C – Functions

Introduction

Most computer programs that solve real-world problems are much larger than simple programs. They are larger programs.

Experience has shown that the best way to develop and maintain a large program is to construct it from smaller pieces, each of which is more manageable than original program.

  • This technique is called divide and conquer.

In C, functions are used to modularize programs.

The C standard library provides a rich collection of functions for performing common mathematical calculations, string manipulations, character manipulations, input/output, and many other useful operations. This makes your job easier, because these functions provide many of the capabilities you need.

Familiarize yourself with the rich collection of functions in the C standard library.

Avoid reinventing the wheel. When possible, use C standard library functions instead of writing new functions. This can reduce program development time. These functions are written by experts, well-tested and efficient.

You can write functions to define specific tasks that may be used at many points in a
program. These are sometimes referred to as programmer-defined functions.

Functions are invoked by a function call, which specifies the function name and provides information (as arguments) that the function needs to perform its designated task.

Functions

Functions allow you to modularize a program.

  1. All variables defined in function definitions are local variables—they can be accessed only in the function in which they’re defined.
  2. Most functions have a list of parameters that provide the means for communicating information between functions via arguments in function calls.
  3. A function’s parameters are also local variables of that function.

There are several motivations for “functionalizing” a program.

  • The divide-and-conquer approach makes program development more manageable.
  • Another motivation is software reusability—using existing functions as building blocks to create new programs.
  • A third motivation is to avoid repeating code in a program. Packaging code as a function allows it to be executed from other locations in a program simply by calling the function.

Each function should be limited to performing a single, well-defined task, and the function name should express that task. This facilitates abstraction and promotes software reusability.

If you cannot choose a concise name that expresses what the function does, it’s possible that your function is attempting to perform too many diverse tasks. It’s usually best to break such a function into smaller functions—this is sometimes called decomposition.

Functions Syntax – Definition

Each program that we have written so far has consisted of a function called main that called standard library functions to accomplish its tasks. We now consider how to write custom functions.

The syntax for a C function declaration is as follows:

The return-value-type void indicates that a function does not return a value.

Together, the return-value-type, function-name and parameter-list are sometimes
referred to as the function header.

  • Include parameter names in function prototypes for documentation purposes. The compiler ignores these names, so the prototype int maximum(int, int, int); is valid.

Choosing meaningful function names and meaningful parameter names makes programs more readable and helps avoid excessive use of comments.

return_type function_name(parameter1_type parameter1, parameter2_type parameter2, ...);

Where:

  • return_type is the data type of the value returned by the function, such as int, float, double, void, etc.
  • function_name is the name of the function, which should follow C naming conventions and be descriptive of what the function does.
  • parameter1_type, parameter2_type, etc., are the data types of the parameters passed into the function.
  • parameter1, parameter2, etc., are the names of the parameters passed into the function.

For example, a simple function that takes two integer parameters and returns their sum could be declared as follows:

int sum(int a, int b);
  • Include parameter names in function prototypes for documentation purposes. The compiler ignores these names, so the prototype int maximum(int, int, int); is valid.

And the implementation of the function would look something like this:

int sum(int a, int b) {
    return a + b;
}

When calling a function, you pass in arguments that match the parameter types declared in the function declaration. For example :

int result = sum(3, 5);

This would call the sum() function with a set to 3 and b set to 5, and assign the result 8 to the result variable.

NOTE :

The compiler compares the function calls to the function prototype to ensure that:

  • the number of arguments is correct,
  • the arguments are of the correct type,
  • the argument types are in the correct order, and
  • the return type is consistent with the context in which the function is called.

Example :

NOTE :

  • Redefining a parameter as a local variable in a function is a compilation error.
  • Although it’s not incorrect to do so, do not use the same names for a function’s arguments and the corresponding parameters in the function definition. This helps avoid ambiguity.

The statements within braces form the function body, which is also a block. Variables can be declared in any block, and blocks can be nested (but functions connot be nested).

Returning control from functions

There are three ways to return control from a called function to the point at which a function was invoked.

If the function does not return a result, control is returned simply when the function-ending right brace is reached, or by executing the statement

return;

If the function does return a result, the statement

return expression;

returns the value of expression to the caller.

The return value of main is used to indicate whether the program executed correctly.

return 0;

at the end of main — 0 indicates that a program ran successfully.