Functions
Functions
A function is a self contained program segment that carries out some specific, well defined task.
Every C program consists of one or more functions. Every C program must have main function.
Execution of program will always begin by carrying out the instructions in main.
Generally, a function will process information that is passed to it from the calling portion of
the function, and return a single value. Information is passed to the function via special
identifiers called arguments.
Function prototypes/Function declaration
Function declaration tells what function looks like. It represents signature (return type, name,
type and number of arguments) of a function. Function prototypes are usually written at the
beginning of a program. The general form of function prototype is
datatype functionname(datatype 1 arg 1,datatype 2 arg 2,……………..,datatype n arg n);
OR
datatype functionname(datatype 1, datatype 2,……………..,datatype n);
Here datatype represents the type of data that is returned by the function, functionname
represents the name of the function, and datatype 1, datatype 2,.....,datatype n represents the data
types of the arguments arg 1, arg 2,…….,arg n.
For example,
int sum(int x, int y); OR int sum(int, int);
Function definition
What a function does is called function definition. The first line of a function definition contains
the type of the value returned by the function, followed by the function name, and (optionally) a
set of arguments, separated by commas and enclosed in parentheses. An empty pair of
parentheses must follow the function name if the function definition does not include any
arguments. Its general form is
datatype functionname(datatype 1 arg 1,datatype 2 arg 2,……………..,datatype n arg n) {
function body
}
These arguments are called formal arguments, because they represent the names of the data
items that are transferred into the function from the calling portion of the program. They are also
known as parameters or formal parameters. The corresponding arguments in the function call
are called actual arguments, since they define the data items that are actually transferred.
The remainder of the function definition is a compound statement that defines the action to
be taken by the function. This compound statement is sometimes referred to as the body of the
function. It can include one or more return statements, in order to return a value to the calling
portion of the program.
Calling a function/accessing a function
A function can be called (i.e. accessed) by specifying its name, a list of arguments enclosed in
parentheses separated by commas, and followed by semicolon.
The arguments appearing in the function call are referred to as actual arguments, in contrast
to the formal arguments that appear in the first line of the function definition.
1
Putting all together
/*program to find sum of two numbers using function*/
#include<stdio.h>
#include<conio.h>
void main()
{
int x,y,sum;
int add(int x, int y); // function declaration
clrscr();
printf("Enter two numbers:\n");
scanf("%d %d",&x,&y);
sum = add(x,y); // function call (x and y are actual arguments)
printf("Sum = %d",sum);
getch();
}
int add(int a, int b) //Function definition (a and b are formal arguments)
{
int z;
z = a + b;
return z;
}
Information is returned from the function to the calling portion of the program via the return
statement. The return statement also causes the program logic to return to the point from which
the function was accessed. In general terms, the return statement is written as
return expression;
Here, the value of the expression is returned to the calling portion of the program. The
expression is optional. If the expression is omitted, the return statement simply causes control to
revert back to the calling portion of the program, without any transfer of information.
Advantages of function
Writing function avoids rewriting the same code over and over. We can call the same
function many times.
Using function it becomes easier to write programs and keep track of what they are
doing.
Function helps to divide a large program into number of parts, which makes it easier to
understand, modify, and debug.
/*program that shows the call of same function more than one time*/
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c,d,l;
int find_larger(int , int );
clrscr();
2
printf(“\nEnter two numbers “);
scanf(“%d %d”,&a,&b);
l = find_larger(a,b);
printf(“\nlarger = %d”,l);
printf(“\nEnter two numbers “);
scanf(“%d %d”,&c,&d);
l = find_larger(c,d);
printf(“\nlarger = %d”,l);
getch();
}
int find_larger(int x, int y)
{
if(x > y)
return x;
else
return y;
}
3
}
void display()
{
printf(“Citizen College”);
}
Functions with arguments and no return type: calling function passes values to the called
function. Called function does not return value to the calling function. It is a one-way transfer of
data from calling to called function.
void main()
{
int x,y,sum;
void add(int x, int y);
clrscr();
printf("Enter two numbers:\n");
scanf("%d %d",&x,&y);
add(x,y);
getch();
}
void add(int a, int b)
{
int z;
z = a + b;
printf(“Sum=%d”,z);
}
Functions with arguments and return value: Passes values from actual arguments of calling
function to the formal arguments of called function and the computed value by the called
function is returned back to the calling function.
void main()
{
int x,y;
int add(int x, int y);
clrscr();
printf("Enter two numbers:\n");
scanf("%d %d",&x,&y);
sum = add(x,y);
printf("Sum = %d",sum);
getch();
}
int add(int a, int b)
{
int z;
z = a + b;
return z;
}
4
Functions with no arguments but return value: These types of functions do not pass values
from calling function to called function but the computed value of the called function is returned
back to the calling function.
void main()
{
int sum;
int add();
clrscr();
sum=add();
printf("Sum=%d",sum);
getch();
}
int add()
{
int x,y,z;
printf("Enter two numbers:\n");
scanf("%d %d",&x,&y);
z = x + y;
return z;
}
Recursion/Recursive Function
Recursion is a process by which a function calls itself repeatedly, until some specified condition
has been satisfied. The process is used for repetitive computations in which each action is stated
in terms of a previous result.
In order to solve a problem recursively, two conditions must be satisfied. First, the
problem must be written in a recursive form, and second, the problem statement must include a
stopping condition.
Example:
/*calculation of the factorial of an integer number using recursive function*/
#include<stdio.h>
#include<conio.h>
void main()
{
int n;
long int facto;
long int factorial(int n);
printf("Enter value of n:");
scanf("%d",&n);
facto=factorial(n);
printf("%d! = %ld",n,facto);
getch();
}
long int factorial(int n)
{
5
if(n == 0)
return 1;
else
return n * factorial(n-1);
}
Example:
/*calculation of the factorial of an integer number without using recursive function*/
#include<stdio.h>
#include<conio.h>
void main()
{
int n;
long int facto;
long int factorial(int n);
printf("Enter value of n:");
scanf("%d",&n);
facto=factorial(n);
printf("%d! = %ld",n,facto);
getch();
}
long int factorial(int n)
{
long int facto=1;
int i;
if(n==0)
return 1;
else {
for(i=1;i<=n;i++)
facto=facto*i;
return facto;
}
}
Some other examples using recursive function:
/* Program to generate Fibonacci series up to n terms using recursive function*/
#include<stdio.h>
#include<conio.h>
void main()
{
int n,i;
int fibo(int);
printf("Enter n:");
scanf("%d",&n);
printf("Fibonacci numbers up to %d terms:\n",n);
for(i=1;i<=n;i++)
printf("%d\n",fibo(i));
6
getch();
}
int fibo(int k)
{
if(k == 1 || k == 2)
return 1;
else
return fibo(k-1)+fibo(k-2);
}
/* Program to find sum of first n natural numbers using recursion*/
#include<stdio.h>
#include<conio.h>
void main()
{
int n;
int sum_natural(int );
printf("n = ");
scanf("%d",&n);
printf("Sum of first %d natural numbers = %d",n,sum_natural(n));
getch();
}
int sum_natural(int n)
{
if(n == 1)
return 1;
else
return n + sum_natural(n-1);
}
7
Storage Classes
Every variable and function in C has two attributes: type and storage class. The four storage
classes are automatic, external, register, and static, with corresponding keywords auto, extern,
register, and static. The storage class of a variable determines which parts of the program can
access it (scope or visibility) and how long it stays existence (lifetime or duration).
The storage class auto
Variables defined within a function body are called automatic variables. These variables have
implicitly automatic storage class. The keyword auto can be used to explicitly specify the
storage class. For example, auto int a,b,c; Because the storage class is automatic by default, the
keyword auto is seldom used. Automatic variables are local or private to a function in which
they are defined. So, these are also called local variables.
Lifetime: An automatic variable is not created until the function in which it is defined is
called. When the function exits and control is returned to the calling program, the variables
are destroyed and their values are lost. Hence, the lifetime of an automatic variable coincides
with the time when the function in which it is defined is executing. The idea behind limiting
the lifetime of variables is to save memory space.
Visibility: Automatic variables are only visible, meaning they can only be accessed, within
the function in which they are defined. Limiting the visibility of variables helps to organize
and modularize the program. You can be confident that the variables in one function are safe
from accidental alteration by other functions, because the other functions can’t see them.
Initialization: When an automatic variable is created, the compiler does not try to initialize
it. Thus it will start off with an arbitrary value, which may be 0 but probably will be
something else. If you want it initialized, you must do it explicitly, as in int sum=0;
The storage class extern
When a variable is declared outside a function, it is called external variable. These variables have
implicitly external storage class. The keyword extern can be used to explicitly specify the
storage class. For example, extern int a,b,c; Because the storage class is external by default, the
keyword extern is seldom used. External variables are also called global variables, since they
are known by all functions declared after it in a program.
Lifetime: These variables exist for the life of the program. That is, memory space is set aside
for them when the program begins, and continues in existence until the program ends.
Visibility: These variables are visible in the file in which they are defined, starting at the
point where they are defined.
Initialization: If an external variable is not initialized explicitly, it is initialized
automatically to 0 when it is created.
Programs need not essentially be limited into a single file, multi-file programs is also possible,
all the files are linked later to form executable object code. To share a single variable in multiple
programs it should be declared as external variables that are shared by two or more files are
obviously global variables.
The storage class static
There are two types of static variables: static automatic and static external. Static variables are
defined using static keyword, such as, static int a; Static automatic variables are defined inside a
function. Static automatic variables are used when it’s necessary for a function to remember a
8
value when it is not being executed; that is, between calls to the function. It has the visibility of
local variable but the lifetime of an external variable.
Lifetime: These variables exist for the life of the program. That is, memory space is set aside
for them when the program begins, and continues in existence until the program ends.
Visibility: Static variables are only visible within the function in which they are defined.
Initialization: If an external variable is not initialized explicitly, it is initialized
automatically to 0 when it is created.
Static external variables are only meaningful in multi-file programs. These are scope restricted
external variables. The scope is the remainder of the source file in which they are declared. Thus,
they are unavailable to functions defined earlier in the file or to functions defined in other files.
The storage class register
This storage class tells the compiler that the associated variables should be stored in high-speed
memory registers. Because resource limitations and semantic constraints sometimes make this
impossible, this storage class defaults to automatic whenever the compiler cannot allocate an
appropriate physical register. It can be declared only inside a function, like, register int i;
Basically, the use of register is an attempt to improve execution speed. When speed is concern,
the programmer may choose a few variables that are most frequently accessed and declare them
to be of storage class register. Common candidates for such treatment include loop variables and
function parameters.
The Preprocessor
Lines that begin with # are called preprocessor directives. These lines communicate with the
preprocessor. Preprocessor is a part of the compiler that deals with preprocessor directives
before real compilation process begin. Preprocessor directives are written at the beginning of the
program. They must not end with a semicolon. Only one preprocessor directive can appear in
one line. There are two types of preprocessor directives: #include and #define.
#include directive
It is also called file inclusion directive. It tells the compiler to include another file into your
source file. In effect, the #include directive is replaced by the contents of the file instead. We can
write this directive as follows:
#include<filename>
OR
#include filename
For example, #include<stdio.h>
In most cases, #include directive is used to include header files that contains various
declarations describing any library function we use in our programs. For example, for sqrt( )
function, the header file is math.h and we use it as follows:
#include<math.h>
#define directive
It is called macro definition. Macro is used to generate inline code. Hence, macro name that
appears in a program is replaced by the string that defines the macro. Their use can reduce the
program execution time. This directive occurs in two forms: macros without arguments and
macros with arguments. These two forms have following general forms respectively.
9
#define identifier text
#define identifier(identifier,…, identifier) text
For example,
#define PI 3.1415 //macro without argument
#define area(l,b) l*b //macro with arguments l and b
Macros with arguments are frequently used to replace function call. When macro name is found,
it is replaced by the string that defines the macro. Since, macro name is replaced by its definition,
it takes less time to execute your program.
Example: Program to calculate area and circumference of circle
#include<stdio.h>
#include<conio.h>
#include<math.h>
#define PI 3.1415
#define area(r) PI*pow(r,2)
#define circum(r) 2*PI*r
void main(void) {
float r,a,c;
clrscr();
printf("Enter radius:");
scanf("%f",&r);
a=area(r);
c=circum(r);
printf("Area=%f\n",a);
printf("Circumference=%f",c);
getch();
}
10