home
C TUTORIALS

Functions & Pointers

What is a Function

A function is a self-contained block of statements that perform a coherent task of some kind. Every C program can be thought of as a collection of these functions. Every C program has at least one function, which is main(), and all the most trivial programs can define additional functions.You can divide up your code into separate functions. How you divide up your code among different functions is up to you, but logically the division usually is so each function performs a specific task.

Structure of a Function

There are two main parts of the function. The function header and the function body.

	
int sum(int x, int y) { int ans = 0; //holds the answer that will be returned ans = x + y; //calculate the sum return ans //return the answer }

Function Header

In the first line of the above code.

	 
int sum(int x, int y)

It has three main parts

  1. The name of the function i.e. sum.
  2. The parameters of the function enclosed in paranthesis.
  3. Return value type i.e. int

Function Body

What ever is written with in { } in the above example is the body of the function.

Function Prototypes

The prototype of a function provides the basic information about a function which tells the compiler that the function is used correctly or not. It contains the same information as the function header contains. The prototype of the function in the above example would be like

	
int sum (int x, int y);

The only difference between the header and the prototype is the semicolon ; there must the a semicolon at the end of the prototype.



Let us now look at a simple C function given below:

	
main( ) { message( ) ; printf ( "\nCry, and you stop the monotony!" ) ; } message( ) { printf ( "\nSmile, and the world smiles with you..." ) ; }

And here’s the output...

Smile, and the world smiles with you... Cry, and you stop the monotony!

Here, main( ) itself is a function and through it we are calling the function message( ). What do we mean when we say that main( ) ‘calls’ the function message( )? We mean that the control passes to the function message( ). The activity of main( ) is temporarily suspended; it falls asleep while the message( ) function wakes up and goes to work. When the message( ) function runs out of statements to execute, the control returns to main( ), which comes to life again and begins executing its code at the exact point where it left off. Thus, main( ) becomes the ‘calling’ function, whereas message( ) becomes the ‘called’ function.

Why Use Functions

Why write separate functions at all? Why not squeeze the entire logic into one function, main( )? Two reasons:

  1. Writing functions avoids rewriting the same code over and over.
  2. We can divide a long C program into small blocks which can perform a certain task. A function is a self contained block of statements that perform a coherent task of same kind.

Passing Values between Functions

The functions that we have used so far haven’t been very flexible. We call them and they do what they are designed to do.

The mechanism used to convey information to the function is the ‘argument’. You have unknowingly used the arguments in the printf( ) and scanf( ) functions; the format string and the list of variables used inside the parentheses in these functions are arguments. The arguments are sometimes also called ‘parameters’.

Consider the following program. In this program, in main( ) we receive the values of a, b and c through the keyboard and then output the sum of a,b and c. However, the calculation of sum is done in a different function called calsum( ). If sum is to be calculated in calsum( ) and values of a, b and c are received in main( ), then we must pass on these values to calsum( ), and once calsum( ) calculates the sum we must return it from calsum( ) back to main( ).

/* Sending and receiving values between functions */ main( ) { int a, b, c, sum ; printf ( "\nEnter any three numbers " ) ; scanf ( "%d %d %d", &a, &b, &c ) ; sum = calsum ( a, b, c ) ; printf ( "\nSum = %d", sum ) ; } calsum ( x, y, z ) int x, y, z ; { int d ; d = x + y + z ; return ( d ) ; }

And here is the output...

Enter any three numbers 10 20 30 Sum = 60

Scope Rule of Functions

Look at the following program

main( ) { int i = 20 ; display ( i ) ; } display ( int j ) { int k = 35 ; printf ( "\n%d", j ) ; printf ( "\n%d", k ) ; }

In this program is it necessary to pass the value of the variable i to the function display( )? Will it not become automatically available to the function display( )? No. Because by default the scope of a variable is local to the function in which it is defined. The presence of i is known only to the function main( ) and not to any other function. Similarly, the variable k is local to the function display( ) and hence it is not available to main( ). That is why to make the value of i available to display( ) we have to explicitly pass it to display( ). Likewise, if we want k to be available to main( ) we will have to return it to main( ) using the return statement. In general we can say that the scope of a variable is local to the function in which it is defined.

Calling Convention

Calling convention indicates the order in which arguments are passed to a function when a function call is encountered. There are two possibilities here:

  1. Arguments might be passed from left to right.
  2. Arguments might be passed from right to left

Advanced Features of Functions

With a sound basis of the preliminaries of C functions, let us now get into their intricacies. Following advanced topics would be considered here.

  1. Return type of function
  2. Calling functions by value or by reference
  3. Recursion

Return Type of Function

A function may return a value. The return_type is the data type of the value the function returns. Some functions perform the desired operations without returning a value. In this case, the return_type is the keyword void.

Call by Value and Call by Reference

While calling a function, there are two ways that arguments can be passed to a function:

(a)Call by value:This method copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument.

(b)Call by reference:This method copies the address of an argument into the formal parameter. Inside the function, the address is used to access the actual argument used in the call. This means that changes made to the parameter affect the argument.

A Introduction to Pointers

Which feature of C do beginners find most difficult to understand? The answer is easy: Pointers. Other languages have pointers but few use them so frequently as C does.

Pointer Notation

Consider the declaration,

int i=3;

This declaration tells the C compiler to:

  1. Reserve space in memory to hold the integer value.
  2. Associate the name i with this memory location.
  3. Store the value 3 at this location.

We can print this address number through the following program:

#include int main() { int i=3; printf("Address of i=%u\n",&i); printf("Value of i=%d\n",i); return 0; }

output of the above program is:

Address of i=65524 value of i=3

Look at the first printf() statement carefully. '&' used in this statement is C's 'address of' operator. The expression &i returns the address of the variable i, which in this case happens to be 65524.Since 65524 represents an address, there is no question of a sign being associated with it.hence it is printed out using %u,which is a format specifier for printing an unsigned integer. We have been using the '&' operator all th etime in the scanf() statement.

The other pointer operator available in C is '*', called 'value at address' operator.It gives the value stored at a particular address.The 'value at address' operator is called 'indirection' operator.

int *j

This declaration tells the compiler that j will be used to store teh address of an integer value.In other words,j points to an integer. Let us go by th meaning of *. It stands for 'value at address'.Thus,int*j would mean, the value at the address conatined in j is an int.

Here is a program that demonstrates the relationships we have been discussing.

#include int main() { int i=3; int *j; j=&i; printf("Address of i=%u\n",&i); printf("Address of i=%u\n",j); printf("Address of j=%u\n",&j); printf("Value of j=%u\n",j); printf("Value of i=%d\n",i); printf("value of i=%d\n",*(&i)); printf("value of i=%d\n",*j); return 0; }

The output of the above program is :

Address of i=65524 Address of i=65524 Address of j=65522 value of j=65524 value of i=3 value of i=3 value of i=3

Work through the above program carefully, taking help of the memory locations of i and j shown earlier.This program summarizes everything that we have discussed so far.If you don't understand the program's output, or the meanings of &i,&j,*j and *(&i).

We can say that Pointers are variables that contain addresses, and since addresses are always whole numbers, pointers would always contain whole numbers.

Back to Function Calls

Having had the first tryst with pointers, let us now get back to what we had originally set out to learn- the two types of function calls- call by value and call by reference.Arguments can be generally be passed to functions in one of the two ways:

  1. sending the values of the arguments
  2. sending the addresses of the arguments

The following program illustrates the 'Call by value'.

#include void swapv(int x,int y); int main() { int a=10,b=20; swapv(a,b); printf("a=%d b=%d\n",a,b); return 0; } void swapv(int x,int y) { int t; t=x; x=y; y=t; printf("x=%d y=%d\n",x,y); }

The output of the above program would be:

x=20 y=10 a=10 b=20

Note that values of a and b remains unchanged even after exchanging values of x and y.

In the second method (call by reference), the address of actual arguments in calling function are copied into the formal arguments of the called function.The following program illustrates this fact.

#include void swapr(int*,int*); int main() { int a=10,b=20; swapr(&a,&b); printf("a=%d b=%d\n",a,b); return 0; } void swapr(int *x,int *y) { int t; t=*x; *x=*y; *y=t; }

The ouput of the above program would be:

a=20 b=10

Note that this program manages to exchange the values of a and b using their addresses stored in x and y.

Recursion

Recursion is the process of repeating items in a self-similar way. Same applies in programming languages as well where if a programming allows you to call a function inside the same function that is called recursive call of the function as follows.

void recursion() { recursion(); /* function calls itself */ } int main() { recursion(); }

The C programming language supports recursion, i.e., a function to call itself. But while using recursion, programmers need to be careful to define an exit condition from the function, otherwise it will go in infinite loop.

Recursive function are very useful to solve many mathematical problems like to calculate factorial of a number, generating Fibonacci series, etc.

Fibonacci Series

Following is another example, which generates Fibonacci series for a given number using a recursive function:

#include int fibonaci(int i) { if(i == 0) { return 0; } if(i == 1) { return 1; } return fibonaci(i-1) + fibonaci(i-2); } int main() { int i; for (i = 0; i < 10; i++) { printf("%d\t%n", fibonaci(i)); } return 0; }

When the above code is compiled and executed, it produces the following result:

0 1 1 2 3 5 8 13 21 34