Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
3 views

UNIT 5-Functions

The document covers various aspects of functions in C programming, including function prototypes, return types, arguments, and the differences between recursion and iteration. It also discusses storage classes, memory areas for different variable types, and the importance of modular programming through user-defined functions. Additionally, it provides examples of function definitions, declarations, and calls, along with explanations of local, global, and static variables.

Uploaded by

Divya Joshi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

UNIT 5-Functions

The document covers various aspects of functions in C programming, including function prototypes, return types, arguments, and the differences between recursion and iteration. It also discusses storage classes, memory areas for different variable types, and the importance of modular programming through user-defined functions. Additionally, it provides examples of function definitions, declarations, and calls, along with explanations of local, global, and static variables.

Uploaded by

Divya Joshi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

UNIT- V

Topics:

Functions – Function prototype, function return type, signature of a function, function


arguments, call by value, Function call stack and Activation Records, Recursion v/s Iteration,
passing arrays (single and multi-dimensional) to functions.

Storage classes- Automatic, Static, Register, External, Static and Dynamic linking
implementation, C program memory (show different areas of C program memory and where
different type of variables are stored), scope rules.
–7 Hrs

Functions:
Function is a sub-program or module that performs a specific task. Every C program must have at
least one function main() from where the program enters and starts executing.

A function is a collection of statements grouped together to do some specific task. In series of learning C
programming, we already used many functions unknowingly. Functions such as - printf(), scanf(), sqrt(), pow() or
the most important the main() function. Every C program has at least one function i.e. the main() function.

Function provides modularity to our program. Dividing a program in different modules makes it easy to
maintain, debug and understand the code.

Functions are of two kinds:


• Inbuilt functions
• User defined functions

Inbuilt functions:
Those functions which are already defined in the header files and are known to the compiler after
inclusion of the header files. These are used by the program to perform a specific task such as
input/output or some mathematical operation or string related operat ion etc.
Ex. printf(..),scanf(..), sqrt(..), pow(..), strcmp(..) etc.

User defined functions:


Those functions which are defined by the users and called inside the program to do a specific task
that programmer expects.
Ex. to add two integers, to perform some mathematical operation which can’t be done with an
inbuilt function, to process strings as per the program requirement etc.
Ex. Following is general form of the C program that calls any function Func1().

void Func1() /*user defined function*/


{
Executable statement(s);
}
void main()
{
Executable statement(s); Func1();
Executable statement(s);
}

ADVANTAGES OF USER DEFINED FUNCTIONS


1) User defined functions (UDF) helps to divide a large program into smaller modules which
makes the programmer easy to understand and maintain the large programs.
2) Redundant/Repeated code in a program can be avoided by calling an UDF.
3) Programmers can easily identify and debug program (remove errors) easily.
4) Reusability is the main achievement of C functions.

Function Definition
Function definition contains programming codes to perform specific task. The syntax is as shown
below:

Data_type function_name(data_type argument1, data_type argument2…....,data_type argumentN)


{
//body of function
//return value – if Data type (return type) of the function is other than void
}

A function definition in C programming consists of a function header and a function body. Here are
all the parts of a function −

Return Type − A function may return a value. The return_type is the data type of the value the
function returns. Some functions perform the desired operations without returning a value. In this
case, the return_type is the keyword void.

Function Name − This is the actual name of the function. The function name and the parameter list
together constitute the function signature.

Parameters − A parameter is like a placeholder. When a function is invoked, you pass a value to
the parameter. This value is referred to as actual parameter or argument. The parameter list refers to
the type, order, and number of the parameters of a function. Parameters are optional; that is, a
function may contain no parameters.

Function Body − The function body contains a collection of statements that define what the
function does.
Function Declarations
A function declaration tells the compiler about a function name and how to call the function. The actual body
of the function can be defined separately.

A function declaration has the following parts −

return_type function_name( parameter list );

