05 Functions
05 Functions
1
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Introduction
Function
• A program segment that carries out a specific, well-defined task.
• Examples
• A function to find the gcd of two numbers
• A function to find the largest of n numbers
Code
Execution
void print_banner ( )
{ int main () print_banner {
{
printf(“********\n”);
…
} }
print_banner ();
…
print_banner {
print_banner ();
int main ( )
{ } }
. . .
print_banner ( ) ;
. . .
print_banner ( ) ; If function A calls function B:
} A : calling function / caller function
B : called function
3
Why Functions?
Functions allow one to develop a program in a modular fashion.
• Codes become readable
• Codes become manageable to debug and maintain
Write your own functions to avoid writing the same code segments multiple times
• If you check several integers for primality in various places of your code, just write a single
primality-testing function, and call it on all occasions
4
Use of functions: Area of a circle
#include <stdio.h>
main()
{
float radius, area;
}
main()
{
The first line contains the return-value-type, the function name, and
float radius, area;
optionally a set of comma-separated arguments enclosed in ( ).
• Each argument has an associated type declaration. scanf (“%f”, &radius);
• The arguments are called formal arguments or formal parameters. area = myfunc (radius);
Example: printf (“\n Area is %f \n”, area);
}
float myfunc (float r)
int gcd (int A, int B)
7
Calling a function
#include <stdio.h>
• Called by specifying the function name and parameters in an
instruction in the calling function.
/* Function to compute the area of a
circle */
float myfunc (float r)
• When a function is called from some other function, the {
float a;
corresponding arguments in the function call are called actual a = 3.14159 * r * r;
arguments or actual parameters. return a;
}
• The function call must include a matching actual parameter for
each formal parameter. main()
{
• Position of an actual parameters in the parameter list in the float radius, area;
call must match the position of the corresponding formal
parameter in the function definition. scanf (“%f”, &radius);
area = myfunc (radius);
• The formal and actual arguments would match in their data printf (“\n Area is %f \n”, area);
types. Mismatches are auto-typecasted if possible. }
8
Function Prototypes: declaring a function
Usually, a function is defined before it is called.
• main() is usually the last function in the program written.
• Easy for the compiler to identify function definitions in a single scan through the file.
Some prefer to write the functions after main(). There may be functions that call each other.
• Must be some way to tell the compiler what is a function when compilation reaches a function call.
• Function prototypes are used for this purpose
• Only needed if function definition comes after a call to that function.
• Function prototypes are usually written at the beginning of a program, ahead of any functions (including main()).
• Prototypes must specify the types. Parameter names are optional (ignored by the compiler).
• Examples:
int gcd (int , int );
void div7 (int number);
• Note the semicolon at the end of the line.
• The parameter name, if specified, can be anything; but it is a good practice to use the same names as in the
function definition.
9
Example:
Function prototype / declaration
#include <stdio.h>
int sum( int, int );
int main( ) This program needs a function prototype or
{ function declaration since the function call
int x, y; comes before the function definition.
scanf(“%d%d”, &x, &y);
printf(“Sum = %d\n”, sum(x, y));
}
Function call
int sum (int a, int b)
{
return a + b; Function definition
}
10
Return value
• Sometimes a function is not meant for returning anything
• A function can return a single value
• Such functions are of type void
Using return statement
• Like all values in C, a function return value has a type
• The return value can be assigned to a variable in the calling Example: A function which prints if a number is divisible
function by 7 or not.
11
The return statement
void compute_and_print_itax ()
In a value-returning function, return does two distinct {
things: float income;
scanf (“%f”, &income);
• Specify the value returned by the execution of the if (income < 50000) {
function. printf (“Income tax = Nil\n”);
• Terminate the execution of the called function and return; /* Terminates function execution */
transfer control back to the caller function. }
if (income < 60000) {
printf (“Income tax = %f\n”, 0.1*(income-50000));
A function can only return one value. return; /* Terminates function execution */
• The value can be any expression matching the return }
type. if (income < 150000) {
printf (“Income tax = %f\n”,0.2*(income-60000)+1000);
• It might contain more than one return statement.
return ; /* Terminates function execution */
}
In a void function: printf (“Income tax = %f\n”,0.3*(income-150000)+19000);
}
• "return” is optional at the end of the function body.
• "return” may also be used to terminate execution of
the function explicitly before reaching the end.
• No return value should appear following “return”.
12
Another Example: What is happening here?
int main()
int prime (int x)
{
{
int numb, flag, j=3;
int i, test;
scanf(“%d”,&numb);
i=2, test =0;
while (j <= numb) {
while ((i <= sqrt(x)) && (test ==0))
flag = prime(j);
{
if (flag == 0)
if (x%i==0) test = 1;
printf( “%d is prime\n”, j );
i++;
j++;
}
}
return test;
return 0;
}
}
13
Tracking the flow of control
int main() PROGRAM OUTPUT
{ 5
int prime(int x) numb = 5
int numb, flag, j=3;
{
scanf(“%d”,&numb); int i, test; Main, j = 3
printf(“numb = %d \n”,numb); i = 2; test = 0; In function, x = 3
while (j <= numb) Returning, test = 0
{ printf(“In function, x = %d \n”,x); Main, flag = 0
while ((i <= sqrt(x)) && (test == 0)) 3 is prime
printf(“\nMain, j = %d\n”,j);
flag = prime(j); {
Main, j = 4
if (x%i == 0) test = 1; In function, x = 4
printf(“Main, flag = %d\n”,flag);
i++; Returning, test = 1
} Main, flag = 1
if (flag == 0) printf(“%d is prime\n”,j); printf(“Returning, test = %d \n”,test);
j++; Main, j = 5
} return test; In function, x = 5
return 0; } Returning, test = 0
} Main, flag = 0
5 is prime
14
Nested Functions
A function cannot be defined within another function. It can be called within another function.
• All function definitions must be disjoint.
15
Example: main( ) calls ncr( ), ncr( ) calls fact( )
16
Local variables
A function can define its own local variables.
The local variables are known (can be accessed) only within the function in which they are
declared.
• Local variables cease to exist when the function returns.
• Each execution of the function uses a new set of local variables.
Parameters are also local.
17
Revisiting nCr
18
Scope of a variable
• Part of the program from which the value of the variable can be used (seen).
19
What happens here?
#include <stdio.h>
int A; /* This A is a global variable */
void main( )
{
A = 1;
myProc( );
A=2
printf ( "A = %d\n", A );
}
Scope of
global A void myProc( )
{
A = 2;
/* other statements */
printf ( "A = %d\n", A ); A=2
}
20
Local Scope replaces Global Scope
#include <stdio.h>
int A; /* This A is a global variable */
void main( )
{
A = 1;
myProc( );
printf ( "A = %d\n", A ); A=1
}
21
Parameter Passing
When the function is called, the value of the actual parameter is copied to the formal parameter
parameter passing
int main ()
{ . . . double area (double r)
double radius, {
a; return (3.14*r*r);
. . . }
a =
area(radius);
. . .
}
22
Parameter Passing by Value in C
Call by reference
• Passes the address of the original argument to a called function.
• Execution of the function may affect the original argument in the calling function.
• Not directly supported in C, but supported in some other languages like C++.
• In C, you can pass copies of addresses to get the desired effect.
23
Parameter passing and return: 1
int main()
{
int a=10, b;
printf (“Initially a = %d\n”, a);
b = change (a);
printf (“a = %d, b = %d\n”, a, b); Output
return 0;
} Initially a = 10
Before x = 10
int change (int x)
{ After x = 5
printf (“Before x = %d\n”,x); a = 10, b = 5
x = x / 2;
printf (“After x = %d\n”, x);
return (x);
}
24
Parameter passing and return: 2
int main()
{
int x=10, b;
printf (“M: Initially x = %d\n”, x);
b = change (x);
printf (“M: x = %d, b = %d\n”, x, b); Output
return 0;
} M: Initially x = 10
F: Before x = 10
int change (int x)
{ F: After x = 5
printf (“F: Before x = %d\n”,x);
M: x = 10, b = 5
x = x / 2;
printf (“F: After x = %d\n”, x);
return (x);
}
25
Parameter passing and return: 3
int main()
{ Output
int x=10, y=5;
M1: x = 10, y = 5
printf (“M1: x = %d, y = %d\n”, x, y);
interchange (x, y); F1: x = 10, y = 5
printf (“M2: x = %d, y = %d\n”, x, y); F2: x = 5, y = 10
return 0;
M2: x = 10, y = 5
}
26
Header files and preprocessor
27
Header Files
Header files:
• Contain function declarations / prototypes for library functions.
• <stdlib.h> , <math.h> , etc.
• Load with: #include <filename>
• Example: #include <math.h>
• The function definitions of library functions are in the actual libraries (e.g., math library).
28
C preprocessor
29
#define: Macro definition
Preprocessor directive in the following form:
#define string1 string2
#define PI 3.1415926
main()
main()
{
{
macro pre-processing float r = 4.0, area;
float r = 4.0, area;
area = 3.1415926 * r * r;
area = PI * r * r;
}
}
30
#define with arguments
#define statement may be used with arguments.
• Example: #define sqr(x) x*x
• How will macro substitution be carried out?
r = sqr(a) + sqr(30); r = a*a + 30*30;
r = sqr(a+b); r = a+b*a+b;
Macros are not functions. They are literally substituted without evaluation.
31
Practice Problems
• Normally, read and print everything from main(). Do not read or print anything inside the function. This will
give you better practice.
• However, you can write simple functions for printing an array.
32
Passing Arrays to a Function
33
How to pass arrays to a function?
An array name can be used as an argument to a function.
• Permits the entire array (not exactly) to be passed to the function.
• The way it is passed differs from that for ordinary variables.
Rules:
• Function definition: corresponding formal argument is declared by writing the array name
followed by a pair of empty brackets.
f ( int A[] )
{
...
}
• Function call: the array name must appear by itself as argument, without brackets or subscripts.
34
f(A), f(B)
main()
{
int n;
We can also write float list[100], avg;
:
float x[100] avg = average(n,list);
The compiler completely :
ignores the size 100. }
35
Example: Minimum of a set of numbers
#include <stdio.h> int minimum(int x[], int size)
int minimum (int x[], int y); {
int i, min = 99999;
main()
{ for (i=0;i<size;i++)
int a[100], i, n; if (min > x[i])
min = x[i];
scanf (”%d”, &n); return (min);
for (i=0; i<n; i++) }
scanf (”%d”, &a[i]);
Note: When a function takes an array as argument, it does not care about how big the array is declared to be.
Moreover, the user is not forced to use the entire allocated array.
The programmer must specify to the function “I am using only these many elements of the array.”
36
The Actual Mechanism
When an array is passed to a function, the values of the array elements are not passed
to the function.
• The array name is interpreted as the address of the first array element.
• The formal argument therefore becomes a pointer to the first array element.
• When an array element is accessed inside the function, the address is calculated
using the formula stated before.
• Changes made to the array elements inside the called function are also reflected
in the calling function.
37
Parameters are passed in C using call-by-value.
Passing the starting address when an array is sent as argument simulates call-by-reference.
Basically what it means:
• If a function changes the elements of an array that is passed as argument, these changes
will be made to the original array that is passed to the function.
• This does not apply when an individual element of an array is passed as argument.
38
Example: Square each element of array
#include <stdio.h>
void square (int a[], int b);
void square (int x[], int size)
{
main()
int i;
{
int a[100], i, n;
for (i=0;i<size;i++)
x[i] = x[i]*x[i];
scanf (”%d”, &n);
for (i=0; i<n; i++)
return;
scanf (”%d”, &a[i]);
}
square (a, n);
39
Practice Problems
1. Read in an integer n (n < 25). Read n integers in an array A. Then do the following (write separate
programs for each, only the reading part is common).
a) Find the sum of the absolute values of the integers.
b) Copy the positive and negative integers in the array into two additional arrays B and C
respectively. Print A, B, and C.
c) Exchange the values of every pair of values from the start (so exchange A[0] and A[1], A[2] and
A[3] and so on). If the number of elements is odd, the last value should stay the same.
2. Read in two integers n and m (n, m < 50). Read n integers in an array A. Read m integers in an array B.
Then do the following (write separate programs for each part, only the reading part is common).
a) Find if there are any two elements x, y in A and an element z in B, such that x + y = z
b) Copy in another array C all elements that are in both A and B (intersection)
c) Copy in another array C all elements that are in either A and B (union)
d) Copy in another array C all elements that are in A but not in B (difference)
40