5.1 Top-Down Design: Main
5.1 Top-Down Design: Main
The programs presented so far are quiet simple. But when the problem is larger and complex, the
program can be divided in to simpler and manageable parts known as modules. Each module can
do a well-defined task. This process of dividing a problem into number of smaller subtasks is
known as top-down design.
Problem
Task 1 Task 2
5.2.1 Advantages
1. Complex programs can be divided into number of smaller components.
2. It avoids redundant programming and supports code reusability. i.e., when the same set of
instructions is accessed repeatedly in a program, they can be written as a function.
Frequently used functions can be stored in the form of a library file. If a program requires
a particular routine, the corresponding library function can be called.
3. It is easy to write and debug programs containing functions.
4. Functions can be used to protect the local data. It is the data available only to the
function. It cannot be changed by an outside function.
1
Example
void main()
{
display( );
printf(“Back to main \n “);
print( );
printf(“Back to main \n “);
}
void display( )
{
printf(“ Now in display \n”);
return ;
}
void print( )
{
printf(“Now in print \n”);
return;
}
Output
Now in display
Back to main
Now in print
Back to main
In the above example, the execution starts from the main function. Inside main, the function
display is called first. The activity of main is temporarily suspended and control is given to the
display function. When the display function completed its task, control will be transferred to
main function again.
Here main( ) is the ‘calling’ function and display ( ) and print() are the ‘called’ functions.
2
5.3 Defining a function
The function definition contains the set of statements needed to complete the task of that
function. It has 2 components:
a) Function header – containing argument declarations, function name and the return type.
The general form is
return _type name(type1 arg1, type2 arg2, …., typen argn)
where,
return_type - data type of value returned by the function.
(void – when there is no return value)
name - function name
arg1, …., argn - List of arguments or parameters.
type1,…, typen - data types of the arguments.
The arguments declared in the function definition are known as formal arguments or
formal parameters. The arguments are local to that function and cannot be accessed from
outside.
b) Function body - consists of the set of statements that defines the action to be done by the
function. It may contain one or more return statements for returning a value to the calling
function. But an empty return statement is optional, if the function doesn’t return a value.
Example
The following function takes 2 arguments and prints the larger value.
void max (int a, int b) Function header
{
if(a>=b)
printf(“%d is larger”,a);
else Body of the function
printf(“%d is larger”,b);
return ;
}
3
fun 1 ( ) fun 2 ( )
{ {
………. ……….
fun2( ); ………..
} }
Example
#include<stdio.h>
void print(int x)
{
printf(“%d \n”,x);
return;
}
void main( )
{
int a=10;
print (5);
print (a);
}
Output
5
10
Example
#include<stdio.h>
int sqr(int x)
{
return(x * x); /* returns the square of x */
}
void main()
{
int a = 5, b;
b = sqr(a);
printf(“%d”,b);
}
Output 25
A function can be called by specifying its name, list of arguments enclosed in parenthesis and
separated by commas and terminated by a semicolon. Use empty parenthesis, when there are no
arguments.
The general form is
name(arg1,arg2,….arg n);
Example
display ( ); /* calling a function without arguments */
power(a,b); /* calling a function with arguments */
The function call can be a part of an expression, if it returns a value. But a function not returning
a value should not be used in expressions; they must be an independent statement.
Example
#include<stdio.h>
int sum(int x, int y)
{
return(x+y);
}
void main( )
{
int a = 1,b = 2,c = -3,d = 4;
res = sum( a, b) / sum( c , d ); /* function calls as part of an
expression */
printf(“%d”,res);
}
Output
3
5
The arguments appearing in the function calling statement are called as actual arguments and
the arguments appearing in the function header are known as formal arguments. The actual and
formal parameters must match in number, type and order. The values of actual arguments are
assigned to the formal argument on a one to one basis. But the names of actual and formal
argument may differ.
A function declaration contains only a function header but no code. The declaration consists of 3
parts, as like function headers.
a. Return type (void – if no return value)
b. Function name
c. Name (optional ) and type (essential) of formal parameters.
In function headers, there will not be semicolons. But function declaration ends with semicolon.
Example
float interest(int, int, int);
The above function declaration tells the compiler that the function interest takes 3 integer
arguments and returns a float value.
Example
#include<stdio.h>
float mul(float x, float y); /* function declaration with argument names */
int sub(int , int); /*function declaration without argument names*/
void main ( )
6
{
float a = 1.5, b = 1.1;
int c = 5, d = 2;
printf(“%f \n”, mul(a,b));
printf(“%d \n”, sub(c,d));
}
int sub (int x, int y)
{
return( x- y );
}
float mul (float x, float y)
{
return(x * y);
}
7
a. Call by value.
b. Call by reference.
a. Call by value
In this method, the value of the actual arguments in the calling function is copied into
corresponding formal arguments of the called function.
Therefore, the changes made to the formal arguments have no effect on the values of
actual arguments.
Example
#include<stdio.h>
void change (int x)
{
int a=5; 5 a
printf(“ Before change %d \n “, a);
change (a);
printf(“After change %d \n”, a);
}
void change( int x)
{
x = x +5;
return; 5 x
}
Output
Before change : 5
After change : 5
Advantages
1) It protects the original data in the calling function, since the changes inside the called
function will not be reflected over it.
2) It allows even expressions as actual arguments rather than a single variable.
Disadvantage
1) It is a one- way transfer of information from the calling function to called function.
Information cannot be transferred back through arguments.
8
Example
#include<stdio.h>
void change( int *x);
void main( )
{
int a = 5;
printf(“Before change : %d”,a);
change(&a); / * address of a is passed */
printf(“After change : %d”, a);
}
void change(int *x) / * x is a pointer * /
{
*x = *x + 5; /* x is an address and * x – value at that address * /
}
Output
Before change : 5
After change : 10
Storage Classes
In C, there are two ways to characterize variables.
a. By data type
The data type refers to the type of information represented by a variable.
e.g., int, float etc.,
b. By storage classes
The storage class provides information about their location and visibility.
5.10.1 Basics
static Local variables in a function which retains its value even after the
9
control is given back to the calling function.
a. Automatic variables
Automatic variables are always declared inside a function or a block and they are local to that
function or block.
By default, any variable declared without a storage class specifier, will be treated as auto
variables. Hence, even the keyword auto is not required. All the variables used by us so far
are auto variables.
e.g., int x; /* denotes an auto variable */
auto float y;
The characteristics of auto variables are given below.
}
Variables a &
b die here /* a & b are not valid here */
Example
#include <stdio.h>
void fun1( );
void fun2( );
void main()
{
10
int a=500;
fun1( );
printf("%d\n",a);
}
void fun1( )
{
int a=300;
fun2( );
printf("%d\n",a);
}
void fun2( )
{
int a=100;
printf("%d\n",a);
}
Output
100
300
500
b. Static variables
A static variable can be defined inside a function or a block and they are local to that function
or block. It cannot be accessed from outside the function.
But unlike the auto variables, static variables retain their values throughout the life of that
program. Hence, if a function is exited and re-entered again, the static variables retain their
values.
11
for (i = 0; i<3; i++)
fun( );
}
void fun( )
{
static int a=0; /* Initialization works only once */
a++;
printf("a = %d \n",a);
}
Output
a=1
a=2
a=3
In the above example, the static variable a is first initialized to 0 and then incremented by 1.
When the same function is called for the second time, a will not be initialized to 0 but the
previous value of a i.e., 1 will be retained. That is why, a++ makes a to become 2. When the
same function is called for the third time, the previous value of a i.e., 2 will get incremented and
makes a as 3.
The following program demonstrates the difference between automatic and static variables.
Example
#include <stdio.h>
void fun( );
void main( )
{
int count;
for (count = 0; count < 3; count++)
{
printf("At iteration %d: ", count);
fun();
}
}
void fun(void)
{
static int x = 0;
int y = 0;
x++;
y++;
printf("x = %d, y = %d\n", x, y);
}
Output
At iteration 0: x = 1, y = 1
At iteration 1: x = 2, y = 1
At iteration 2: x = 3 y = 1
12
c. External variables
They are also known as global variables. Extern variables are alive and active throughout the
program. They are declared outside all the functions. Hence, they can be accessed from
anywhere in the program.
The characteristics of extern variables are given below.
3. Initialization
Same as static variables.
Example
int count;
void fun1( )
{
……………..
}
void fun2( )
{
……………..
}
void main( )
{
……………..
}
In the above example, the global variable count can be used by all the 3 functions fun1( ), fun2( )
and main( ).
If a local variable and a global variable have the same name, the local variable will have
precedence over the global variable.
Example
int count;
void fun1( )
{ count = 0; /* Global variable */
……………..
}
void fun2( )
{
int count = 10;
count++; /* Local variable */
}
13
void main( )
{
……………..
}
In the above example, the usage of variable count in the function fun1( ) leads to error message.
To avoid this, the variable may be declared as extern which tells the compiler that count is
defined somewhere else in the program.
Example
void fun1( )
{ extern int count; /* External declaration */
……………..
}
int count = 0;
void main( )
{
count++; /* OK */
……………..
}
d. Register variables
A register variable tells the compiler to use a CPU register for the variable instead of a
memory location.
The scope and lifetime of Register variables are same as auto variables.
Advantages
a. The time taken for accessing a CPU register is less than the time required for accessing a
memory location. Hence they are more efficient.
b. Frequently accessed variables can be stored in registers.
Disadvantages
14
a. Only few numbers of Registers are available with CPU and the compiler uses all of them
for running the program efficiently. Hence most of the time compiler will not allocate
registers for our request.
b. Address (&) operator and indirection (*) operator cannot be used with register variables.
5.9 Recursion
Recursion is a process in which a function calls itself repeatedly till some specified condition is
satisfied.
5.9.1 Factorial
Consider the problem of finding the factorial of a number n.
By definition, 0! = 1
Now, 1! = 1 * 0! = 1
2! = 2 * 1! = 2 * 1 = 2
3! = 3 * 2! = 3 * 2 = 6
4! = 4 * 3! = 4 * 6 = 24
Similarly, n! = n * (n-1)!
The original problem n! is expressed recursively in terms of a previous result (n-1)!,
which is assumed to be known.
The case 0! = 1 provides a stopping condition for recursion and is also known as the base
case. The other cases are known as general cases.
Example
#include<stdio.h>
int fact(int);
void main( )
{
int n;
printf(“Enter the no \n”);
scanf(“%d”,&n);
printf(“factorial is %d”, fact (n));
}
int fact(int n)
{
if (n = = 0)
return(1);
else
return( n * fact (n-1));
}
15
5.9.2 Binary Search
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 20
int binsearch(int a[], int x, int low, int high);
void main()
{
int a[MAX_SIZE];
int key, fnd, indx, n;
printf("Enter the No. of elements :\n");
scanf("%d", &n);
printf("Enter the Array Elemnet values : \n");
for (indx=0;indx < n; indx++)
scanf("%d",a[indx]);
fnd = binsrch(a, key, 0,n-1);
if (fnd != -1)
printf("Searched element %d found at location %d\n",key,fnd);
else
printf("Element not found\n");
}
The “Towers of Hanoi” problem involves three poles and a number of different-sized disks. Let
us consider the problem with 3 disks. Initially, the disks are stacked on the source pole in the
order of decreasing size ie., largest at the bottom and smallest at the top.
1
2
3
Source Intermediate Destination
16
The objective is to transfer the three disks from the source pole to the destination pole, obeying
the following rules.
Goal
1
2
3
Source Intermediate Destination
Recursive solution
1
2 2 1
A B C A B C
Start Step 1
1
1 2 2
17
A B C A B C
Step 2 Step 3
Case 3 : Number of disks = 3
Steps : a. Move two disks from source to intermediate.
b. Move one disk from source to destination.
c. Move two disks from intermediate to destination.
General Solution
1. Move n-1 disks from source to intermediate.
2. Move one disk from source to destination.(Base Case)
3. Move n-1 disks from intermediate to destination.
Program
#include<stdio.h>
void towers(int n, char source, char dest, char inter);
void main ( )
{
int n;
printf(“ How many disks? \n”);
scanf(“%d”, &n);
towers(n, ‘A’, ‘B’, ‘C’);
}
void towers(int n, char source, char dest, char inter)
{
if (n>0)
{
towers(n-1, source, inter, dest);
printf(“ Move disk %d from %c to %c \n”, n, source, dest);
towers(n-1, inter, dest, source);
}
}
Output
How many disks?
3
Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C
18
Advantages of Recursion
Limitations of Recursion
Important questions
1. What is a function?
A function is a self contained program segment that carries out some specific, well
defined task. C program consists of one or more functions. One of these functions must
be called main.
The major difference between actual and formal parameters is that actual parameters are
the source of information; calling programs pass actual parameters to called functions.
The called functions access the information using corresponding formal parameters.
Information is returned from the function to calling portion of the program vi return
statement. The return statement also causes program logic to return to the point from
which the function was accessed. return statement can be expressed as
Return expression;
5. How can you access the function?
19
6. What are function prototypes?
A function prototype is a function declaration that specifies the data types of its
arguments in the parameter list. The compiler uses the information in a function
prototype to ensure that the corresponding function definition and all corresponding
function declarations and calls within the scope of the prototype contain the correct
number of arguments or parameters, and that each argument or parameter is of the correct
data type.
7. Write a function that accepts two integer quantities and determines large vale,
which is then displayed.
Maximum(int x, int y)
{
int z;
z=(x>=y)?:x:y;
printf(“maximum value=%d”,z);
return;
}
20
else
return(y);
}
Storage class refers to permanence of a variable and its scope within the program ie.the
portion of the program over which the variable is recognized.
12. List out the various storage classes in C
1. Automatic
2. Register
3. Static
4. External
Part B
#include <stdio.h>
int fact(int x); //function declaration
void main()
{
int n;
printf("Enter the no:");
scanf("%d",&n);
printf("Factorial is:%d",fact(n));//function call
21
}
/*function definition*/
int fact(int x)
{
if(x<=1)
return(1);
else
return(x*fact(x-1));
}
#include<stdio.h>
#include<conio.h>
int gcd(int x,int y);
void main()
{
int a,b;
clrscr();
printf("Enter the numbers:");
scanf("%d%d",&a,&b);
printf("GCD is:%d",gcd(a,b));
getch();
}
int gcd(int x,int y)
{
if(y==0)
return x;
else
return gcd(y,x%y);
}
Functions - Overview
A function is an independent module or a self-contained program segment that performs some
specific well-defined task when it is called.
22
Every C program consists of one or more functions. One of these functions must be the
main.
The execution of a program always starts and ends with main, but it can call other functions
to do specific tasks.
A function will do the specific task whenever it is called from some other portion of the
program. Once the function has carried out its work, control will be returned to the calling
point.
Moreover, information can be passed to a function through special identifies called
arguments or parameters and returned through the return statement.
Example
void main()
{
display( );
printf(“Back to main \n “);
print( );
printf(“Back to main \n “);
}
void display( )
{
printf(“ Now in display \n”);
return ;
}
void print( )
{ printf(“Now in print \n”);
return;
}
Output
Now in display
Back to main
Now in print
Back to main
In the above example, the execution starts from the main function. Inside main, the function
display is called first. The activity of main is temporarily suspended and control is given to the
display function. When the display function completed its task, control will be transferred to
main function again.
Here main( ) is the ‘calling’ function and display ( ) and print() are the ‘called’ functions.
call
void main() void display( )
{ return return return {
display( ); printf(“ Now in display \n”);
printf(“Back to main \n “); call return ;
print( ); }
void print( )
printf(“Back to main \n “); return {
} printf(“Now in print \n”);
return;
}
4. Differentiate call
23
print( );
printf(“Back to main \n “);
}
5.
6.
7.
a. Call by value.
b. Call by reference.
a. Call by value
In this method, the value of the actual arguments in the calling function is copied into
corresponding formal arguments of the called function.
Therefore, the changes made to the formal arguments have no effect on the values of
actual arguments.
Example
#include<stdio.h>
void change (int x)
void main( )
{
int a=5; 5 a
printf(“ Before change %d \n “, a);
change (a);
printf(“After change %d \n”, a);
}
void change( int x)
{
x = x +5;
return; 5 x
}
Output
Before change : 5
After change : 5
Advantages
1) It protects the original data in the calling function, since the changes inside the called
function will not be reflected over it.
2) It allows even expressions as actual arguments rather than a single variable.
24
Disadvantage
2) It is a one- way transfer of information from the calling function to called function.
Information cannot be transferred back through arguments.
Storage class specifiers in C language tells to the compiler where to store a variable (Storage
area of variable), how to store the variable, Scope of variable, Default value of a variable (if it is
not initialized it), what is the initial value of the variable and life time of the variable.
25
Storage classes in mainly divided into four types,
auto
extern
static
register
The auto storage class is the default storage class for all local variables. The scope auto variable
is within the function. It is equivalent to local variable.
#include<stdio.h>
#include<conio.h>
void increment();
void main()
{
increment();
increment();
increment();
increment();
getch();
}
void increment()
{
auto int i = 0 ;
printf ( "%d", i ) ;
i++;
}
Output:
0000
26
The static storage class instructs the compiler to keep a local variable in existence during the life-
time of the program instead of creating and destroying it each time it comes into and goes out of
scope.
#include<stdio.h>
#include<conio.h>
void increment();
void main()
{
increment();
increment();
increment();
increment();
getch();
}
void increment()
{
static int i = 0 ;
printf ("%d", i ) ;
i++;
}
Output:
0123
The extern storage class is used to give a reference of a global variable that is visible to ALL the
program files. It is equivalent to global variable.
#include<stdio.h>
#include<conio.h>
int x = 20 ;
void main( )
{
extern int y;
printf("The value of x is %d \n",x);
printf("The value of y is %d",y);
getch();
}
int y=30;
Output:
The value of x is 20
27
The value of y is 30
Register variable
Register variables are also local variables, but stored in register memory. Whereas, auto variables
are stored in main CPU memory.
Advantages: The register variables are faster than remaining variables, because register variable
are stored in register memory not in main memory.
Example
void main()
{
register int a=10;
++a;
printf("\n value of a: %d",a);
printf("Enter a value:");
scanf("%d",&a);
--a;
printf("\n value of a: %d",a);
getch();
}
Output
Input data is 50.
Error, must take address of a memory location.
5. Write a C program to find and smallest and largest of two numbers using functions.
#include<stdio.h>
#include<conio.h>
int large(int x,int y)
{
int z1;
z1=(x>=y)?x:y;
28
return(z1); }
int small(int x1,int y1)
{
int z2;
z2=(x<=y)?x:y;
return(z2);
}
void main()
{
int a,b,c,d,e;
clrscr();
printf("Enter the values of a and b:");
scanf("%d %d",&a,&b);
d=large(a,b);
printf("The largest number is:%d",d);
e=small(a,b);
printf("The smallest number is:%d",e);
getch();
}
29
#include<stdio.h>
float mul(float x, float y); /* function declaration with argument names */
int sub(int , int); /*function declaration without argument names*/
void main ( )
{
float a = 1.5, b = 1.1;
int c = 5, d = 2;
printf(“%f \n”, mul(a,b));
printf(“%d \n”, sub(c,d));
}
int sub (int x, int y)
{
return( x- y );
}
float mul (float x, float y)
{
return(x * y);
}
8. Write a C program to find square and cube of a given number using functions.
#include<stdio.h>
#include<conio.h>
#include<math.h>
30
Cube of program:
Volume of a cube using function
#include <stdio.h>
double cube(double num);
int main()
{
int num;
double c;
printf("Enter any number: ");
scanf("%d", &num);
c = cube(num);
printf("Cube of %d is %.2f\n", num, c);
return 0;
}
double cube(double num)
{
return (num * num * num);
}
Output:
Enter any number: 5
32