Parameter names are not important in function declaration only their type is required, so the following is also
a valid declaration −

int max(int, int);

Calling a Function
While creating a C function, you give a definition of what the function has to do. To use a function, you will
have to call that function to perform the defined task.
Control of the program cannot be transferred to user-defined function unless it is called or invoked. The
syntax to invoke a function inside a program:

function_name(argument1, argument2 argumentN);


or
variable_name= function_name(argument1, argument2 argumentN);

where the data type of variable_name above is same as return type of function.

When a program calls a function, the program control is transferred to the called function. A called function
performs a defined task and when its return statement is executed or when its function-ending closing brace is
reached, it returns the program control back to the main program.
To call a function, you simply need to pass the required parameters along with the function name, and if the
function returns a value, then you can store the returned value.
Example 1.
#include <stdio.h>
void Display();
void main()
{
printf(“Main program.\n”);
Display();
}
void Display()
{
printf(“I am inside the display function.\n”);
}
Output:
Main program.
I am inside the display function.
In the above program the main program calls the function Display() with no
arguments while the function displays message “I am inside the display function.”
After the message “Main program.” is displayed by the main program.
Note before calling the function Display() compiler is inform ed about its prototype
before the main function by declaring it and ending with a semicolon.
Example 2.
#include <stdio.h>
int Sum(int x, int y); Function prototype
void main()
{ int x, y, result;

Actual arguments

x=77;
y=103;
result=Sum(x , y);
Function Call

printf(“The sum of %d and %d is %d\n”, x , y , result );


}

Return type

Formal arguments
int Sum(int x, int y)
{
int temp;
temp=x+y; Returns a value to the calling program and
the value should be same as the return type.

return(temp);
}

Output:
The sum of 77 and 103 is 180

In the above program the function Sum is called by the main program by passing two arguments x
and y of integer type. The function returns a value of integer type. Hence, its definition shows the
return type as int.
Classification of function:
//With argument without return type

#include <stdio.h>
void sum(int x, int y)//formal parameters
{
int s=x+y;
printf("sum=%d",s);
}
int main()
{
int a,b;
scanf("%d%d",&a,&b);
sum(a,b);//actual parameters
return 0;
}

//With argument with return type


#include <stdio.h>
int su(int x, int y)
{
int s=x+y;
return s;
}
int main()
{
int a,b;
scanf("%d%d",&a,&b);
int s=su(a,b);
printf("sum=%d",s);
return 0;
}

//Without argument with return type


#include <stdio.h>
int s()
{
int x,y;
scanf("%d%d",&x,&y);
int s=x+y;
return s;

}
int main()
{
int a,b;

int sum=s();
printf("sum=%d",sum);
return 0;
}

//Without argument without return type


#include <stdio.h>
void s()
{
int x,y;
scanf("%d%d",&x,&y);
int s=x+y;
printf("sum=%d",sum);

}
int main()
{
int a,b;

s();
return 0;
}

Function Arguments
While the arguments in the main program called as actual arguments are sent by value i.e their actual
value is passed. In the function definition the arguments passed are known as formal arguments and
their data type and order of the arguments should remai n same although their names while declaring
again the arguments in the function definition may be changed.
Function call types:
• Call by value
• Call by reference

Call by value: The function is called by sending arguments by their values


i.e the values passed by the calling program through the variables are copied to the formal
parameters.
Example 3.

#include <stdio.h>
int Max(int,int); /* Function Prototype */
void main()
{ int big;
printf(“Main program.\n”);

big=Max(10,15);
printf(“The biggest number is %d”,big);
}
Example 5.
/* Program passes two arguments of integer type to the function Sum. The function Sum adds the
two integers returns their sum after addition in the function to the main program.*/

#include <stdio.h> int


Sum(int x, int y);

void main()
{ int x,y,result;
x=77; y=103;
result=Sum(x , y);
printf(“The sum of %d and %d is %d\n”,x,y,result);
}
int Sum(int x, int y)
{
int temp;
temp=x+y;
return(temp);
}

