Learning Objectives
After completing this session, you will be able to:
Define functions
Understand how to pass arguments to function
Understand and Implement Recursive functions
Understand how to pass arrays in a function
Need for Functions
Functions are smaller self-contained components which carry out some specific, well defined task.
As real world applications become more complex and large, several problems arise.
Most common are:
Algorithms for solving more complex problems become more difficult and hence difficult to design.
Even after designing an algorithm, its implementation becomes more difficult because of the size of the program.
As programs become larger, testing, debugging, and maintenance will be a difficult task.
Thus, complex problems can be solved by breaking them into a set of sub-problems, called
Modules. Each module can be implemented independently and later can be combined into a single unit.
C supports modularity by means of functions. C functions are classified into two categories.
User defined functions
Library functions
C function offers the following advantages.
It facilitates top-down modular programming. Modularity brings logical clarity to the programs
It avoids the need for redundant code. The repeated instructions can be written as a function, which can then be called whenever it is needed
It facilitates reusability – functions created in one program can be accessed in other programs. C programmer can build on what others have already done, instead of starting from scratch
C functions can be used to build a customized library of frequently used routines
Function Prototype
Like variables, functions are declared and declaration of a function is called Function Prototype.
Prototype specifies the signature (name) of the function, the return type, and number and data types of the arguments. It helps the compiler to know about the function. Functions must be declared before it is called.
Function prototyping is not mandatory in C. It is mandatory when the function is called prior to its definition. They are desirable, however, because they further facilitate error checking between function calls and the corresponding function definition.
Example 9.1
int find_big (int, int);
/* function find_big returns integer value, takes 2 integer arguments */
void swap (int *, int *);
/* function ‘swap’ does not return any value, takes 2 pointer variables. */
float add(float, int);
/* function ‘add’ returns float value, takes 1 float variable and 1 integer variable */
Example 9.2 (1)
main() {
int a,b;
int sum(int, int) ; /* function prototyping. */
scanf("%d%d” , &a, &b);
printf(“ %d “ , sum(a, b);
}
int sum(int a , int b) {
return a+b;
}
(2) void fun() {
printf(“"prototype not needed “);
}
Function is defined prior to its reference. So compiler will identify the function name.
main() {
fun();
}
Function Definition
Function definition is used to define the function with appropriate name, parameters, and the operations to be carried out by the function. Functions can be defined at any location in the program. If the function is defined before the ‘main’ program, there is no need for the function prototype.
A function definition has two principle components: Function header (first line), Function body.
General form:
return-type function-name(type arg1, type arg2, …..) {
local variables Declaration;
executable statement 1;
executable statement 2;
:
return expression;
}
Function Header
function-name Æ specifies the name of the function and it must be a valid identifier
arg1,arg2 … Æ specifies formal arguments (formal parameters)
return-type Æ represents the data type of the data item returned by the function
Function Body
Function can have declaration statements and any number of valid executable statements.
Local Variables - The variables declared inside any function are local to that function. It can be accessed only within that function. Memory for the local variables is allocated only when the function is invoked and de-allocated when the control moves out of the function.
Global Variables - The variables that are common to all the functions are declared outside the functions. If it is declared in the Global declaration section, it is used by all the functions in the program. Memory for the global variables is allocated, when the program gets executed and de-allocated only at the end of program execution.
return statement is used to transfer the control back to the calling program. A function may or may not return a value to the calling function. A function may receive any number of values from the called function. If it returns a value, it is achieved by the return statement. There can be multiple return statements, each containing different expression. If there is no return statement, the closing braces (}) in the function body acts as a return statement.
General Form:
return;
OR
return(expression);
expression can be a variable name, constant value or any single valued expression.
Example 9.3
Function for finding the biggest of two integers int find_big(int a, int b)
{
If the function doesn’t receive any arguments and doesn’t return any data, then void keyword is used to represent that. Default return type is ‘int’.
Example 9.5
(1) void display(void) {
printf(“this is a function”);
} (2) main() {
return 0;
}
Function Call
Functions are invoked by specifying its name, followed by a list of parameters enclosed within parentheses.
General form:
[variable name =] function name(actual arguments);
Actual arguments are the parameters passed to the called function. The number, data type, and the order of the actual arguments and formal arguments should match. Variable names of the actual arguments and the formal arguments need not be same.
When the function call is encountered, the control is transferred to the called function and the statements in the function are executed. When the return statement is executed or last statement is execution, the control is transferred back to the place of function call in the calling function. If a function is returning a value, that value is substituted in place of a function call in the calling function. The LHS variable name in the function call is optional. If the function returns value, the value returned is stored in the LHS variable name.
Example 9.6
Program for finding biggest of two integers using the function find_big int find_big(int, int);
/* function prototype, global declaration */
main( ) {
int num1, num2, big;
scanf(“%d%d”, &num1, &num2);
big=find_big(num1,num2);
/* function call statement, num1 & num2 are actual arguments */
printf(“ The biggest is : %d “, big);
Note: Function can also be called using printf (“The biggest is: %d”, find_big(num1,num2)) statement.
Recursion
If a function is having a self-reference, it is called Recursion. It is a process by which a function calls itself.
A recursive function must have the following properties:
The problem must be written in a recursive form
There must be a base criteria (terminating condition) for which the function doesn’t call
In fourth call, the condition evaluates to 1 and returns 1 to the calling part (call 3), which in turn return the value to its calling function. Function will be evaluated in Last In First Out manner (Stack)
Nesting of Functions
Functions may be nested. The main function may call function1, which in turn call function2, which may call function3.
Passing Arguments
A function is referenced by its name and providing appropriate values for the arguments. On seeing the name of the function in calling statement, the control is immediately transferred to the function. The parameter values are substituted and the function is executed. When the return statement is encountered, control is transferred back to the called function, along with the value returned.
Depending on its definition, functions may be classified as:
Functions with no arguments & no return value
Functions with no arguments but return value
Functions with arguments but no return value
Functions with arguments and return value
Example 9.8
No Arguments and no return value No arguments but return value main() main()
{ {
border(); int sum;
printf(“\t\t Hello World\n””) sum=add();
border(); printf(“\nSum = %d”,sum);
} }
border() add()
{ {
int i; int a,b;
for(i=1;i<=80;i++) scanf(“%d%d”, &a,&b);
printf(“-“); return(a+b);
printf(“\n”); }
return;
}
Example 9.9
With arguments and no return value With arguments and
return value
main() main()
{ {
int n; char c; int sum,a,b;
printf(“Enter the size of border & style\n”); printf(“Enter2 integers\n”);
scanf(“%d%c”, &n,&c); scanf(“%d%d”,&a,&b);
border(n,c); sum=add(a,b);
printf(“\t\t Hello World\n””) printf(“\nSum = %d”,sum);
border(n,c);
Passing arguments to a Function:
There are two approaches to pass the information to a function via arguments. They are:
Call by Value
Call by Reference
Call by Value
Arguments are usually passed by value in C function calls. The values of the actual arguments are copied in to the respective formal arguments. Actual and formal arguments refer to the different memory locations and the value of actual argument is copied into the formal argument. So, any changes made to the formal argument are not reflected in their corresponding actual arguments.
The value of the actual argument will remain same.
a Æ x a is actual argument and x is formal argument.
Example 9.10: Program that illustrates call by value mechanism main()
/*Function used to swap the values of variables c and d*/
{
In this approach, the addresses of actual arguments are passed to the function call and the formal arguments will receive the address. The actual and formal arguments refer to the same memory location. So, changes in the formal arguments are reflected in actual arguments.
Note: Actual arguments are address of the ordinary variable, pointer variable or array name.
Formal arguments should be a pointer variable or array.
This approach is of practical importance while passing arrays to functions and returning back more than one value to the calling function. Passing arrays to functions is call by reference by default.
a x a is actual argument and x is formal argument.
Example 9.11: Program that illustrates call by reference mechanism main()
It is possible to pass an entire array to a function. To pass an array to a function, it is enough to give the name of the array as argument. Array name is interpreted as base address of the array and the address is given to the formal argument. Formal argument can be an array or pointer variable, which points to an array.
Example 9.12
int maximum( int val[] )
/*size of the array need not be mentioned */
{
printf("Enter 5 numbers\n");
for( i = 0; i < 5; ++i )
scanf("%d", &values[i] );
max = maximum(values);
/* array name is used to pass an entire array without any
subscripts */
printf("\nMaximum value is %d\n", max );
}
Passing Multidimensional Arrays
Multi dimensional arrays can also be passed in the same manner as single dimensional array, but care must be taken in representing the formal arguments.
Example 9.13
void print_table(int xsize,int ysize, float table[][5]) {
int x,y;
for (x=0;x<xsize;x++)
{
for (y=0;y<ysize;y++)
printf("\t%f",table[x][y]);
printf("\n");
} }
Note: Second dimension is mentioned with its size. In case of three dimensional arrays, second &
third dimension has to be mentioned. This is to represent the column size. The array elements are stored in row major form.
Arrays can not be returned with return statement since return can pass only a single-value back to the calling program. Therefore, in order to return an array to the calling program, the array must either be defined as global array, or it must be passed as a formal argument to a function.
Try It Out
1. Problem Statement:
Write a program to print out first 10 numbers in descending order using recursive function Code:
#include <stdio.h>
void recurse(int i);
void main(void) {
recurse(0);
getchar();
}
void recurse(int i) {
if (i<10) { recurse(i+1);
printf("%d ",i);
} }
Refer File Name: <sesh9_1.c> to obtain soft copy of the program code How It Works:
This program explains about how to write recursive function
The main program calls the recurse function with value 0 as argument
In the recurse function, the value is increment and the recurse function is called again.
This time it passes 1 as argument.
Again in the next step value will be incremented and the recurse function is called.
This continues till the value passed is less than 10.
Once it is equal to 10, it start printing the value of i. First it will print the value of 10, then it returns from the function and again prints the value as 9 and returns back.
This continues till all the function call is completed.
Hence the 10 numbers will be printed in descending order.
2. Problem Statement:
Write a program to have functioning returning a value
Code:
/* function that returns value*/
#include <stdio.h>
#include <stdlib.h>
int getval(void);
int main() {
int weight;
weight=getval();
printf("Entered value is %d\n",weight);
getchar();
return(0);
}
int getval(void) {
char input[20];
int x;
printf("some integer:");
gets(input);
x=atoi(input);
return(x);
}
Refer File Name: <sesh9_2.c> to obtain soft copy of the program code How It Works:
The main program calls the getval() function.
In getval() function, prompts the user to enter some number.
It reads the input value and converts to integer form .
Then returns the integer value.
The main program then prints the value on the screen.
Summary
Functions are smaller self-contained components which carry out some specific, well defined task.
Functions facilitates reusability and brings logical clarity to the programs.
C functions should be considered with three aspects: i) function definition, ii) function call, iii) function prototyping
Arguments can be passed to a function via call by reference method or by call by value method.
Arrays can be passed to a function by simply specifying its name.
A function calling itself is called recursion.
C supports four storage class specifiers (auto, static, extern and register) to define scope and life time for the variable.
The command line arguments, argc and argv are used to pass arguments to main() function.
Test your Understanding
1. What is function prototyping?
2. What is relationship between the actual parameters and its formal parameters?
3. What is the output of the following code?
main()
4. What is the difference between call by reference and call by value?
5. What is the output of the following code?
main()
6. What the following declaration statements imply?
a. int p(char *a) b. int *p(char *a) c. int (*p)(char a) d. int *p(char *a[])
7. How main() function is called with parameters?
Answers:
1. Function prototyping is like a function declaration statement which informs the compiler about the function (its name, type of its arguments, return data type). In C, it is needed only when the function is called prior to its definition.
2.
a. There must be a one-to-one correspondence between the actual and formal parameters.
b. Corresponding parameters must be of same type.
3. 3 4
4. In call by reference, address of the actual parameters are passed to corresponding formal parameters but in call by value, only the values of the actual parameters are copied in to corresponding formal parameters.
5. 10
6. a) p is a function which receives a character pointer and returns an integer value b) p is a function which receives a character pointer and returns an integer pointer
c) p is a pointer (function pointer) which can point to any function with character argument and integer return value.
d) p is a function whose argument is an array of pointers.
7. Using command line arguments.