Introduction to Functions in C

Writing code that is easy to read and maintain can be a very difficult task.

It is often said that "programs should be written to be read by people, and only incidentally to be executed by machines". This means that when writing programs we must focus on creating code that is easy to understand by other developers.

Functions in C language help to break down programs into smaller "pieces". This makes the code simpler to create, maintain and test.

A function is a self-contained program unit designed to perform a specific task. When writing a large program, the smartest thing to do is to break down the program itself into smaller "pieces": the functions.

One of the key ideas of C is that every program is segmented, or rather modularized, into smaller and simpler functions. Starting from them it is then possible to build complex programs.

As the ancient Romans used to say: "divide et impera", that is "divide and conquer". By dividing the program into logically self-contained functions that perform a well-defined task, it is possible to solve problems of a broader nature. Furthermore, if we divide our program into simpler "pieces" it will be easier to test it and verify its correct behavior. Finally, if one or more functions perform specific tasks, they can be reused in other programs without having the need to rewrite the same code or, worse still, reinvent the wheel.

Structure of a Program and Functions

As we have said, a C program is composed of one or more functions. The most important of all is the main function.

The main function represents the point where the execution of the program starts at the moment it is launched. For this reason it is indicated, in technical jargon, as entry point. Inside the main function we are able to use other functions, as we have seen in the programs of previous lessons, such as for example printf. In C, therefore, a function is able to use, that is to call, other functions in turn.

Definition

main Function

The main function is the entry point of a program, that is the point from which it begins its execution.

To obtain modularity the C language uses functions. Each program is usually created through the combination of functions from the C standard library and new ad-hoc functions created by developers.

C Standard Library

The C standard library makes available a vast quantity of ready-to-use functions that take care of performing mathematical calculations, manipulating strings, managing input and output and much more. These functions are specified in the C language standard in addition to the syntax of the language itself. The resulting advantage is that in this way every C compiler must provide a function library that adheres to the standard so that, even if we change operating system or processor, using the associated C compiler we will always have available a set of ready-to-use functions without having to worry about the differences that exist between various systems.

Programs that use the standard library will therefore be portable. This means that a program written using only standard library functions can be compiled without problems both with a compiler for Windows and with a compiler for Linux and so on. The printf and scanf functions are, for example, standard library functions.

Definition

C Standard Library

Every C compiler that adheres to the C language standard must provide a standard function library, that is functions that offer the same functionality and behave the same way regardless of the platform, operating system and processor, on which the program is executed.

User-Defined Functions

Obviously, the functions provided by the C standard library cannot cover all the possible needs of real programs. There will always arise, within a project, the need to implement a new functionality. For this reason the C language makes available to developers the necessary means and constructs to implement new functions that are called user-defined functions.

The advantage in implementing custom functions lies in the fact that the instructions contained in the new function are written only once and are self-contained in the function itself, however the function can be invoked at any point in our program.

In the next lessons we will see how to create new functions and how to call them.

Function Invocation

Before delving into the details of how to create and call functions in C language, it is however necessary to clarify some concepts about the mechanism of use.

In technical jargon, when you want to "use" a function the term invocation is used.

Invoking a function means yielding control to it, so that it can perform its tasks. To invoke a function the function call mechanism is used. A function call consists in specifying:

  1. The name of the function.
  2. The parameters: that is the information that the function needs in order to perform its task.

To better understand the invocation mechanism let's try to examine the following example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>
#include <math.h>

int main() {
    double x = 5.0;
    double y;

    y = exp(x);

    printf("exp(5) = %f\n", y);

    return 0;
}

In this example we have used two functions: printf which we already know and exp which is a function of the C standard library. The latter is a mathematical function that calculates e^x.

As can be seen in the example, to invoke exp it was necessary to specify the name and the parameter x of which it must calculate the power enclosed in two parentheses. In doing this, when our program reaches line 8:

y = exp(x);

it yields execution control to the function. From this moment on, the function will calculate the result and then yield control again to our program which collects the result. In technical jargon it is said that the exp function returns the result, which is then stored in the variable y.

Note: Pay attention to the example program above. If you try to compile the program using gcc you will get compilation errors. In fact, to be able to compile a C program that uses the mathematical library it is necessary to provide the compilation option -lm. This is not necessary for the visual studio C compiler.

Not necessarily a function must return a result. There are functions that perform a task and return nothing. In this case we speak of procedures. In some programming languages procedures and functions are treated differently. In C, on the other hand, procedures and functions are treated the same way.

The value returned by a function can also be ignored. For example, we could have written:

exp(y);

However an expression like this would have made little sense. printf also returns a value (which we have always ignored so far). It provides as output, in fact, the number of characters it has printed to screen. For example:

1
2
3
4
5
6
7
#include <stdio.h>

int main() {
    int number_characters = printf("TEST\n");
    printf("Number of characters printed: %d\n", number_characters);
    return 0;
}

The function invocation or function call mechanism involves the following steps:

  1. The function that invokes, called caller, invokes the desired function specifying its name and parameters in parentheses.
  2. Execution control is yielded to the called function.
  3. The instructions contained in the body of the called function are executed.
  4. A function may or may not return a result. In case it returns it, the caller can retrieve the result by saving it in a variable.
  5. At the end of the execution of the instructions of the called function, execution resumes from the point following the one at which the function was invoked.

This invocation mechanism can also be extended to called functions, that is called functions can in turn invoke other functions. This is a fundamental point that we will see later in the course of the lessons.

In Summary

In this lesson we have seen that:

  • The C language makes available functions to modularize our programs.
  • Functions can be invoked by specifying the name and parameters in parentheses.
  • Functions can, moreover return a result which can also be ignored.
  • Typically, functions that do not return a result are called procedures. While in other languages functions and procedures are treated differently, C treats them the same way.
  • Called functions can, in turn, invoke other functions.

In the next lesson we will see how to create user-defined functions.