PCE Unit – 4: Programming With C 251FY3-06
User-Defined Functions
A function is a self-contained block of statements that performs a specific task. If a
program is divided into functional parts, then each part may be independently coded and
later combined into a single unit. These independently coded programs are called
subprograms that are much easier to understand, debug, and test. In C, such
subprograms are referred to as ‘functions’. This ‘division’ approach clearly results in a
number of advantages.
It improve the readability of code.
The length of a source program can be reduced by using functions.
It improves the reusability of the code, same function can be used in any program
rather than writing the same code from scratch.
Debugging of the code would be easier, as errors are easy to be traced.
A function may be used by many other programs.
It facilitates top-down modular programming.
There are two types of function in C language:
Function
Library Function User-Defined Function
Library Functions: The standard library functions are built-in functions in C programming.
Library functions are the inbuilt function in C that are grouped and placed at a common
place called the library. Such functions are used to perform some specific operations. For
example, printf() is a library function used to print on the console. The library functions are
created by the designers of compilers. All C standard library functions are defined inside
the different header files saved with the extension .h. We need to include these header
files in our program to make use of the library functions defined in such header files.
User-Defined Functions: A User-defined functions on the other hand, are those functions
which are defined by the user at the time of writing program. These functions are made for
code reusability and for saving time and space.
Modular Programming
Modular programming is a strategy applied to the design and development of software
systems. It is defined as organizing a large program into small, independent program
segments called modules (functions) that are separately named and individually callable
program units. These modules are carefully integrated to become a software system that
satisfies the system requirements. It is basically a “divide-and-conquer” approach to
problem solving. In C, each module refers to a function that is responsible for a single
task. Some characteristics of modular programming are as follows:
Each module should do only one thing.
Communication between modules is allowed only by a calling module.
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 1
PCE Unit – 4: Programming With C 251FY3-06
A module can be called by one and only one higher module.
No communication can take place directly between modules that do not have
calling-called relationship.
All modules are designed as single-entry, single-exit systems using control
structures.
Elements of User-Defined Functions
In order to make use of a user-defined function, we need to establish three elements that
are related to functions.
1. Function declaration: A function must be declared in a program to tell the
compiler about the function name, function arguments, and return type.
2. Function definition: It contains the actual statements which are to be executed. It
is the most important aspect to which the control comes when the function is called.
3. Function call: Function can be called from anywhere in the program. The
parameter list must not differ in function calling and function declaration.
The function definition is an independent program module that is specially written to
implement the requirements of the function. In order to use this function we need to invoke
it at a required place in the program. This is known as the function call. The program that
calls the function is referred to as the calling program or calling function. The calling
program should declare any function that is to be used later in the program. This is known
as the function declaration or function prototype. Syntax of a function is:
Return_type function_name ( argument list )
{
//block of statements
}
Definition of Functions
A function definition, also known as function implementation shall include the following
elements:
Function name
Return type
List of parameters
Local variable declarations
Function statements
Return statement
List of parameters contains variables name along with their data types. These arguments
are kind of inputs for the function.
Return type can be of any data type such as char, int, short, float, double etc. A C function
may or may not return a value from the function. If you don’t have to return any value from
the function, use void for the return type.
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 2
PCE Unit – 4: Programming With C 251FY3-06
Category of Functions
A function, depending on whether arguments are present or not and whether a value is
returned or not, may belong to one of the following categories:
1. Functions with NO arguments and NO return values.
2. Functions WITH arguments and NO return values.
3. Functions NO arguments and WITH return values.
4. Functions WITH arguments and WITH return values.
5. Functions that return multiple values.
Parameters (Arguments) Passing
The parameters specified in the function call are known as actual parameters and those
specified in the function declaration are known as formal parameters. The scope of
formal parameters is limited to its function only.
Parameter passing is a mechanism for communication of data and information between
the calling function (caller) and the called function (callee). It can be achieved either by
passing the value or address of the variable. C supports the following two types of
parameter passing schemes:
1. Pass By Value or Call by Value
2. Pass By Address/Pointer/Reference or Call by Reference
Pass By Value / Call by Value
The value of the actual parameters is copied into the formal parameters.
We cannot modify the value of the actual parameter by the formal parameter.
In call by value, different memory is allocated for actual and formal parameters
since the value of the actual parameter is copied into the formal parameter.
The actual parameter is the argument which is used in the function call whereas
formal parameter is the argument which is used in the function definition.
Pass-by-value mechanism does not change the contents of the argument variable in the
calling function, even if they are changed in the called function.
Example: Swap integer values by pass by value.
void swap (int x, int y) int main()
{ {
int t; int a, b;
t = x; printf(“Enter two numbers: ”);
x = y; scanf((%d%d”,&a, &b);
y = t; swap ( a, b );
printf(“After swaping in swap fun”); printf(“\nAfter calling swap function”);
printf(“\nx = %d y = %d”, x, y); printf(“\n a = %d b = %d”, a, b);
} }
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 3
PCE Programming for Problem Solving 1FY3-06
Pass By Address / Call by reference
In call by reference, the address of the variable is passed into the function call as
the actual parameter.
The value of the actual parameters can be modified by changing the formal
parameters since the address of the actual parameters is passed.
In call by reference, the memory allocation is similar for both formal parameters and
actual parameters. All the operations in the function are performed on the value
stored at the address of the actual parameters, and the modified value gets stored at
the same address.
In Pass-by-Address mechanism, instead of passing the value, the address of the variable is
passed in the function. The de-referencing operator ( * ) is used to access the variable in
the called function.
Example: Swap integer values by pass by address.
void swap (int * x, int * y)
{
int t;
t = * x;
x = * y;
y = * t;
printf(“After swaping in swap fun”);
printf(“\nx = %d y = %d”, * x, * y);
}
int main()
{
int a, b;
printf(“Enter two numbers: ”);
scanf((%d%d”,&a, &b);
swap ( &a, &b );
printf(“\nAfter calling swap function”);
printf(“\n a = %d b = %d”, a, b);
}
Passing One-Dimensional Array to Function
Like the values of simple variables, it is also possible to pass the values of an array to a
function. To pass a one-dimensional array to a called function it is sufficient to list the name
of the array, without any subscripts, and the size of the array as arguments. For example,
the call
maximum ( arr, n );
will pass the whole array arr to the called function. The maximum function header might
look like:
int maximum ( int arr[ ], int size );
The function maximum is defined to take two arguments, the array name and the size of
the array to specify the number of elements in the array.
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 4
PCE Programming for Problem Solving 1FY3-06
Recursion
Any function which calls itself is called recursive function, and such function calls are called
recursive calls. When a called function in turn calls another function a process of ‘chaining’
occurs. Recursion is a special case of this process, where a function calls itself. For
example:
main()
{
printf( “main() is called recursively” )
main();
}
Recursive functions can be effectively used to solve problems where solution is expressed
in terms of successively applying the same solution to subsets of the problem. For example,
following the C function to generate the nth term of Fibonacci series:
int fibo( int n )
{
if ( n <=0 )
{ printf (“Series cannot be generated”);
return -111; //error state
}
else if ( n == 1 || n == 2)
return 1;
else
return ( fibo(n – 1 ) + fibo( n – 2 ) );
}
Example: Program to calculate the factorial of a number using recursion.
#include <stdio.h>
int fact(int);
int main()
{
int num, factorial;
printf(“\nEnter a number: ”);
scanf(“%d”,&num);
factorial = fact(num);
printf(“\nFactorial of %d = %d”, num, factorial);
return 0;
}
int fact(int n)
{
if (n == 0 || n == 1)
return 1;
else
return n * fact(n – 1);
}
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 5
PCE Programming for Problem Solving 1FY3-06
Storage Classes
(The Scope, Visibility, and Lifetime of Variables)
In C all variables have a data type and also have a storage class. A variable’s storage class
tells us the following things about the variable:
Where would the variable be stored?
What would be the default initial value of the variable?
What would be the scope of the variable, i.e., to which statements the value of the
variable would be available?
What would be the life of the variable, i.e., how long would the variable exist.
There are four storage classes in C:
1. Automatic storage class
2. Register storage class
3. Static storage class
4. External storage class
Automatic Storage Class
The visibility of the automatic variables is limited to the block in which they are
defined.
The scope of the automatic variables is limited to the block in which they are
defined.
The automatic variables are initialized to garbage by default.
The memory assigned to automatic variables gets freed upon exiting from the
block.
The keyword used for defining automatic variables is auto.
Every local variable is automatic in C by default.
Register Storage Class
The variables defined as the register is allocated the memory into the CPU registers
depending upon the size of the memory remaining in the CPU.
We cannot dereference the register variables, i.e., we cannot use & operator for the
register variable.
The access time of the register variables is faster than the automaticvariables.
The initial default value of the register local variables is 0.
The register keyword is used for the variable which should be stored in the CPU
register. However, it is compiler’s choice whether or not; the variables can be stored
in the register.
Static Storage Class
The variables defined as static specifier can hold their value between the multiple
function calls.
Static local variables are visible only to the function or the block in which they are
defined.
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 6
PCE Programming for Problem Solving 1FY3-06
Default initial value of the static integral variable is 0 otherwise null.
The visibility of the static global variable is limited to the file in which it has
declared.
The keyword used to define static variable is static.
Example:
#include <stdio.h>
void print(void);
int main()
{
int i;
for( i = 1; i <= 5; i++)
print();
return 0;
}
void print(void) {
static int n = 1;
printf(“%4d”,n);
n++;
}
External Storage Class
The external storage class is used to tell the compiler that the variable defined as
extern is declared with an external linkage elsewhere in the program.
The variables declared as extern are not allocated any memory. It is only declaration
and intended to specify that the variable is declared elsewhere in the program.
The default initial value of external integral type is 0 otherwise null.
We can only initialize the extern variable globally, i.e., we can not initialize the
external variable within any block or method.
Storage Default
Storage Scope Life
Class Value
Local to the block in Till the control remains
auto Memory Garbage which variable is within the block in which the
defined. variable is defined.
Local to the block in Till the control remains
register CPU Register Garbage which variable is within the block in which the
defined. variable is defined.
Local to the block in Value of the variable
static Memory Zero which variable is persists between different
defined. function calls.
As long as the program’s
extern Memory Zero Global execution doesn’t come to
an end.
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 7
PCE Programming for Problem Solving 1FY3-06
Pointers
A pointer is a variable which stores the address of another variable. A pointer is a derived
data type in C. It is built from one of the fundamental data types available in C. Pointers
contain memory addresses as their values. The purpose of pointer is to save memory
space and achieve faster execution time.
Pointers are used frequently in C, as they offer a number of benefits to the programmers.
They include:
Pointers can be used to return multiple values from a function via function
arguments.
Pointers permit references to functions and thereby facilitating passing of functions
as arguments to other functions.
The use of pointer arrays to character strings results in saving of data storage space
in memory.
Pointers allow C to support dynamic memory management.
Pointers provide an efficient tool for manipulating dynamic data structures such as
structures, linked lists, queues, stacks and trees.
Declaring Pointer Variables
Since pointer variables contain addresses that belong to a separate data type, they must
be declared as pointer before we use them. The declaration of a pointer variable takes the
following form:
Data_type * p_name;
This tells the compiler three things about the variable p_name.
1. The asterisk (*) tells that the variable p_name is a pointer variable.
2. p_name needs a memory location.
3. p_name points to a variable of type Data_type.
For example:
int *ptr; //pointer to an integer
float *p; //pointer to float
declares the variable ptr as a pointer variable that points to an integer data type and p as a
pointer variable that points to a float data type.
The data type of pointer and the variable must match, an int pointer can hold the address
of int variable, and similarly a pointer declared with float data type can hold the address of
a float variable.
Initialization and Accessing
Once a pointer has been assigned the address of a variable, we can access the value of
the variable using the operator * (asterisk), usually known as the indirection operator.
Another name for the indirection operator is the dereferencing operator.
int num, *ptr, val;
num = 25;
ptr = #
val = *ptr;
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 8
PCE Programming for Problem Solving 1FY3-06
Example:
#include <stdio.h>
void main()
{
int n = 10;
int *ptr;
ptr = &n;
printf(“Address of n = %p”, &n); //using address of operator of variable n
printf(“\nAddress of n = %p”, ptr); //using pointer
printf(“\nValue of n = %d”, *ptr); //using dereference operator
}
Pointer Arithmetic
There are only a few operations that are allowed to perform on pointers in C language.
The operations are slightly different from the ones that we generally use for mathematical
calculations. The operations are:
Increment/Decrement of a pointer (++ or --)
Addition of integer to a pointer ( + or +=)
Subtraction of integer to a pointer (- or -=)
Subtracting two pointers of the same type
Comparison of two pointers. (p == ptr or p == NULL)
Pointer arithmetic is meaningless unless performed on an array.
Void (Generic) Pointer
Void pointer (void *) is a pointer that points to some data location in storage, which doesn’t
have any specific type. Void refers to the type. Basically the type of data that is points to is
can be any. If we assign address of char data type to void pointer it will become char
pointer, if int data type then int pointer and so on. Any pointer type is convertible to a void
pointer hence it can point to any value.
Example:
#include <stdio.h>
void main()
{
int inum = 10;
float fnum = 2.2;
void* ptr; //void/generic pointer
ptr = &inum;
// (int*)ptr – does type casting of void
//*((int*)ptr) – dereferences the typecasted void pointer variable
printf("\nValue of inum = %d",*((int*)ptr));
ptr = &fnum; //void pointer is now float
printf("\nValue of fnum = %.2f",*((float*)ptr));
}
Output:
Value of inum = 10
Value of fnum = 2.20
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 9
PCE Programming for Problem Solving 1FY3-06
Pointer to Pointer (Chain of Pointers)
It is possible to make a pointer to point to another pointer. A variable that is a pointer to a
pointer must be declared using additional indirection operator symbols in front the name.
For example:
int *p, **ptr, num;
This declaration tells the compiler that p is a pointer and ptr is a pointer to a pointer of int
type.
p = #
ptr = &p;
**p = 15;
Pointers to an Array
When an array is declared, the compiler allocates a base address and sufficient amount
of storage to contain all the elements of the array in contiguous memory locations.
Suppose we declare an array num as follows:
int num[50] = { 10, 20, 30, 40, 50 };
if we declare ptr as an integer pointer, then we can make the pointer ptr to point to the
array num by the following assignment:
ptr = num; or ptr = &num[0];
now we can access every value of num using ptr++ to move from one element to
another.
Pointers can be used to manipulate two-dimensional array as well. For example:
int v[2][3]; is a two-dimensional array,
int *ptr;
if we declare ptr as an int pointer with the initial address of &v[0][0], then
v[i][j] is equivalent to *(ptr+4 * i + j );
Pointers and Character Strings
C supports a method to create strings using pointer variable of type char. Example
char *name = “Bhagirath”;
This creates a string for the literal and then stores its address in the pointer variable
name. Like in one-dimensional arrays, we can use a pointer to access the individual
characters in a string.
Array of Pointers
An array of pointers would be a collection of addresses. The addresses present in it can
be addresses of isolated variables or addresses of array elements or any other
addresses. For example:
int *ptr[3]; //array of integer pointers
int a = 10, b = 20, c = 30;
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 10
PCE Programming for Problem Solving 1FY3-06
ptr[0] = &a;
ptr[1] = &b;
ptr[2] = &c;
One important use of pointers is in handling of a table of strings. Consider the following
array of strings:
char names[3][20];
This says that the name is a table containing three names, each with a maximum length
of 20 characters. We know that rarely the individual strings will be of equal length.
Therefore, instead of making each row a fixed number of characters, we can make it a
pointer to a string of varying length. For example,
char *names[3] = { “Bhagirath”, “Vedant”, “Suraj” };
declares names to be an array of three pointers to characters, each pointer pointing to a
particular name.
Pointers and Structures
We know that the name of an array stands for the address of its zeroth element. The
same thing is true of the names of arrays of structure variables. Suppose students is an
array variable of struct type. The name students represents the address of its zeroth
element.
struct record
{
int rollno;
char name[30];
float per;
} students[5], *ptr;
ptr = students;
The pointer ptr will now point to students[0]. Its members can be accessed using the
following notation:
ptr -> rollno;
ptr ->name;
ptr -> per;
The symbol -> is called the arrow operator (also known as member selection operator).
We could also use the notation:
(*ptr).rollno;
Disadvantages of Pointers
Pointers are a little complex to understand.
Pointers can lead to various errors such as segmentation faults or can access a
memory location which is not required at all.
If an incorrect value is provided to a pointer, it may cause memory corruption.
Pointers are also responsible for memory leakage.
Pointers are comparatively slower than that of the variables.
Programmers find it very difficult to work with the pointers; therefore it is
programmer’s responsibility to manipulate a pointer carefully.
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 11
PCE Programming for Problem Solving 1FY3-06
Dynamic Memory Allocation
The process of allocating memory during program execution is called dynamic memory
allocation. Dynamic Memory Allocation is manual allocation and freeing of memory
according to our programming needs.
C provides some functions to achieve these tasks. There are 4 library functions provided
by C defined under <stdlib.h> header file to facilitate dynamic memory allocation in C
programming. They are:
1. malloc()
2. calloc()
3. free()
4. realloc()
malloc() Function
malloc or ‘memory allocation’ function is used to allocate space in memory during
theexecution of the program.
malloc function does not initialize the memory allocated during execution. It carries
garbage value.
malloc function returns null pointer if it couldn't able to allocaterequested amount of
memory.
Syntax:
ptr = (castType*) malloc (size in bytes);
Example: Create a Dynamic array of n elements and print the sum of elements.
#include <stdio.h>
#include <stdlib.h>
void main()
{
int size, i. *ptr, sum = 0;
printf(“\nEnter the size of an array: ”);
scanf(“%d”,&size);
ptr = (int*) malloc (size * sizeof(int) );
if(ptr == NULL)
{
printf(“\nNo memory available”);
exit(0);
}
printf(“\nEnter %d elements:”, size);
for(i =0; i < size ; i++)
{
scanf(“%d”, ptr+i);
sum = sum + *(ptr+i);
}
printf(“\nSum = %d”,sum);
free(ptr);
}
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 12
PCE Programming for Problem Solving 1FY3-06
calloc() Function
“calloc” or “contiguous allocation” method in C is used to dynamically allocate the
specified number of blocks of memory of the specified type. it is very much similar to
malloc() but has two different points and these are:
1. It initializes each block with a default value ‘0’.
2. It has two parameters or arguments as compare to malloc().
Syntax:
ptr = (castType*) calloc (n, size in bytes);
realloc() Function
realloc function modifies the allocated memory size by malloc and calloc functions to
new size.
If enough space doesn't exist in the memory of the current block to extend, a new
block is allocated for the full size of reallocation, then copies the existing data to the
new block and then frees the old block.
free() Function
Dynamically allocated memory created with either calloc() or malloc() doesn't get
freed on their own.
free() function frees the allocated memory by malloc(), calloc(), realloc() functions.
Subject Teacher: Bhagirath Singh Chauhan # 9829275869 Page No.: 13