int Max( int x, int y)


{
if( x > y )
return x;
else
return y;
}
Output:
The biggest number is 15
The values 10 and 15 in the main program are passed to the function Max are passed by values
and are called as actual arguments/parameters. These values are copied to the formal
parameters x and y. The function after processing returns x if x is greater t han y or returns y if y is
greater than x to the calling program.

Example 4.

#include <stdio.h>
void Display();
void main()
{
printf(“Main program.\n”);
Display();
}
void Display()
{
printf(“I am inside the display function.\n”);
}

RECURSION

• A function that calls itself is known as recursive function and this process is called
recursion.

Example-1: Program to find sum of first N natural numbers using recursion.

#include <stdio.h>
int add(int n)
{
if(n==0)
return 0;

else

}
return n+add(n-1); /*self call to function add() */

void main()
{
int n, sum;
printf("Enter a positive integer: ");
scanf("%d",&n);
sum=add(n);
printf("\nSum is %d", sum);

}
Output:
Enter a positive integer: 10
Sum is 5
In the above program:
Function add(n) is called with the argument n. Inside the function add, it sums the value of n and
then calls the same function add by decreasing the value of n. This process is repeated until the
value of n is greater than 0.
When the value of n reaches zero, the function starts returning, and in the process it starts adding
the number stored on the stack i.e from 1 to n.

• The following steps helps to understanding in a better way the working of the recursive
function:

add(5)
=5+ add(4)
=5+4+ add(3)
=5+4+3+ add(2)
=5+4+3+2+ add(1)
=5+4+3+2+1+ add(0)
=5+4+3+2+1+0
=5+4+3+2+1
=5+4+3+3
=5+4+6
=5+10
=15

• Any recursive function must have an exit condition. In the above example w hen, n is equal to
0, there is no more recursive call, the recursion ends and functions starts returning the values
on the stack by performing the desired mathematical operation.

Example-2: Program to find the factorial of a positive integer.

#include <stdio.h>
int fact(int n)
{

if(n==0)
return 1;
else
return n*fact(n-1); /*self call to function fact(..) */
}
void main()
{
int n, Factorial;
printf("Enter a positive integer: ");
scanf("%d",&n); Factorial=fact(n);
printf("\nFactorial of %d is %d", n,Factorial);
}
Output:
Enter a positive integer: 5
Factorial of 5 is 120

• The following steps helps to understanding in a better way the working of the recursive
function:

fact(5)
=5*fact(4)
=5*4*fact(3)
=5*4*3*fact(2)
=5*4*3*2*fact(1)
=5*4*3*2*1*fact(0)
=5*4*3*2*1*1
=5*4*3*2*1
=5*4*3*2
=5*4*6
=5*24
=120

• In the above example when, n is equal to 0, there is no recursive call and recursion ends. The
function starts returning the values on the stack by performing the desired mathematical
operation.

Example-3: Program to find the Sum of first N natural numbers using recursion.
#include <stdio.h> int
Sum(int n)
{
if(n==0)
return 0;
else
return ( n+Sum(n-1)); /*self call to function Sum(..) */
}
void main()
{
int n, FinalSum;
printf("Enter a positive integer: ");
scanf("%d",&n);
FinalSum =Sum(n);
printf("\nThe sum of first %d natural numbers is %d", n, FinalSum);
}
Output:
Enter a positive integer: 10
The sum of first 10 natural numbers is 55

TYPES OF VARIABLES
A variable is a name of the memory location. It is used to store data. Its value can be changed, and it can be
reused many times.

It is a way to represent memory location through symbol so that it can be easily identified.

There are many types of variables in c:

1. local variable
2. global variable
3. static variable

Local Variable

A variable that is declared inside the function or block is called a local variable.

It must be declared at the start of the block.

Example 1:
void function1(){
int x=10;//local variable
}

Example 2:
void swap ( int x, int y )
{
int temp ;
temp = x ;
x=y;
y = temp ;
int z = 0 ;
}
• You must have to initialize the local variable before it is used.
• Automatically allocated storage on function call
• De-Allocated on function exit
• Scope in block { }

Global Variable

A variable that is declared outside the function or block is called a global variable. Any function can change
the value of the global variable. It is available to all the functions.

It must be declared at the start of the block.

#include <stdio.h>
int i = 0; // Global Variable
void show_msg ()
{
for ( i = 0 ; i < 3 ; i++)
printf("India ");
} // India India India
int main ()
{
for ( i = 0 ; i < 3 ; i++)
show_msg ();
}
Static Variable

A variable that is declared with the static keyword is called static variable.

• It retains its value between multiple function calls.


• Storage allotted for entire duration of the program.

void static_var_concept (void)


{
static int i = 0 ;

printf(“%d\n”, i++);
} // 0 1 2 3 4

int main ()
{
for (int i = 0 ; i < 5 ; i++)
static_var_concept();
}
Storage classes
General Syntax:
storage_class var_data_type var_name;

1. auto: This is the default storage class for all the variables declared inside a function or a
block. Hence, the keyword auto is rarely used while writing programs in C language. Auto
variables can be only accessed within the block/function they have been declared and not
outside them (which defines their scope). Of course, these can be accessed within nested
blocks within the parent block/function in which the auto variable was declared. They are
assigned a garbage value by default whenever they are declared.
Void F1();
void main()
{
auto int x;
printf(“x=%d”,x); // Garbage Value
F1();
}
voif F1()
{
printf(“x=%d”,x); //x is not accessible in the function F()
}
2. extern: Extern storage class tells us that the variable is defined elsewhere and not within the
same block where it is used. Basically, the value is assigned to it in a different block and this
can be overwritten/changed in a different block as well. So an extern variable is nothing but a
global variable initialized with a desired value where it is declared, in order to be used
elsewhere. It can be accessed within any function/block. Also, a normal global variable can be
made extern as well by placing the ‘extern’ keyword before its declaration/definition in any
function/block. This basically signifies that we are not initializing a new variable but instead
we are using/accessing the global variable only. The main purpose of using extern variables is
that they can be accessed between two different files which are part of a large program.

P1.c:
extern int var=10; void
main()
{ int x;
printf(“x=%d”,x); // Garbage Value
F1();
}
P2.c:
extern int var;
void main()
{ int x=100;
x=x+var; //var is accessible in the program P2.c although it is
declared
// in P1.c
printf(“x=%d”,x);
F1();}
3. static: This storage class is used to declare static variables which are popularly used while
writing programs in C language. Static variables have a property of preserving their value
even after they are out of their scope! Hence, static variables preserve the last value that was
assigned in their scope. Hence, they are initialized only once and exist till the termination of the
program. Thus, no new memory is allocated because they are not re-declared. Their scope is
local to the function to which they were defined. Global static variables can be accessed
anywhere in the program. By default, they are assigned the value 0 by the compiler.
#include <stdio.h> void
F1(int x)
{
static int var=10; printf(“\nx=%d,
var=%d\n”,x,var); var++;
x++;
}

void main()
{ int x=100,i;
for(i=0;i<3;i++)
F1(x);
}
Output:
x=100, var=10
x=100, var=11
x=100, var=12

4. register: This storage class declares register variables which have the same functionality as
that of the auto variables. The only difference is that the compiler tries to store these
variables in the register of the microprocessor if a free register is available. This makes the
use of register variables to be much faster than that of the variables stored in the memory
during the runtime of the program. If a free register is not available, these are then stored in
the memory only. Usually few variables which are to be accessed very frequently in a
program are declared with the register keyword which improves the execution time of the
program. An important and interesting point to be noted here is that we cannot obtain their
address because they are not stored in the memory.

