The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as
well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct. Donald E. Knuth

Functions in C

A function is a block of statements which perform a specific task. A program can be divided into functions. This enhances the modularity and maintainability of a program. Functions eliminates redundant code i.e it helps us to avoid rewriting the same logic again and again. Functions are the means to support code reusabilty in C.

Function Declaration and Definition
Every C program has at least one function i.e main( ) where the program execution begins. Consider the following C program in which we use a function to add two numbers :

#include <stdio.h>

/* function declaration or prototype 
 * Function Name : add
 * It takes two integer values as arguments / parameters 
 * It returns an integer value 
 */
int add ( int , int );

int main() {
   int x = 5, y = 3;
   int s = add(x, y); /* function call (s stores returned value */
   printf("Sum : %d", s);
   return 0;
}

/* function definition */
int add ( int a, int b ) {
   int sum = a + b;
   return sum;
}


Function Declaration / Prototype describes the function interface to the compiler giving information about the function name, return types and parameters (arguments). In the above program,
Function Name : add
Return Type : int
Parameters / Arguments : int a, int b

Function Definition provides the code which constitutes the body of the function. A general form of C function definition is shown below :

return_type function_name ( argument list ) {
            function body
}

Function Call invokes the function body to perform a specific task.

Please note that argument list may consists of 0 or more no. of arguments and the return type of the function may be void also in case the function doesn't return any value. Following program uses two functions to generate first 'n' terms of fibonacci series. In fibonacci series, ith term of the series is equal to the sum of (i - 1)th and
(i - 2)th term with first two terms as 0 and 1.
Fibonacci series : 0 1 1 2 3 5 8 13 21 ....

/*
 * This program prints the first 'n' terms of fibonacci series
 * let the series be fib = { 0, 1, 1, 2, 3, 5, 8, 13, 21, ... }
 * fib(0) = 0 and fib(1) = 1
 * fib(i) = fib(i-1) + fib(i-2) for i >= 2 
 */

#include <stdio.h>

/***************** function prototypes ******************/

int add ( int, int );
void fibonacci ( int );

/********************************************************/

/***************** function definitions *****************/

/* Adds two numbers */
int sum ( int a, int b ) {
   int s = a + b;
   return s;
}

/* Prints first 'n' terms of fibonacci series */
void fibonacci ( int n ) {
   int a = 0, b = 1;
   int s = 0, i;
   printf("%d %d ", a, b);
   for ( i = 2; i < n; i++ ) {
      s = sum(a, b); /* call to function sum() */
      printf("%d ", s);
      a = b;
      b = s;
   }
}

/********************************************************/

/* main function */
int main () {
   int n = 8;
   printf("Fibonacci Series till %d terms :- \n", n);
   fibonacci(n); // call to function fibonacci()
   return 0;
}

Another sample program which finds the maximum of three numbers using a function max (int a, int b) which finds the maximum of two numbers.

/*
 * This program finds the maximum of three numbers
 */

#include <stdio.h>

int max ( int, int );
int maxThreeNum ( int, int, int );

/* Finds max of two numbers */
int max ( int a, int b ) {
   // find max using conditional operator
   int large = ( a > b ) ? a : b;
   return large;
}

/* Finds max of three numbers */
int maxThreeNum ( int a, int b, int c ) {
   int x;
   x = max(a, b); // store the max of 'a' and 'b' in 'x'
   x = max(c, x); // store the max of 'x' and 'c' in 'x' 
   return x;
}

/* main function */
int main() {
   int x = 6, y = 9, z = 3;
   int max_val = maxThreeNum(x, y, z);
   printf("Maximum Value : %d\n", max_val);
   return 0;
}


Parameter Passing
We have seen above that while calling a function we pass parameters/arguments.
There are two ways of passing parameters :
Call by Value : This method copies the argument value into the formal parameters of the function. Apparently, all the programs we have seen till now uses call by value. In this method, changes made to the argument values in the called function is not reflected in the calling function. Consider the program which finds the maximum value out of three numbers. In the function call maxThreeNum(x, y, z) , values in x, y and z are copied into variables a, b and c respectively.
Call by Reference :
This method copies the address of the arguments into the formal parameters of the function. In this method, changes made to the argument values in the called function is reflected in the calling function.
Following program illustrates the difference between call by value and call by reference :

/*
 * This program distinguishes the behaviours of call-by-value and
 * call by reference parameters.
 */

#include <stdio.h>

/* param 'a' is passed by using call-by-value
   param 'b' is passed by using call-by-reference
*/
void changeValues(int a, int *b) {
   a = a * 10; /* new value of 'a' is not reflected in main() */
   *b = *b * 10; /* new value of 'b' is reflected in main(); */
}

int main() {
   int a = 2, b = 5;
   printf("Before calling changeValues() : \n");
   printf("a : %d  b : %d\n", a, b);
   changeValues(a, &b); /* calling changeValues() */
   printf("After calling changeValues() : \n");
   printf("a : %d  b : %d\n", a, b);
   return 0;
}

A typical program in which call by reference is used is swapping of two numbers :

/*
 * Swapping of two numbers
 */

#include <stdio.h>

/* swap two numbers */
void swap(int *x, int *y) {
   int temp;
   temp = *x;
   *x = *y;
   *y = temp;
}

int main() {
   int a = 5, b = 2;
   printf("Before swapping :- \n");
   printf("a : %d  b : %d\n", a, b);
   swap(&a, &b);
   printf("After swapping :- \n");
   printf("a : %d  b : %d\n", a, b);
   return 0;
}


Variable Length Argument List
Consider a scenario in which a function is expected to accept any number of arguments i.e the no. of arguments is not known at compile time. To handle this kind of situation C offers an advanced concept of variable length arguments. We need to include stdarg.h header file to use this feature. Following program computes the average of the values passed to a function. The number of values to be passed is not known previously. So, we use a function which accepts variable length arguments.

#include <stdio.h>
#include <stdarg.h>

/* Function to compute average of given numbers
 * params : no [ No. of args] and ellipses (...) denotes variable length args 
 */
float average(int no, ...) {
     va_list arglist; /*create a variable of type va_list */
     int i;
     float sum = 0.0;

     va_start(arglist, no); /* Initialize the argument list */
     for (i = 0; i < no; i++) {
         sum += va_arg(arglist, int); /* read each argument from list and add */
     }
     va_end(arglist); /*clean up memory assigned to arglist */
     sum = sum / no;
     return sum;
}

int main() {
     float avg1, avg2;
     int x = 5, y = 4, z = 7;
     avg1 = average(2, x, y); /* calling average with 2 arguments */
     avg2 = average(3, x, y, z); /* calling average with 3 arguments */
     printf("avg1 = %f\tavg2 = %f\n", avg1, avg2);
     return 0;
}

Back | Next