A function is often defined as a section of a program performing a specific job. In fact, the concept of functions (which were originally a subset of a concept called subprograms) came up because of the following argument.
Imagine a program wherein a set of operations are to be done often. (Not continuously N times or so, if that were the case, we can use loops). Instead of inserting the code for these operations at so many places, you write a separate program segment and compile it separately. As many times as you need it, you keep “calling” the segment, to get the result. The separate program segment is called a function and the program that calls it is called a “main program”.
‘C’ went one step further, it divided the entire concept of programming to a combination of functions. The scanf(), printf(), main() etc.. that we have seen are all functions. C provides a lot of library functions, in addition, you should be able to write your own functions & use them.
This function finds the Greatest Common Divisor of two nonnegative integer values
gcd (u,v) int u,v; { int temp; printf("The gcd of %d and %d is",u,v); while( v!=0) { temp=u%v; u=v; v=temp; } printf("%d\n",u) } main() { gcd(150,35); gcd(1026,405); gcd(83,240); }
OUTPUT:
The gcd of 150 and 35 is 5 The gcd of 1026 and 405 is 27 The gcd of 83 and 240 is 1
This function finds the Greatest Common Divisor of two nonnegative integer values and returns the result
gcd (u,v) int u,v; { int temp; while( v!=0) { temp=u%v; u=v; v=temp; } return (u); } main() { int result; result=gcd(150,35); printf("The gcd of 150 and 35 is %d\n", result); result = gcd(1026,405); printf ("The gcd of 1026 and 405 is %d\n",result); printf("The gcd of 83 and 240 is %d\n",gcd(83,240)); }
OUTPUT:
The gcd of 150 and 35 is 5 The gcd of 1026 and 405 is 27 The gcd of 83 and 240 is 1
Function to calculate the absolute value
float absolute_value (x) float x; { if (x < 0) x=-x; return(x); } main() { float f1 = -15.5, f2=20.0, f3= -5,0; int i1= -716; float result; result=absolute_value(f1); printf("result = %.2f\n", result); printf("f1 = %.2f\n",f1); result=absolute_value (f2) + absolute_value (f3); printf("result = %.2f\n",result); result=absolute_value (float) il ); printf("%.2f\n", absolute_value (-6.0) /4); }
OUTPUT:
Result = 15.50 F1= -15.50 Result = 25.00 Result = 716.00 1.50
In each of these cases, the concept is very simple. Each function is given a name and a list of parameters. Whenever you want the function to be called, refer to the function name with a suitable list of arguments. The next line of the program executed will be not from the main execution, the control comes back to the main, to the place where it was called.
But there is no restriction that the main only should call a function. A function can call another, that another and so on. See figure below:
The number indicates the sequence of control flow.
Function to calculate the absolute value of a number
float absolute_value (x) float x; { if (x < 0) x= -x; return (x); }
Function to compute the square root of a number
float square_root (x) float x; { float epsilon = .0001; float guess = 1.0; while (absolute_value (guess * guess -x) >=epsilon ) guess = ( x/guess + guess ) / 2.0; return (guess); } main() { printf("square_root (2.0) = %f\n", square_root (2.0); printf("square_root (144.0) = %f\n", square_root(144.0); printf("square_root (17.5) = %f\n",square_root (17.5); }
OUTPUT:
Square_root (2.0) = 1.414216 Square_root (144.0) = 12.000000 Square_root (17.5) = 4.183300
Now we look into certain terminology encountered w.r.f functions each function is given a name. It can be any valid variable name. This is called a function declaration. Also zero or more number of arguments to the function. They are similar to variables but are used to transfer values to the function. Often they are called formal parameters. Formal parameters will also have to be declared inside the function.
In addition, several variables are needed for the function. They are declared just like any other variable. They are called automatic local variables, because (i) They are local: their effect is limited to the function. (ii) They are automatic since they are automatically created whenever the function is called. Also, their value can be accessed only inside the function, not from any other function ( some authors also use “auto” to indicate that they are automatically created).
Again each function should also return back one/more values, the statement return (expression ) does the job. However, the type of value that the return expression returns (int, char, or float) will also have to be indicated in the name of the function (like int gcd(), float convert() etc.. ). If, however, no such declaration is made, the function is expressed to return an int value.
If the function does not return any value, it is called a void function and should be indicated so. (void main() for example). However, there is a small problem, since any function can call any other function, it is also possible that a function that is not yet defined can be used. (see example). In that case, the compiler presumes that the called function returns only int values, even if return float or even if it is void.
To overcome this, it is desirable to declare before, how that function 2 return float (as shown):
Function to find the minimum in an array
int minimum (values) int values [10]; { int minimum_value, i; minimum_value = values [0]; for ( i=1; i<10; ++i) if (values [i] < minimum_value) minimum_value = values[i]; return (minimum_value); } main() { int scores[10], i, minimum_score; printf("enter 10 scores \n"); for (i =0; i < 10; ++i) scanf("%d",&scores[i]); minimum_score = minimum (scores); printf("\nMinimum score is %d\n",minimum_score); }
OUTPUT:
Enter 10 scores 69 97 65 87 69 86 78 67 92 90 Minimum score 65
Sorting
Sorting is a very popular activity in programming, which essentially arranges a set of given numbers in ascending/ descending order. One simple way is to simply keep finding the smallest number one after another and put them in another array ( using the previously defined method). However, more efficient method are available one of them is called the exchange sort method.
Here we begin comparing the first element with the second. If the first is smaller than second, we leave them as it is, otherwise, we “swap” then (i.e interchange them). Next compare the first element with the third. Again if the first one is smaller, leave it as it is, otherwise swap the first and third element. This way, if we keep comparing the first element with all other elements ( and keep swapping if necessary) at the end of the iterations, we end up with the first element being the smallest of elements.
Now, we can repeat the same with the second element and all other elements; third element and all other elements etc. In the end, we will be left with an array in which the numbers are in ascending order. This algorithm is called the exchange sort algorithm.
Step1: set i to 0
Step2: set j to i + 1
Step3: if a[i] > a[j] exchange their values
Step4: set j to j+1. If j < n goto step 3
Step5: set i to i+1 If i< n-1 goto step 2
Step6: a is now sorted in ascending order.
Sort an array of integers into ascending order
void sort (a,n) int a[]; int n; { int i,j,temp; for(i =0; i< n-1; ++i) for ( j=i+1; j<n; ++j) if ( a[i] > a[j] ) { temp = a[i]; a[i] = a[j]; a[j] = temp; } } main() int i; static int array[16] = { 34,-5,6,0,12,100,56,22,44,-3,-9,12,17,22,6,11}; printf("The array before the store:\"); for (i=0; i< 16; ++i) printf(%d",array[i] ); sort (array, 16); printf ("\n\n The array after the sort:\n"); for ( i=0; i <16; ++i) printf("%d", array[i] ); printf("\n"); }
OUTPUT:
The array before the store: 34,-5,6,0,12,100,56,22,44,-3,-9,12,17,22,6,11 The array after the store: -9 -5 -3 0 6 6 11 12 12 17 22 22 34 44 56 100
Function to multiply a 3 x 5 array by a scalar
void scalar_multiply (matrix,scalar) int matrix [3] [5] ; int scalar; { int row,column; for ( row = 0; row < 3; ++row ) for ( column = 0; column < 5; ++column) matrix[row] [column] *=scalar; } void display_matrix (matrix) int matrix [3] [5]; { int row,column; for (row =0; row < 3; ++row) { for ( column = 0; column < 5; ++column ) printf("%5d", matrix[row][column] ); printf("\n"); } } main() { static int sample_matrix[3][5] = { { 7, 16, 55, 13, 12 }, { 12, 10, 52, 0, 7 }, { -2, 1, 2, 4, 9 } }; printf("Original matrix : \n"); display_matrix (sample_matrix); scalar_multiply (sample_matrix, 2); printf("\nMultiplied by 2: \n"); display_matrix (sample_matrix); scalar_multiply (sample_matrix, -1); printf ("\n Then multiplied by -1\n"); display_matrix (sample_matrix); }
OUTPUT:
Original matrix: 7 16 55 13 12 12 10 52 0 7 -2 1 2 4 9 Multiplied by 2: 14 32 110 26 24 24 20 104 0 14 -4 2 4 8 18 Then multiplied by -1: -14 -32 -110 -26 -24 -24 -20 -104 0 -14 4 -2 -4 - 8 -18
Before we proceed, we would introduce one more concept. Previously we talked about local variables (auto local variables). These variables cease to exist once that function is exited. So, in case we want their values to be available even after the function execution is complete, it can be done in two ways.
i) Make that variable Global. i.e define them before all functions. Then their vlues will be available from all the functions and they can be accessed from any of the functions.
Example:
#include<stdio.h. Int a,b,c; Main() { } function() { } etc..
Here. a,b,c are global variables and can be accessed from the main as well as all other functions.
ii) The second method is to call them static in the function in which it is used.
Example:
#include<stdio.h> main() { } function1() { static int a - - - - - - - - - - }
Here, the scope of the variable a is only for the function1. I.e. it’s values cannot be accessed from any other function. However, when we next time come back to function 1, the previously computed value of a is found to be retained.
Recursive functions
C provides for a special type of function called Recursive function. Previously we have seen that in C any function can call any other function. The limiting case is can a function call itself? The answer is yes. A function can call itself. If a function repeatedly keeps calling itself ( until certain conditions are satisfied called terminating conditions), then such a function is called a recursive function.
Consider the following example:
The factorial of a number is defined as the product of all integers from 1 to that number. For example the factorial of 4, Represented as 4! = 4 x 3 x 2 x 1 = 24 And 5! = 5 x 4 x 3 x 2 x 1 = 120
One method of evaluation is, of course, by a loop
for ( I=1; e<=n; ++I) { fact= fact * I; }
This method is the method of recursion. There is another method. Now look at the previous example 5! Can be evaluated if we had known 4!
5! = 5 x 4!
If we write the relevant numbers, we know that 4! = 4 x 3!
3! = 3 x 2! And
2! = 2 x 1!
But 1! Is known, it is 1.
So, if we work back wards, using the formula n! = n * (n-1)! Until we strike 1, then we can evaluate the factorial of any number n. This can be done, if a function, when called with an argument n, repeatedly calls itself with (n-1) until the value of (n-1) reaches 1. ( This value =1 is called the terminating condition).
The following program adequately illustrates the concept.
Recursive function to calculate the factorial of a positive integer
long int factorial (n) int n; { long int result; if (n == 0) result = 1; else result = n * factorial ( n-1) ; return (result); } main() { int j; for ( j =0; j < 11; ++j) printf("%d! = %ld\n",j,factorial (j) ); }
OUTPUT:
0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10!=3628800
Though in this case, the advantage of using recursive functions, may not be obvious at first sight, there are situations, when a recursive function reduces the complexity of program writing significantly.
Program to find the first n entries in the fibonacci
#include<stdio.h> main(0 { int i,n; int fibonacci(int,i); /* read the number of entries */ printf(“Enter no. of entries:”); scanf(“%d”,&n); /* calculate and display the fibonacci series */ printf(“The fibonacci series: \n”); for(i=1; i<n; i+=) printf(“%d\n”,fibonacci(i) ); } /* end of main() */ int fibonacci(int x) /* function to find the nth fibonacci no */ { if (( x== 1) || (x = = 2)) return(1); else return(fibonacci(x-1) + fibonacci(x-2)); } /* end of fibonacci() */
OUTPUT:
Enter no.of entries: 9 The fibonacci series: 1 1 2 3 5 8 13 21 34
Program to calculate the GCD of two numbers
#include <stdio.h> #include<math.h> unsigned gcd(unsigned num1,unsigned num2); main() { unsigned num1,num2; printf(“Enter two numbers whose GCD is to be found:”); scanf(“%u %u”, &num1, &num2); printf(“GCD of %u and %u is = %u\n”,num1,num2,gcd(num1,num2)): } /* Function to calculate the GCD of two unsigned numbers */ unsigned gcd(unsigned num1, unsigned num2); { unsigned num, gcdnum,i; num = num1 < num2 ? num1; for (i =1; i<=num; i++) if ((num1% i = = 0) && (num2 % i = =0) gcdnum = i; return gcdnum; }
OUTPUT:
Enter two numbers whose GCD is to be found: 25 10 GCD of 25 and 10 is = 5 Enter two numbers whose GCD is to be found: 47 10 GCD of 47 and 10 is = 1 Enter two numbers whose GCD is to be found: 16 64 GCD of 16 and 64 is = 16
Program to check the given integer prime or not
#include <stdio.h> #include<math.h> int isprime(unsigned num); main() { int num; printf("\nEnter an integer:"); scanf("%u",&num); if(num < 0) printf("Invalid entri\n"); else { if (isprime(num)) printf("%d is a prime number\n",num); else printf("%d is not prime number\n",num); } } int isprime(unsigned num) { unsigned index sq; if((num = = 1) || (num = =2)) return 1; sq = sqrt((double)num); for(index = 2; index < = sq; index++) { if (num % index = = 0) return; } return 1; }
OUTPUT:
Enter an integer 15 15 is not a prime number Enter an integer: 29 29 is a prime number Enter an integer: 397 397 is a prime number
Program to find prime numbers upto N
#include<stdio.h> #include<math.h> int isprime(unsigned num); main() { unsigned index,pcnt=0; int max; printf("\nEnter integer N upto which primes are to be found:"); scanf("%u",&max); if(max > 0) { printf("Prime nos. Upto %u:\n",max); for (index = 1; index < = max; index++) if (isprime(index)) { printf("%u\n",index); pcnt++; } printf("\nNumber of primes = %u",pcnt); } } /*Function to find whether a given unsigned */ /* integer is a prime number */ int isprime(unsigned num) { unsigned index sq; if((num = = 1) || (num = = 2)) return1; sq = sqrt((double)num); for (index = 2; index <=sq; index++) { if num%index = = 0) return 0; } return 1; {
Output:
Enter integer N upto which primes are to be found: 10 Prime nos. Upto 10; 1 2 3 5 7 Number of primes = 5
Program to find n!/(n-r)! And n!(n-r)!r! for given values of n and r*
#include <stdio.h> double factorial (int num); main() { /* Variable declaration */ int n,r; double val1,val2; printf("Enter 2 integer numbers(n & r):"); scanf(%d%d",&n,&r); val1 = factorial(n)/factorial(n-r); val2 = factorial(n)/(factorial(n-r) * factorial(r)); printf("%d!/(%d-%d)! = %d1f\n",n,n,r,val1); printf("%d!/(%d-%d)! %d! = %d1f\n",n,n,r,r,val2); } /* Function to find the factorial of a number */ double factorial(int num); { unsigned i; double fact = 1; /* Repeat until i reaches 1 */ for ( i=num; i>1; i--) fact = fact * i; return fact; }
OUTPUT:
Enter 2 integer numbers(n & r): 10 2 10!/(10-2)! = 90.000000 10!/10-2)! 2! = 45.000000 Enter 2 integer numbers(n & r): 5 3 5!/(5-3)! = 60.000000 5!/5-3)! 3! = 10.000000 Enter 2 integer numbers(n & r): 3 2 3!/(3-2)! = 6.000000 3!/3-2)! 2! = 3.000000