A function is a named group of statements that performs a task. Functions are used to avoid repeating the same piece of code every time you need it.




We’ve been using some predefined functions so far, in particular printf and scanf.

Today you’re going to learn how to create your own functions.

Definitions, declarations and calls


Functions can appear in a program in three forms:

  • Definitions
  • Declarations
  • Calls

First, a small summary, then we’ll see them in detail.

Defining a function means specifying its name, inputs, body and outputs.

Declaring a function means telling the computer that it exists. In the next sections you’ll learn when and why it’s useful.

Calling a function means using it, letting it performing its task.

Defining a function


In order to use a custom function, you first have to create it.

Function Parts

A function consists of four parts:

  • Name: it’s a custom name that you give to a function in order to use it.
  • Inputs: it’s a list of variables, called parameters, that represent the values that you want to pass to a function during a call. If I define a function that multiplies two numbers, its parameters will be the two numbers I want to multiply. Moreover, each time I call it I can pass different values.
  • Body: it’s a list of statements (e.g. loops, conditions, operations) that all together perform the task of a function.
  • Output: it’s the result of a function. Programmers usually use the verb to return to indicate the output of a function.

The syntax of a function definition is:

Where:

  • return_type is the data type of the function output.
  • function_name is the function name.
  • parameter1, …, parameter_n is a list of one or more variables that represent the inputs. For each parameter you have to specify its type and its name and they can’t be initialised.
  • body is a group of statements that are executed when you call the function. It has to be delimited by curly brackets.

An important role is played by the return statement.

A return statement terminates the execution of a function and it determines its output.

This statement requires a variable, a value or an expression of the same type of the function, therefore a void function can contain an empty return ( return; ), but all the other types can’t.

All the functions – except void ones – usually require at least one return statement, but some compilers can add one with a default value if it’s absent.

Example

This is a function that multiplies two numbers:

Declaring a function


In C, you can only call a function that was defined or declared previously.

While a definition may take up a lot of lines, a declaration is really short, because it only contains type, name and inputs of a function.

A function declaration doesn’t contain a body, which is defined separately.

Programmers usually declare a function before the main one and then they define it at the end.

In order to declare a function use the following syntax:

Examples

You can also omit the names of the parameters, they aren’t necessary in a declaration.

Calling a function


Calling a function is what you do to use printf and scanf: you pass the required parameters, it performs it task and it may return a value.

For example, to multiply 3 by 7 and assign the result to a variable c, do this:

The first parameter, called a in the function definition, is 3. The second one is 7. The variable c gets the value of the function output, that is a * b, as you can see in the first and only line return a * b;.

Types of parameters


When you pass a variable to a function and you assign a new value to it, that change doesn’t apply to the calling function – that one ( even main() ) in which the call is.

The output of the following program is 2, even though the function func() sets it to 3.

Why does it happen?

In C, every parameter is passed by value.

This means that what is really passed to a function is a copy of a variable and not the variable itself. If you modify the copy, the original doesn’t change.

However, if that value is an address, you can modify a variable used by the calling function, because its memory address remains always the same – in or out a function.

Therefore, you can pass a variable using two methods:

  • by copy: you simply pass a variable and the function gets a copy of it. Every change to the copy doesn’t affect the original.
  • by reference: you pass a pointer to a variable, so that the function can always access the original one using its address, even if it’s a copy.

copy_vs_reference

Compare the two lines of outputs of this program:

The function copy has a normal variable as parameter and it can’t change the value of a, while reference gets a pointer as input, so it can affect that variable.

Since passing a parameter by reference requires pointers, this article about them may be helpful.

Recursive functions


A function that calls itself is called recursive function.

For example, the following program prints all the even numbers from 10 to 2 and it quits when a parameter reaches 0.

Remember: make sure of returning a normal value under a certain condition or at a certain point of a recursive function, otherwise, if there’s an infinite loop, the program will crash.

Read more about recursive functions here.

Let’s analyse today’s program


Today’s program contains a function that moves each element of a list by two places and another one that prints that list.

void rotate_list(int *list, int elements);

This line declares a function called rotate_list, which doesn’t return anything – its type is void – and which takes two parameters: a pointer to an int – in this case an array – and an int.

void print_list(int *list, int elements);

This line is almost identical to the previous one, but it declares a different function.

print_list(list, 5);

This is a call to the function print_list. Even though I haven’t defined it yet at this point in the code, the program knows that it exists, because I’ve declared it.

void rotate_list(int *list, int elements) { ... }

This is the definition of rotate_list and it contains the list of statements that performs the function task. In this piece of code we can see the difference between passing a copy and passing a reference.

In fact, since elements isn’t a pointer, what is copied is its value, so even if you modify it, that change doesn’t affect the original input.

On the other hand, list is a pointer, so what is copied is the address of a variable. Therefore you can always access the original variable using that address.

Conclusion


Today you’ve learn an important feature of C and more modern languages: functions.

Now you know that, using pointers, you can pass a variable by reference in order to change its value even in the calling function.

One of the most asked questions about functions is how to pass an array. You’ve just learnt it: pass a pointer to that array.

If you have any questions, you know what to do: write a comment and I will answer you!

If you’ve found this useful, share it, so that it can help some friend of yours too.

Anyway, the post is finished, have a good day and we will see next week!

From Zephyro it’s all, Bye!

Categories: Learn C

Leave a Reply

%d bloggers like this: