C Functions

A function is a block of statements that perform a specific task, which can be used multiple times within a program. In C, as with a lot of languages, there are a number of functions built in, which are part of the C Standard Library, however, it is also possible to create user defined functions. The statements within a function are only executed once the function is called, so, if the function is never called then they won’t run. In C, a function can be defined and called as follows.

// Function definition.
return_type function_name(parameter_type parameter_name)
{
   // Statement(s) to execute.
}

// Function call.
function_name(parameters);

A function can return an item of data of a particular type. When a function is defined, the return type is specified prior to the function name, which is used to call it. If no value is to be returned from a function, then the keyword ‘void’ is used. The rules for naming a function are similar to a variable, it must start with a letter or underscore, but can then be followed by either letters, numbers or underscores. Any parameters, or arguments, that are to be passed to the function are enclosed in parenthesis after the name, separated by commas, if there is more than one. The parameter type is the type of data that the parameter holds, such as ‘int’, ‘char’, ‘float’ and ‘double’. If there are no parameters to be passed, then the parenthesis must still be included, but with nothing enclosed.

To call a function, it is simply a case of specifying the function name, along with any parameters in the parenthesis after the name. Again, if there are no parameters, the parenthesis must still be included.

One stipulation with functions is that they must be defined before they can be used. The function call cannot be above the function definition. To solve this issue, function prototypes can be used. Function prototypes are placed above the ‘main’ function.

return_type function_name(parameter_type parameter_name);

A function prototype should match the first line of the function definition, except there must be a semi-colon at the end. Once this is done it doesn’t matter what order the function call and definition are.

Below is a simple example of a function prototype, call and definition. The function, called ‘addition’, takes two parameters of type ‘int’ and returns an ‘int’ after adding the two parameters together. The function contains one statement, a ‘return’ statement, where the addition is done directly within it. The function call is made as part of a ‘printf’ statement.

#include <stdio.h>
#include <stdlib.h>

// Function prototype.
int addition(int num1, int num2);

int main()
{

    // Numbers to add together.
    int num1 = 10;
    int num2 = 15;

    // Function call as part of 'printf' statement.
    printf("num1 and num2 added together equals: %d\n", addition(num1, num2));

}

// Function definition.
int addition(int num1, int num2)
{

    // Return result.
    return num1 + num2;
}

The output from the above is shown in the console.

num1 and num2 added together equals: 25

As mentioned previously, a function doesn’t always need to return a value. In such circumstances, the ‘void’ keyword is used instead of the return type. Below is an example of a function that takes no parameters and does not return a value. All it does is output the message, ‘Hello World!’ to the console, using the ‘printf’ function, which is built in to the C Standard Library.

#include <stdio.h>
#include <stdlib.h>

// Function prototype.
void hello();

int main()
{

    // Function call.
    hello();

}

// Function definition.
void hello()
{
    printf("Hello World!\n");
}

The above example can be enhanced to include parameters, such as a person’s name. Here, two character array parameters containing strings for first name and last name, are passed to the function, separated by commas and used within the greeting displayed.

#include <stdio.h>
#include <stdlib.h>

// Function prototype.
void hello(char fname[], char lname[]);

int main()
{

    // Name character arrays.
    char fname[] = {"Fred"};
    char lname[] = {"Bloggs"};

    // Function call.
    hello(fname, lname);

}

// Function definition.
void hello(char fname[], char lname[])
{
    printf("Hello %s %s!\n", fname, lname);
}

The resulting output from this is as follows.

Hello Fred Bloggs!

It should be noted that passing variables as parameters in this way is known as pass by value because a copy of the variable value is being passed and not the variable itself. If the values of ‘fname’ and ‘lname’ were changed within the ‘hello’ function, these changes would not be available back in the ‘main’ function.

Passing By Reference

It is possible to pass a variable by reference by using a pointer. This would mean that the updated value would be accessible back in the ‘main’ function.

Expanding on the previous example, the ‘hello’ function now takes three parameters, all of which are pointers to strings within character arrays, denoted by the asterisk prior to the name of each parameter. The first two are the first name and last name, as before and the third is the greeting, which will be updated within the ‘hello’ function. It should be noted that if a numerical variable, such as an ‘int’, ‘float’ or ‘double’ is being passed as a pointer,  the variable names in the function call would need to be preceded by the ‘address of’ operator. The ‘hello’ function constructs the greeting using the ‘strcat’ function to combine the various strings. The greeting is now displayed using a ‘printf’ statement back in the ‘main’ function.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Function prototype.
void hello(char *fname, char *lname, char *greeting);

int main()
{

    // Name character arrays.
    char fname[] = {"Fred"};
    char lname[] = {"Bloggs"};

    // Greeting.
    char greeting[50] = {"Hello "};

    // Function call.
    hello(fname, lname, greeting);

    // Display the greeting.
    printf("%s\n", greeting);

}

// Function definition.
void hello(char *fname, char *lname, char *greeting)
{

    // Construct greeting.
    strcat(greeting, fname);
    strcat(greeting, " ");
    strcat(greeting, lname);
    strcat(greeting, "!");

}

The resulting output is the same as in the previous example.

Hello Fred Bloggs!

Variable Scope

Variables in C can be defined anywhere within a program. The scope of a variable refers to the area of a program that it can be used. Variable scope in C can either be local or global.

Variables that have a global scope are defined outside of a function and are available to the whole program, whereas, variables with a local scope are defined within a function and are only accessible within the function they are defined.

The example below is a variation on the one above. Instead of the greeting variable being defined in the ‘main’ function and passed as a pointer to the ‘hello’ function, it is defined as a global variable outside of any function. This variable is accessible to both the ‘main’ and ‘hello’ functions.

The variables ‘fname’ and ‘lname’ are examples of local variables because they are defined within the ‘main’ function and are not directly accessible to other functions, unless a pointer to these variables is passed to another function, which, in this case, they are.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Function prototype.
void hello(char *fname, char *lname);

// Global greeting variable.
char greeting[50] = {"Hello "};

int main()
{

    // Local name character array variables.
    char fname[] = {"Fred"};
    char lname[] = {"Bloggs"};

    // Function call.
    hello(fname, lname);

    // Display the greeting.
    printf("%s\n", greeting);

}

// Function definition.
void hello(char *fname, char *lname)
{

    // Construct greeting.
    strcat(greeting, fname);
    strcat(greeting, " ");
    strcat(greeting, lname);
    strcat(greeting, "!");

}

As before, the greeting is displayed in the console as follows.

Hello Fred Bloggs!