Ex. Register variable is declared similar to an auto variable except that it is declared with the
keyword register before the data type. register int rvar=26;
Storage Storage Initial Value Scope Life
Specifier
Area

Auto Stack Garbage Within block End of block

extern Data Segment Zero Global multiple End of program


files

static Data Segment Zero Within block End of program

Register CPU Garbage Within block End of block


Register

Activation record
Activation record is used to manage the information needed by a single execution of a procedure
(function). An activation record is pushed into the stack when a procedure (function) is called and
it is popped when the control returns to the caller function.

Activation record is another name for Stack Frame. It's the data structure that composes a call
stack. It is generally composed of:

Locals to the callee


Return address to the caller
Parameters of the callee
ACTIVATION RECORDS
Control stack or runtime stack is used to keep track of the live procedure (function(s)) activations
i.e the procedures whose execution have not been completed. A procedure name ( function) is
pushed on to the stack when it is called (activation begins) and it is popped when it returns
(activation ends). Information needed by a single execution of a procedure is managed using an
activation record or frame. When a procedure is called, an activation record is pushed into the
stack and as soon as the control returns to the caller function the activation record is popped.

Activation record comprises of the following fields:

• Local variables: holds the data that is local to the execution of the procedure.
• Temporary values: stores the values that arise in the evaluation of an expression.
• Saved machine registers: holds the information about status of machine just before the
function call.
• Access link (optional): refers to non-local data held in other activation records.
• Control link (optional): points to activation record of caller.
• Return value: used by the called procedure to return a value to calling procedure
• Actual parameters
Memory map of C program
A typical memory representation of C program consists of following sections.
1. Text segment
2. Initialized data segment
3. Uninitialized data segment
4. Stack
5. Heap

A Typical memory layout of a running program (process )


1. Text Segment:
A text segment, also known as a code segment or simply as text, is one of the
sections of a program in an object file or in memory, which contains executable
instructions. As a memory region, a text segment may be placed below the heap
or stack in order to prevent heaps and stack overflows from overwriting it.
Usually, the text segment is sharable so that only a single copy needs to be in
memory for frequently executed programs, such as text editors, the C compiler,
the shells, and so on. Also, the text segment is often read-only, to prevent a
program from accidentally modifying its instructions.

2. Initialized Data Segment:


Initialized data segment, usually called the Data Segment. A data segment is a
portion of virtual address space of a program, which contains the global
variables and static variables that are initialized by the programmer.
Note that, data segment is not read-only, since the values of the variables can be
altered at run time. This segment can be further classified into initialized read -
only area and initialized read-write area.
For instance the global string defined by char s[] = “hello world” in C and a C
statement like int var=1 outside the main (i.e. global) would be stored in
initialized read-write area. And a global C statement like const char* string =
“hello world” makes the string literal “hello world” to be stored in initialized
read-only area and the character pointer variable string in initialized read -write
area.

Ex: static int i = 10 will be stored in data segment and global int i = 10 will also
be stored in data segment
3. Uninitialized Data Segment:

Uninitialized data segment, often called the “bss” segment, named after an
ancient assembler operator that stood for “block started by symbol.” Data in
this segment is initialized by the kernel to arithmetic 0 before the program starts
executing.
For instance a variable declared static int i; would be contained
in the BSS segment. For instance a global variable declared int j;
would be contained in the BSS segment.
4. Stack:
The stack area grows in the opposite direction; when the stack pointer meets the
heap pointer, implies free memory is exhausted. (With modern large address
spaces and virtual memory techniques they may be placed almost anywhere, but
they still typically grow opposite directions.) On the standard PC x86
computer architecture, it grows toward address zero; on some other
architectures it grows in the opposite direction. The set of values pushed for one
function call is termed a “stack frame”;
Stack, where automatic variables are stored, along with information that is saved
each time a function is called. Each time a function is called, the address of
where to return to and certain information about the caller’s environment, such
as some of the machine registers, are saved on the stack. The newly called
function then allocates room on the stack for its automatic and temporary
variables. The best example is a recursive function in C. Each time a recursive
function calls itself, a new stack frame is used, so one set of variables doesn’t
interfere with the variables from another instance of the function.
5. Heap:

