FUNCTIONS
DEFINITION:A function is a self-contained program segment that carries out some specific, well-defined task.
USER-DEFINED FUNCTION:
The user has the freedom to choose the function name, return data type and the arguments (no. and type), is called user defined function.
Advantages of using functions:
1. Repeated statement can be grouped into functions.
2. Splitting the programs into separate function makes the program more readable and maintainable (easy to rectify the errors if occurs).
The function main() in the program is executed first. The other functions are executed when the function main() calls them directly or indirectly.
The function main() is also a user defined function except that the name of the function, the no. of arguments, and the argument types are defined by the language. The individual statements are written by the programmer in the body of the function main(). The following, in a sense, is complete C program. main() { }
The above statement is sufficient for the execution of the program, though the program does not do any useful operation. The function main() is executed first, when the program starts execution. Other user-defined functions can be called from the function main().
The following example has a function PrintMsg in addition to main. If a call to the function PrintMsg is included in the function main, the statement within the body of the function main. A prefix void is used before the function name, i.e., PrintMsg inticating that the function does not return any value.
/* EX-34: TO PRINT A MESSAGE USING FUNCTION */ |
#include<stdio.h> void PrintMesg() { printf("\n\n\t\tStudying at National Institute, Pazhavanthangal"); } void main() { clrscr(); printf("\n\n\n\n\n\n\n\n\t\t\t I am in Main City - Chennai"); PrintMesg(); getch(); } |
Note: The function name in the above example (PrintMesg) has mixed case, in contrast to the functions, that we have used so far (such as printf and scanf) which consists entirely of lowercase characters. Using mixed case is a popular alternative to using underscores to make identifier names more readable. Function names are also identifiers. Hence, functions can have any name, as long as they satisfy the rules for identifiers.
/* EX-35: FUNCTION MAIN CALLS MORE THAN ONE USER DEFINED FUNCTION */ |
T#includestdio.h> comp() { printf("\n\n\t\t * Free Computer Courses"); } tut() { printf("\n\t\t * Coaching class for all students"); } main() { clrscr(); printf("\n\n\n\n\n\t\t \"NATIONAL INSTITUTE OFFERS\""); comp(); tut(); printf("\n\n\n\n\n\t\t --> \"VISIT AND JOIN\" <--"); getch(); } |
Note:
The functions comp() and tut() are placed before the function main. This is appropriate, because the function main used these functions and hence needs to know about it. However, in many cases, it is desirable to place the function main at the beginning in order to give the reader on over view of the logic.
The problem now is that while compiling main(), the functions called in it are not known to the compiler. To assist the compiler, we write the information about each function interface: its name, return type and the parameter, which it appears, prior to main itself. In main, these functions can be called. The actual code (definition) of these functions can be placed after main.
FUNCTION WITH ARGUMENTS BUT NO RETURN VALUES:
In the following program, the function square is supplied with an argument no. This function calculates the square of the given value based on the values sent to it, but it does not return any value (square of no) to the calling function.
When the function is called from the calling function, control passes to the function, then the result is evaluated, and then it displays the output.
/* EX-36: FUNCTION WITH ARGUMENTS BUT NO RETURN VALUE */ |
#includetdio.h> main() { void square(float); float no,result; clrscr(); printf("\n\tEnter the no. whose square has to be found: "); scanf("%f",&no); square(no); getch(); } void square(float num) { float res; res=num*num; printf("\n\tThe square of the number is %f",res); } |
The function definition starts with the return data type, the function name, and the arguments it accepts (within round braces). However, after the closing braces, there is no semicolon. The function body follows, enclosed within a pair of curly braces.
In large programs having several functions, there is an added advantage in declaring all the functions at the beginning; we do not need to keep track of the order in which the functions are called.
FUNCTION WITH ARGUMENTS AND RETURN VALUES:
In the following program, the function value accepts three arguments namely principle, inrate, period and manipulate the values of them. When this function is called from main(), the control passes to the called function, calculated the simple interest and the amount is returned to the calling function from called function.
/* EX-37: FUNCTION WITH ARGUMENTS AND IT RETURNS VALUE */ |
#include<stdio.h> main() { float value(float, float,int); float principal, inrate, amount; int period; clrscr(); printf("Enter Principal amount: "); scanf("%f",&principal); printf("Enter Rate of interst: "); scanf("%f",&inrate); printf("Enter the period(No. of years): "); scanf("%d",&period); amount=value(principal,inrate,period); printf("\n\n PRINCIPLE AMOUNT RATE OF INTEREST PERIOD SIMPLE INTEREST"); printf("\n\n %f\t %f \t %d \t %f",principal,inrate,period,amount); getch(); } float value(float p,float r,int n) { float netamt; netamt=(p*n*r/100); return(netamt); } |
Note: A function can return only one value of integer data type to the calling function.
Conditions must satisfy the function call:
1. The no. of arguments in the function call and in the function declaration should be same.
2. The data type of each of the arguments in the function call should be the same as the corresponding parameter in the function declaration statement i.e., the order in which we specify the arguments while calling the function must be same as the order in which the parameters are specified.
However the names of the arguments in the function call and the names of parameters in function definition are unrelated. They can be same or different.
MECHANISMS OF PASSING ARGUMENTS:
C provides two mechanisms to pass arguments to a function
• Pass arguments by value, and
• Pass arguments by address or by pointers.
An argument may take the form of a constant, variable, expression, pointer, structure etc.
i) PASSING BY VALUE:
Function in C passes all arguments by value. Passing arguments by value means that the contents of the arguments in the calling function are not changed, even if they are changed in the called function.
This is because the content of the variable is copied to the formal parameter of the function definition, thus preserving the contents of the arguments in the calling function. Passing arguments by value is useful when the function does not need to modify the values of the original variables in the calling program.
/* EX-38: SWAPPING THE NUMBER USING CALL BY VALUE */ |
#include<stdio.h> void swap(int a,int b) { int temp; temp=a; a=b; b=temp; printf("\nIn function: Swapped values: %d %d\n",a,b); } main() { int x,y; clrscr(); printf("\nEnter any two integers:\n"); scanf("%d %d",&x,&y); printf("\nIn main(): Before swapping : %d %d\n",x,y); swap(x,y); printf("\nIn main(): After swapping : %d %d",x,y); getch(); } |
Sample run:
Enter any two integers: 8 3 In main(): Before swapping : 8 3 In function: Swapped values : 3 8 In main(): After swapping : 8 3 |
In above program, when the main function calls swap(x,y); the values of the variable x and y are copied into the parameters of the function swap, a and b respectively. The values of a and b are interchanged in the swap function. The function returns and the values of a and b are discarded. i.e., the original value in main() will not affect using call by value.
ii) PASSING BY REFERENCE:
Instead of passing two integers to the swap function, we can pass the addresses of the integers that we want to swap. For this, two changes are required.
First, the function definition must be changed to accept the address of the two integers. Specifying does this
void swap(int *a, int *b)
instead of
void swap(int a, int b)
Inside the function also we have to access the value of address of a. This is done by using *a instead of a and *b instead of b.
Second, the call in main() must be changed to pass the addresses of x and y instead of their values. This is done by calling swap(&x, &y);
/* EX-39: FUNCTION - CALL BY REFERENCE */ |
#include<stdio.h> void swap(int *a,int *b) { int temp; temp=*a; *a=*b; *b=temp; printf("\n\nIn function: Swapped values: %d %d\n",*a,*b); } void main() { int x,y; clrscr(); printf("\n\n Enter any two integers: \n"); scanf("%d %d",&x,&y); printf("\n\nIn main(): Before swapping : %d %d\n",x,y); swap(&x,&y); printf("\n\nIn main(): After swapping : %d %d",x,y); getch(); } |
ITERATION AND RECURSION:
Expressing an entity in terms of itself is called recursion. In C, a function can call any function that has been defined, including itself.
The definition of factorial can be stated in two ways:
• The factorial of 0 is 1, and the factorial of any positive integer ‘n’ is the product of all integers from 1 to n.
• The factorial of 0 is 1, and factorial of any positive integer ‘n’ is the product of ‘n’ and the factorial of the number n-1.
The first definition is iterative whereas the second is recursive. In the second definition, “what is the factorial of n-1?” It is the product of n-1 and the factorial of n-2[i.e., (n-1)*n-2)!]. It continues till ‘n’ becomes 0, in which case the factorial is 1.
/* EX-40: PGM TO FIND FACTORIAL OF A NUMBER USING ITERATIVE (WITHOUT RECURSION) */ |
#include<stdio.h> long int fact(int num) { int i; long int f=1; for(i=num; i>1; i--) f*=i; return f; } void main() { int n; clrscr(); printf("\n\tEnter an integer: "); scanf("%d",&n); printf("\n\tThe factorial of %d is %ld",n,fact(n)); getch(); } |
Note: %ld is a access specifier for the data type of long integer. Sample Run: Enter an integer: 5 The factorial of 5 is 120 (i.e., 5! = 5*4*3*2*1)
/* EX-41: PGM TO FIND FACTORIAL OF A GIVEN NUMBER USING RECURSION */ |
#include<stdio.h> factorial(n) int n; { int fact; if(n==0) return(1); else fact=n*factorial(n-1); return(fact); } main() { int j; clrscr(); for(j=0;j<=5;j++) printf("\n\t%d\n", factorial(j)); getch(); } |
Recursion is implemented through the use of functions. A function that contains a function call to itself, or a function cal to a second function, which eventually calls the first function, is known as a recursive function.
Two important conditions must be satisfied by any recursive function:
• Each time a function calls itself it must be closer, in some sense to a solution.
• There must be a decision criterion for stopping the process of computation.
For the function factorial, each time the function calls itself, its argument is decrement by one (condition 1). The stopping criterion is the if statement that checks for the zero argument.