Heap is the segment where dynamic memory allocation usually takes place. The
heap area begins at the end of the BSS segment and grows to larger addresses
from there. The Heap area is managed by malloc / calloc, realloc and free
functions. The Heap area is shared by all shared libraries and dynamically
loaded modules in a process.

Static and Dynamic Linking of Libraries:

Let’s understand the life cycle of a typical program right from writing source code
to its execution.
A program is first written using any editor of programmer's choice in form of a
text file, then it has to be compiled in order to translate the text file into object
code that a machine can understand and execute.
Program life cycle (write -> compile -> link -> load -> execute).
The program we write might make use of other programs, or libraries of
programs. These other programs or libraries must be assembled together with the
program written in order to execute it and linking (part of the compilation) is the
process of bringing these external programs together for its successful execution.
Static and dynamic linking are two processes of collecting and combining
multiple object files in order to create a single executable file.
Linking can be performed at both compile time, when the source code is
translated into machine code; and load time, when the program is loaded into
memory by the loader, and even at run time, by application programs. This is
performed by programs called linkers. Linkers are also called link editors.
Linking is performed as the last step in compiling a program.
After linking, for execution the combined program must be moved into memory. In
doing so, the
addresses must be assigned to the data and instructions for its final execution.
The figure below illustrates the linking process in a statically and dynamically
linked libraries and the final size of the file on compiling and executing using both
the methods.
Difference between Static Linking and Dynamic Linking.

Static Linking Dynamic Linking

Static linking is the process of In dynamic linking the names of the external
copying all library modules used libraries (shared libraries) are placed in the
in the program into the final final executable file while the actual linking
executable image. takes place at run time when both executable
file and libraries are placed in the memory.

Static linking is performed by Dynamic linking is performed at run time by the


programs called linkers as the last operating system.
step in compiling a program.
Linkers are also called link
editors.

Statically linked files are In dynamic linking only one copy of shared
significantly larger in size library is kept in memory. This drastically
because external programs are reduces the size of executable programs.
also combined into the executable Hence, saves memory.
files.
In static linking, if any of the In dynamic linking this is not the case and
external programs has changed individual shared modules can be updated and
then the program needs to be recompiled. There is no need to recompile and
recompiled and re-linked again relink the program.
otherwise the changes are not
reflected in existing executable
file.

Statically linked program takes In dynamic linking load time might be reduced
constant load time every time it is if the shared library code is already present in
loaded into the memory for memory.
execution.

Programs that use statically- Programs that use shared libraries are usually
linked libraries are usually faster slower than those that use statically-linked
than those that use shared libraries.
libraries.

In statically-linked programs, all Dynamically linked programs are dependent on


code is contained in a single a compatible library. If a library is changed (for
executable module. Therefore, ex., a new compiler release may change a
they never run into compatibility library), then applications might have to be
issues. reworked to be made compatible with the new
version of the library. If a library is removed
from the system, programs using that library
will no longer work.
Flowcharts for Functions

Q1. Draw a flowchart to calculate factorial of a given number using function fact();
Method 1. With no return type with no arguments

Q2. Draw a flowchart to calculate factorial of a given number using function fact();

Method 2. With no return type with arguments

return
Q3. Draw a flowchart to calculate factorial of a given number using function fact();
Method 3. With return type with no arguments

return f

Q4. Draw a flowchart to calculate factorial of a given number using function fact();
Method 4. With return type with arguments

return f
Q5. Draw a flowchart to calculate factorial of a given number using recursive function fact();

return
1

You might also like