0% found this document useful (0 votes)
4 views186 pages

Unit 4 C Notes by Prof. Shahid Masood

Uploaded by

yrfhj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views186 pages

Unit 4 C Notes by Prof. Shahid Masood

Uploaded by

yrfhj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 186

CABSMJ-1001 [2024-25]

CABSMJ-1001
Problem Solving Using C
Unit - IV
CABSMJ-1001 [2024-25]

Recursion
Recursive function CABSMJ-1001
int rf(int n) [2024-25]
(finds sum of first n { int res;
Recursion natural numbers) if ( n==1 ) Base
condition
return 1;
 It is a technique of defining a process res = n + rf(n-1);
in terms of itself. return res;
}
 It is implemented by means of recursive function that:
 calls itself repeatedly till base condition (called Direct recursion)
is satisfied or
 calls another fn which calls the first fn. (called Indirect recursion)

 Two important conditions that must be satisfied by recursive functions:


1. There must be a base criteria (for stopping the recursive process).
2. After each recursive call - we must get closer to the solution.

Recursion is an extremely powerful mechanism that can express


many otherwise complex processes very clearly in few steps.
CABSMJ-1001 [2024-25]

Example
Computing the value of n! (n is a non-negative integer)

 Iterative function:

int fact( int n)


{ int f = 1, i;
for ( i=2; i<=n; i++) /* if n=0 or 1, loop not executed */
{ f = f * i;
}
return f;
}
CABSMJ-1001 [2024-25]

Alternative method – to compute n!


n! = n x (n-1)!
n! = n x ((n-1) x (n-2)!)
n! = n x ((n-1) x ((n-2) x (n-3)!))
: : :
n! = n x ((n-1) x ((n-2) x……x (2 x 1!)))
n! = n x ((n-1) x ((n-2) x……x (2 x (1 x 0!))))
Then backtrack using 0!=1 to find value of 1!, using 1! to find value of 2!,
and so on. Finally using (n-1)! to find the value of n!:
n! = n x (n-1) x (n-2) x……x 3 x 2 x 1 x 1

Recursive defn: 1 if n=0


fact(n) =
n * fact(n-1) if n>0
CABSMJ-1001 [2024-25]

Recursive Factorial function

C Recursive function C Recursive function (Ver.2)


int fact(int n) int fact(int n)
{ int f; { if (n==0) return 1;
if (n==0) return 1; return (n*fact(n-1));
f = n*fact(n-1);
}
return f;
}

Computation of fact(4) using stack?

Note: During execution of the Recursive function, a stack is


used.
CABSMJ-1001 [2024-25]
Pop Push
Stack data structure
top 4
 It is a linear collection of 3 stack
elements in which all insertions 2
and deletions take place: 1
 only at one end which is Stack mechanism
 called top of the stack.

 It follows LIFO phenomenon.

 Example: Stack of trays/plates


kept on a table.
CABSMJ-1001 [2024-25]

main() int fact(int n)


Address {... { int f;
Address
of instr. ... of instr. if (n==0) return 1;
5001 value = fact(4); 8868 f = n*fact(n-1);
...
return f;
}
}
Computation of fact(4) by the recursive function:
from To calling Insert Delete
Call-I (main) fact(4)  f = 4 * fact(3) = 24 main() fn. n address

Call-II (fact) fact(3)  f = 3 * fact(2) = 6


0 8868
Call-III (fact) fact(2)  f = 2 * fact(1) = 2 1 8868
2 8868
Call-IV (fact) fact(1)  f = 1 * fact(0) = 1 3 8868
4 5001
Call-V (fact) fact(0)  return 1 stack
CABSMJ-1001 [2024-25]

C Program To Compute Factorial Using Recursion


/* factusingrfn.c */
#include<stdio.h>
int fact(int n)
{ if (n==0)
return 1;
return( n*fact(n-1) ); Output
} Enter a positive integer: 5
main() Factorial of 5 = 120
{ int num;
printf("Enter a positive integer: ");
scanf("%d",&num);
printf("Factorial of %d = %d", num, fact(num));
}
CABSMJ-1001 [2024-25]

Advantages of Recursion

 Concise and elegant programming technique

 Easier to write & understand

 No need of using looping structures

 Give final result (No need to focus on intermediate values)


CABSMJ-1001 [2024-25]

Disadvantages of Recursion
 Execution time is more due to:
 maintenance of stack
 multiple function calls & return overhead

 Takes more memory

 We can’t get intermediate values

 May result in indefinite looping

 Can’t be applied for - all looping processes


CABSMJ-1001 [2024-25]

main() int factorial(int n)


Address {... { int fact = 1, i;
of instr. ... for ( i=2; i<=n; i++)
5001 value = factorial(4); fact = fact * i;
... return f;
} }

Function call & return involves following operations:


i) Saving current contents of registers and pushing the address
of next instruction (to be executed after the function call is
complete) onto the stack
ii) Pushing actual arguments of the fn call onto the system stack
iii) Jumping (transferring control) to the function
iv) Popping the actual arguments from system stack and copying
into formal arguments (now called function is executed)
CABSMJ-1001 [2024-25]

main() int factorial(int n)


Address {... { int fact = 1, i;
of instr. ... for ( i=2; i<=n; i++)
5001 value = factorial(4); fact = fact * i;
... return f;
} }

v) Saving the return value in memory, if any (when execution of


called function is complete)
vi) Returning the control to the next instruction to be executed
in the calling function (its address is popped out from the stack)
vii) Returned value (if any) is retrieved for use in the calling
function
viii) Reloading the contents of registers saved earlier – so that
remaining part of the calling function may be executed.
CABSMJ-1001 [2024-25]

Prob:

Write a C program that reads a non-negative integer n and


finds sum of its individual digits using a recursive function.

Solu: Iterative function:


n s
int sum(int n)
{ int s = 0; 0
while ( n != 0 ) 4250 0+0 =0
{ s = s + n%10; 425 0+5 =5
n = n/10;
42 5+2 =7
}
return s; 4 7+4 =11
} 0
CABSMJ-1001 [2024-25]

Recursive 0 if n=0
definition: sum(n) =
n%10 + sum(n/10) if n>0

Recursive function Recursive function (Ver.2)


int sum(int n) int sum(int n)
{ int s; { if (n==0) return 0;
if (n==0) return 0; else
else return(n%10+sum(n/10));
{ s = n%10+sum(n/10); }
return s;
}
}
CABSMJ-1001 [2024-25]
int sum(int n)
Working of { int s;
int main() if (n==0) return 0;
Recursive {... else
function value= sum(1234); { s = n%10+sum(n/10);
... return s;
} }
}
Fn. call: sum(1234);
From Return
Call I (main) sum(1234)  s = 4 + sum(123) = 10 to main()

Call II (sum) sum(123)  s = 3 + sum(12) = 6


Call III (sum) sum(12)  s = 2 + sum(1) = 3

Call IV (sum) sum(1)  s = 1 + sum(0) = 1


Call V (sum) sum(0)  return 0
CABSMJ-1001 [2024-25]

C Program To Compute Sum of Individual Digits Using Recursion


/* sumofdigitsrfn.c */
#include<stdio.h>
int sum(int n) Output
{ if (n==0) Enter a non-negative integer: 1234
return 0; Sum of digits = 10
else
return(n%10+sum(n/10));
}
main()
{ int n;
printf("Enter a non-negative integer: ");
scanf("%d",&n);
if ( n<0 )
printf("n should be non-negative");
else
printf("Sum of digits = %d",sum(n));
}
CABSMJ-1001 [2024-25]

Prob
Write a C program that reads the term number (n) and returns
the nth term of the Fibonacci series using a recursive function.
Assume that the Fibonacci series terms are numbered as below:
T1 T2 T3 T4 T5 T6 T7 T8 . . . . .
0, 1, 1, 2, 3, 5, 8, 13 . . . . .

Solu: Recursive definition:


Term number

n-1 if n=1 or n=2


fib(n) =
fib(n-1) + fib(n-2) if n>2
CABSMJ-1001 [2024-25]
C Recursive function
Recursive
function int fib(int n)
{ if (n==1||n==2)
return (n-1);
else
return ( fib(n-1)+fib(n-2) );
}
Fn. call: fib(4);
Value
fib(4)  return ( fib(3) + fib(2) ) = 2 returned

fib(3)  return ( fib(2) + fib(1) ) = 1 fib(2)  return (1)

fib(2)  return (1)


fib(1)  return (0)
CABSMJ-1001 [2024-25]

C Program To Print nth Fibonacci Term Using Recursive fn


/* fibtermrfn.c */ T1 T2 T3 T4 T5 T6 T7 T8 . . . .
#include<stdio.h> 0, 1, 1, 2, 3, 5, 8, 13 . . . .
int fib(int n)
Output
{ if (n==1||n==2)
return (n-1); Enter term number (a positive int): 5
else 5th Fibonacci term = 3
return ( fib(n-1)+fib(n-2) );
}
main()
{ int n;
printf("Enter term number (a positive int): ");
scanf("%d",&n);
if ( n<1 ) printf("Enter a positive int");
else
printf("%dth Fibonacci term = %d", n, fib(n));
}
CABSMJ-1001 [2024-25]

Prob:
Write a C program that reads the no. of terms n (a positive
integer) and finds the sum of first n terms of the following
series using a recursive function.
1 + 4 + 9 + 16 + 25 + . . . . . upto n terms.

Solu: Recursive definition:

1 if n=1
sum(n) =
n*n + sum(n-1) if n>1
1 + 4 + 9 + 16 + 25 + . . CABSMJ-1001 [2024-25]
. upto n terms

Recursive int sum(int n)


function: { if ( n==1 )
return 1;
else
return(n*n+sum(n-1));
}
Fn. call: sum(4);
Value
sum(4)  return(16+ sum(3)) = 30 returned

sum(3)  return( 9 + sum(2)) = 14


sum(2)  return( 4 + sum(1)) = 5

sum(1)  return 1
CABSMJ-1001 [2024-25]

C Program To Find Sum of n Terms of the Series Using Recursion


/* sumseriesrfn.c */
#include<stdio.h> Output
int sum(int n) Enter no. of terms (a positive integer): 4
{ if ( n==1 )
Sum of 4 terms = 30
return 1;
else
return(n*n+sum(n-1));
}
main() 1 + 4 + 9 + 16 + 25 + . . . upto n terms
{ int n;
printf("Enter no. of terms (a positive integer): ");
scanf("%d",&n);
if ( n<=0 ) printf("n should be a positive integer");
else
printf("Sum of %d terms = %d", n, sum(n));
}
CABSMJ-1001 [2024-25]

Prob:
Write a C program that reads two positive integers a and b and
finds their greatest common divisor (GCD) using a recursive
function.

Solu: Recursive definition:


a b a%b
20 75 20
b if ( a%b ) == 0 75 20 15
gcd(a,b) =
20 15 5
gcd(b, a%b) otherwise
15 5 0
CABSMJ-1001 [2024-25]

Recursive function C recursive function


to compute GCD: int gcd(int a,int b)
{ if (a%b==0)
return b;
else
return(gcd(b,a%b));
}
Fn. call: gcd(48,20):
Value
gcd(48,20)  return( gcd(20,8) ) = 4 returned

gcd(20,8)  return( gcd(8,4) )


gcd(8,4)  return 4
CABSMJ-1001 [2024-25]

C Program To Find GCD of two positive integers Using Recursion


/* gcdusingrfn.c */
#include<stdio.h>
int gcd(int a,int b)
{ if (a%b==0)
return b;
else
return(gcd(b,a%b)); Output
} Enter two positive integers: 20 8
main() GCD = 4
{ int x, y;
printf("Enter two positive integers: ");
scanf("%d %d",&x,&y);
if ( x<=0 || y<=0 )
printf("Enter positive integers");
else
printf("GCD = %d",gcd(x,y));
}
CABSMJ-1001 [2024-25]

Prob:

Write a C program that reads an integer array a[n] and finds


the sum of all its elements using a recursive function.

lb ub
10 11 12 13 14
0 1 2 3 4
a[5]
CABSMJ-1001 [2024-25]

lb ub
10 11 12 13 14
0 1 2 3 4
a[5]
Solu:
C Recursive function
int sum(int a[], int ub)
{ if ( ub==0 )
return a[ub];
else
return (a[ub]+sum(a,ub-1));
}
Fn.call: sum(a,ub) /* output: 60 */
CABSMJ-1001 [2024-25]
int sum(int a[], int ub)
{ if ( ub==0 ) lb ub
return a[ub]; 10 11 12 13 14
else 0 1 2 3 4
return (a[ub]+sum(a,ub-1)); a[5]
}

Fn. call: sum(a,4);


Value
sum(a,4)  return(a[4]+sum(a,3)) = 60 returned

sum(a,3)  return(a[3]+sum(a,2)) = 46
sum(a,2)  return(a[2]+sum(a,1)) = 33

sum(a,1)  return(a[1]+sum(a,0)) = 21
sum(a,0)  return(a[0]) = 10
CABSMJ-1001 [2024-25]

C Program To Find Sum of All Elements of 1D array Using Recursion


/* sumarrayrfn.c */
#include<stdio.h> Output
#define N 100 Enter size of the array (positive integer): 5
long sum(int a[], int ub) Enter 5 array elements
{ if ( ub==0 ) 10 20 30 40 50
return a[ub]; Sum of all array elements = 150
else
return (a[ub]+sum(a,ub-1));
}
main()
{ int n, a[N], i;
printf("Enter size of the array (max size %d): ",N);
scanf("%d",&n);
printf("Enter %d array elements\n",n);
for (i=0; i<n; i++)
scanf("%d",&a[i]);
printf("Sum of all array elements = %ld",sum(a,n-1));
}
CABSMJ-1001 [2024-25]

Storage
Classes
in C
CABSMJ-1001 [2024-25]

Storage Classes
 In C programming, every variable has two properties:
1. Data type and
2. Storage class
i.e. every C variable not only has a data type but it also has
a storage class.

 There are four types of storage classes in C:


1. auto (automatic)
2. register
3. extern (external or global)
4. static
CABSMJ-1001 [2024-25]

Storage Classes
 Till now, we have been declaring variables in our C programs
by specifying their data type only, e.g.
int i;
float j;
char c;
 If we don’t specify the storage class while declaring a
variable:
 some default storage class is auto assumed by the compiler
 depending upon the location of the variable declaration
in the program.
In C, general form of variable’s declaration statement is:
StorageClass DataType VarName; e.g. static int i;
CABSMJ-1001 [2024-25]

Features of Storage Classes


Each storage class specifies following four features of the variable:
1. Where the variable would be stored?
(i). in primary Memory or
(ii). in a CPU register
 Normally values of variables are stored in primary memory but
C provides a special feature through which the values of few (2
to 3) variables can be stored in CPU registers.
 A variable stored in a CPU register is accessed much faster.
 So, if we store a variable that is accessed many times in a
program (like loop control variable) in a CPU register, program
efficiency will increase.
CABSMJ-1001 [2024-25]

Features of Storage Classes

2. What will be the default initial value of the variable?


(i). Garbage value or
(ii). Zero

 If some initial value is not assigned while declaring a variable


(e.g. int a; ) then:
 by default, the variable will contain either some garbage
(unpredictable) value or 0
 depending upon default storage class assumed for this
variable by the compiler.
CABSMJ-1001 [2024-25]

A block is a group of
Features of Storage Classes statements enclosed
within { and }.

3. What will be the scope/visibility of the variable?


Scope of a variable specifies that:
 in which part of the program (i.e. in which functions or blocks)
 the variable would be available/accessible.

4. What will be the life of the variable?


This feature specifies that:
 how long a variable would exist in the memory/CPU-register
 during the execution of the program.
CABSMJ-1001 [2024-25]

Storage Class Specifications

There are 4 storage class specifications:


• Only local variables can be
1. auto (automatic variable) declared auto or register.
• They are declared inside a block.
2. register

3. extern (external or global variable)


A local or global variable can be
4. static
declared static variable.

C variable declaration: auto int i; /* local variable */


register int j; /* local variable */
extern double x; /* global variable */
static float y; /* local/global variable */
CABSMJ-1001 [2024-25]
void main()
{ ……… /* auto var */
1. Automatic (auto) Variables { ……. /* auto var */
}
………..
Features of auto storage class: }

Storage Memory
Default initial value Garbage
Scope (Accessibility)  Accessible in the block in which the
variable is declared
 Also known as internal variables
Life Till the control remains in the block in
which it is declared
CABSMJ-1001 [2024-25]
void main()
{ auto int a; /* auto var */
Automatic (auto) Variables { int b; /* auto var */
}
………..
}
 Declared inside a block in which they are to be used.
 They are created when control enters the block and auto
deleted when the block is exited (hence the name automatic).
 Automatic variables can have the same variable names in
different blocks/functions. Value of such a variable in one
block is not affected by changing the value of another
variable in another block (this allows declaration and use of
same variable names in different functions/blocks in the program).
 Default storage class of a variable declared inside a block is
auto (automatic).
CABSMJ-1001 [2024-25]

Automatic (auto) Variables


Ex.1: Default storage class of a variable declared inside a block is
auto (automatic):
#include<stdio.h>
main()
{ int a=10; /* eqv. to: auto int a */
auto int b;
{ int c=20; /* eqv. to: auto int c */
printf("%d %d %d\n",a,b,c); /* a,b,c available in this block */
}
printf("%d %d\n",a,b); /* output: 10 garbage */
printf("%d",c); /* compilation error: undefined symbol c */
}
CABSMJ-1001 [2024-25]

Automatic (auto) Variables


Ex.2: Automatic variables can have the same variable names in
different blocks/functions:
#include<stdio.h>
main()
{ auto int a=5, b=10;
{ int a=50, b=100;
printf("%d %d\n",a,b); /* 50 100 (local a gets precedence) */
}
b = 20;
printf("%d %d\n",a,b); /* 5 20 */
}

 Compiler treats both the a’s and b’s as totally different


variables (as they are defined in different blocks).
 Every a and b is local to its block.
void main() CABSMJ-1001 [2024-25]

{ register int x=10; /* register var */


2. register Variables { register int y; /* register var */
}
………..
}
Features of register storage class:
Storage CPU register
Default initial value Garbage
Scope (Accessibility)  Accessible in the block in which the
variable is declared
 Also known as internal variables
Life Till the control remains in the block in
which it is declared
CABSMJ-1001 [2024-25]

register Variables
 local variables (variables inside a block) or formal
parameters of a function can be declared register
 Accessible much faster than a memory variable (as register
access is faster than a memory access)
 Program efficiency is improved.

Ex.1 #include<stdio.h> /*print numbers between 1-2000 divisible by 500 */


main()
{ register int i, x=500; /*storage class of i and x is register/*
for ( i=1; i<=2000; i++ )
if ( ( i%x ) == 0 ) Output
printf("%d ",i); 500 1000 1500 2000
}
CABSMJ-1001 [2024-25]

register Variables (Points to be Remembered)

1. Variable i and x will be stored in CPU registers:


 but there is no guarantee that they will be certainly stored
in CPU registers
 because if the CPU registers are already occupied & busy
doing some other task then the storage class for i and x will
be assumed as auto.

2. Later if a register becomes available, then:


 the storage class of one of these variables i.e. i will be
changed to register for the rest of the execution of the
program.
 In the meanwhile, if another register becomes available
then storage class of x also will be changed to register.
CABSMJ-1001 [2024-25]

register Variables (Points to be Remembered)

3. Most compilers allow only 2 to 3 register variables to be


stored in the CPU registers.

4. The register specifier can only be applied to local variables


or to the formal parameters of a function.
Global register variables are not allowed.
CABSMJ-1001 [2024-25]
Ex.2: Printing numbers between 1 to 200 using function in
which formal parameter is register type
#include<stdio.h> Output
void print(register int n) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
{ register int i; 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
for (i=1; i<=n; i++) 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
printf("%d ",i); 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
}
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
main()
101 102 103 104 105 106 107 108 109 110 111 112
{ 113 114 115 116 117 118 119 120 121 122 123 124
print(200); 125 126 127 128 129 130 131 132 133 134 135
} 136 137 138 139 140 141 142 143 144 145 146
147 148 149 150 151 152 153 154 155 156 157
158 159 160 161 162 163 164 165 166 167 168
169 170 171 172 173 174 175 176 177 178 179
180 181 182 183 184 185 186 187 188 189 190
191 192 193 194 195 196 197 198 199 200
CABSMJ-1001 [2024-25]

3. extern Variables (External or Global Vriables)


Features of extern storage class:
Storage Memory
Default initial value Zero

Scope (Accessibility) Global


i.e. the variable will be accessible from the
point of its declaration till the end of the
program
 in the file in which it is defined and
 in other files also.
Life Value is retained till the execution of the
program comes to an end
CABSMJ-1001 [2024-25]
Default storage class #include<stdio.h>
extern, default initial int a; //global var */
extern Variables value 0 void fn1()
{.....
}
 Default storage class of a variable
int b; //global var */
declared outside of functions is extern. void fn2()
{.....
 Default initial value of extern variable is 0. }
main()
 It is accessible from the point of its
{.....
declaration till the end of program (also }
accessible in other files).
 Any function in its scope (i.e. below its declaration) can use
them and change their values.

 Value is retained till the execution of the program comes to


an end.
CABSMJ-1001 [2024-25]
Ex.1: Default initial value of extern (global) variable is 0
#include<stdio.h>
int a; /* default storage class extern, default initial value 0 */
void add() /* extern is not to be written before int a; it gives comp error */
{ a = a+1;
printf("a=%d\n",a);
}
void sub()
{ a = a-1;
printf("a=%d\n",a);
} Output
main() a=1
{ add(); a=2
add(); a=1
sub(); a=0
sub();
}
Ex.2: Writing extern int a; in the beginning of function body is[2024-25]
CABSMJ-1001

optional
#include<stdio.h>
int a;
void add()
{ extern int a; /* writing extern int a; [optional] */
a = a+1;
printf("a=%d\n",a);
}
void sub()
{ extern int a; /* writing extern int a; [optional] */
a = a-1;
printf("a=%d\n",a); Output
} a=1
main()
a=2
{ extern int a;
a=1
add(); add();
sub(); sub();
a=0
}
CABSMJ-1001 [2024-25]
Ex.3: By default, extern (global) variable is accessible from the
point of its declaration onward.
#include<stdio.h>
/* extern int a; must be written here to */
void add()
/* access a in add() function, otherwise */
{ /* a will not be accessible in add() and */
a = a+1; /* we will get compilation error: */
printf("a=%d\n",a); /* “undefined symbol a in add()”. */
}
int a; /* a is accessible from here till end of program */
void sub()
{ a = a-1;
printf("a=%d\n",a); Output
} a=1
main() a=2
{ add(); add(); a=1
sub(); sub(); a=0
}
CABSMJ-1001 [2024-25]

4. static Variables Features of static storage class:


Storage Memory
Default initial value Zero
Scope  If a local variable is declared static:
(Accessibility) o it will be accessible in the block in which it
is declared
o It is also known as internal static variable
 If a global variable is declared static:
o it will be accessible from the point of its
declaration till the end of program
o It will be accessible only in the file in which
it is defined
o It is also known as external static variable
Life Value is retained till the execution of the
program comes to an end
CABSMJ-1001 [2024-25]

static Variables

 Variables declared inside a block (local var) or variables


declared outside of all functions (global var) can be declared
static.

 Static variable is initialized only once (when the program is


compiled) and never initialized again.

 Their values persist until the end of program execution (i.e.


their values are retained in the memory and not destroyed after
the execution of the function/block is over).

 Static means that has no movement, so is the value of static


variables which doesn’t come and go as the function is called
and returns.
CABSMJ-1001 [2024-25]

static Variables
Ex. Illustrates the Use of Local (or Internal) static variables
#include<stdio.h>
void add()
{ static int count; /* default initial value of count is 0 */
static int a = 50; /* both variables initialized only once */
printf("Fn.call no. %d\n",++count);
printf("a = %d\n",a);
Output
a = a+10;
Fn.call no.1
}
a = 50
main()
Fn.call no.2
{ add();
a = 60
add();
Fn.call no.3
add();
a = 70
}
CABSMJ-1001 [2024-25]

static Variables
Ex. Illustrates the Use of Global (or External) static variables
#include<stdio.h>
static int a = 100; /* a is static extern variable (accessible */
int addwitha(int x,int y) /* in this file only) */
{ return x+y+a;
}
main()
{ a = addwitha(10,20);
Output
printf("a = %d\n",a); a = 130
a = addwitha(10,20); a = 160
printf("a = %d\n",a);
}
CABSMJ-1001 [2024-25]

static Variables (Points to be Remembered)


1. Its use should be avoided.

2. It should be used only when it is really needed because it


remains in the memory throughout the execution of the
program and that much memory remains occupied which
otherwise could be used for some other use.

3. static extern variable Vs. extern variable

static extern variable extern variable


It is available/accessible to It is available/accessible to
all the functions within the all the functions within the
file in which it is defined. file and in other files also.
CABSMJ-1001 [2024-25]

Dynamic
Memory
Allocation
CABSMJ-1001 [2024-25]

Memory Allocation

 Memory allocation is a process by which variables are


assigned memory space.
 There are two types of memory allocations.

Two types of memory allocation


1. Compile-time (or Static Memory Allocation)

2. Run-time (or Dynamic Memory Allocation)


CABSMJ-1001 [2024-25]

Compile-time or Static Memory Allocation

 Memory allocation done for the declared variables


automatically by the compiler at compile-time – known as
static memory allocation.

 Starting address of the memory allocated to any variable can


be found using the ’&’ (address of) operator.

 In static memory allocation, once the memory is allocated, the


memory size is fixed (it can’t be changed).

 Memory is allocated in the stack region of memory.


CABSMJ-1001 [2024-25]

Example - Compile-time (or Static Memory Allocation)


main()
{ float x, y; /* 4 bytes reserved for x and 4 bytes for y */
double a[50]; /* 8*50 = 400 bytes reserved for array a */
.....
}

 In static memory allocation:


 the memory size for variables is fixed at compile-time
 and memory is actually allocated when the program
execution is started.
Limitations of Static Memory Allocation:
1. Memory size is fixed.
2. Wastage of memory (if allocated memory is not being used fully).
3. Can’t store elements more than the size of the array.
CABSMJ-1001 [2024-25]
ptr=(cast-type *) malloc(byte-size);
Dynamic Memory Allocation
 Sometimes we need to allocate memory of desired size and type
to store the data at run-time.
 Memory allocation done at run-time by the programmer using
library functions is known as dynamic memory allocation.
 In dynamic memory allocation, contiguous memory space of
desired size and type is allocated at run-time.
 Memory allocated dynamically can be freed when it is no more
required (it is immediately released/deallocated).
 Memory size of a previously allocated block can be changed.
 Memory is allocated in the heap region of memory.
uses complicated uses simple linear
hierarchical data structure data structure
 Program executes slower because heap is slower than stack.
DynamicCABSMJ-1001
int array of 10[2024-25]
elements

Library Functions Used For int *ptr = (int*) malloc(10*sizeof (int));


Dynamic Memory Allocation int *ptr = (int*) calloc(10 , sizeof (int));
malloc()  Used to allocate space of desired size and returns
a pointer to the first byte of the allocated space.
 Allocates a single block of storage which can be
used for storing fundamental types or derived
data types, such as arrays and structures.
calloc()  Used to allocate space for storing derived data
types, such as arrays and structures, initializes all
bytes to zero and then returns a pointer to the
first byte of the allocated space.
 Allocates contiguous space for multiple blocks of
storage, each of same size to a single variable.
free() Frees (deallocates) previously allocated space.
realloc() Modifies the size of the previously allocated space.
CABSMJ-1001 [2024-25]
ptr
malloc() Library Function Storage block

 Allocates a storage block of desired size and type at run-time.


 It returns a pointer:
 of type void to the first byte of the storage block
 that can be type casted into any desired type.

General form:
ptr = (cast-type *) malloc(byte-size);

 void type pointer (to the allocated storage block with size
byte-size) returned by malloc() is type casted to cast-type.
 ptr is a pointer of type cast-type.
 Allocated storage block initially contains garbage value.
CABSMJ-1001 [2024-25]
p1
malloc() Library Function float type (4 bytes)

p2
int type (4 bytes)

Examples:
float *p1 = (float*) malloc(4); /* can store a float value */
int* p2 = (int*) malloc(sizeof(int)); /* can store an int value */

 Storage block (allocated dynamically) has no name.


 It is accessible through its pointer only for various operations.
 If memory allocation is not successful, malloc() returns a NULL
pointer. It can be checked as below:
if ( p2==NULL )
printf("Memory allocation failed…");
CABSMJ-1001 [2024-25]
p1
malloc() Library Function float type (4 bytes)

p2
int type (4 bytes)

Examples:
float *p1 = (float*) malloc(4); /* can store a float value */
int* p2 = (int*) malloc(sizeof(int)); /* can store an int value */

 Data can be read into or stored data can be retrieved from


these storage blocks as below:

scanf("%f %d", p1, p2); /* input: 10.5 45 */


printf("%f %d", *p1, *p2); /* output: 10.500000 45 */
CABSMJ-1001 [2024-25]
p1
float type (4 bytes)
Deallocation of Dynamically
Allocated Memory p2
int type (4 bytes)

 Previously allocated storage can be released when it is no


more required during execution of the program.
 It becomes immediately available for some other use.

free(p1); /* deallocates storage block pointed to by p1 */


free(p2); /* pointers p1 and p2 can be reused */

 malloc() and free() functions are defined in stdlib.h file.

Note: Dynamically allocated memory has dynamic duration


i.e. it will stay allocated until you deallocate it or the
program terminates.
CABSMJ-1001 [2024-25]
Example: C program that reads two integer numbers stored in
dynamically allocated storage and finds their sum:
/* dma1.c */
#include<stdio.h>
#include<stdlib.h> p1 10
main() int type (4 bytes)
{ int *p1, *p2, sum;
p2 20
p1 = (int *) malloc(sizeof(int));
int type (4 bytes)
p2 = (int *) malloc(sizeof(int));
if (p1==NULL || p2==NULL)
{ printf("Memory allocation failed...exiting");
exit(1); }
printf("Enter two integer values: "); Output
scanf("%d %d", p1, p2); Enter two integer values:
sum = *p1 + *p2;
10 20
Sum = 30
printf("Sum = %d",sum);
}
CABSMJ-1001 [2024-25]

Prob:

Write a C program that reads two integers for which storage


is allocated dynamically and swaps their values using
function.
#include<stdio.h> /* dma2.c */ CABSMJ-1001 [2024-25]
p1 100
#include<stdlib.h>
void swap(int *p1,int *p2) int type (4 bytes)
{ int temp = *p1; p2 200
*p1 = *p2; int type (4 bytes)
*p2 =temp;
}
main()
{ int *p1, *p2; Output
p1 = (int *) malloc(sizeof(int)); Enter two integer values: 100 200
p2 = (int *) malloc(sizeof(int)); Values after swapping: 200 100
if (p1==NULL || p2==NULL)
{ printf("Memory allocation failed...exiting");
exit(1); }
printf("Enter two integer values: ");
scanf("%d %d", p1, p2);
swap(p1,p2);
printf("Values after swapping: %d %d",*p1,*p2);
}
CABSMJ-1001 [2024-25]
0 1 2 3 4 5 6 7 8 9
Allocating Storage for a
1D Dynamic Array
a+1 a+2

 To allocate a storage block for storing 10 floats:


float *a;
a = (float *) malloc(10*sizeof(float));

 Reading and retrieving data from this storage block:


for (i=0; i<10; i++)
scanf("%f", (a+i) ); /* &a[i] can also be used */
for (i=0; i<10; i++)
printf("%f ", *(a+i) ); /* a[i] can also be used */

Deallocation: To deallocate storage when it is no more required:


free(a); /* deallocates storage block pointed to by a */
CABSMJ-1001 [2024-25]

Prob:
Write a C program that reads marks obtained in a test by n
students into a 1D dynamic array (for which storage is
allocated dynamically) and finds how many students have
secured marks >= average marks.
/* dynamicarray1.c */ CABSMJ-1001 [2024-25]
0 1 2 3 4 5 6 7 8 9
#include<stdio.h>
a
#include<stdlib.h>
main()
{ int n, *a, i, count=0; a+1 a+2
float avg, sum=0;
printf("Enter no. of students: ");
scanf("%d",&n); Output
a = (int*) malloc(n * sizeof(int)); Enter no. of students: 5
printf("Enter %d marks\n",n); Enter 5 marks
for (i=0; i<n; i++) 75 
{ scanf("%d",(a+i)); /* or &a[i] */ 80 
sum = sum + *(a+i); /* or a[i] */ 65 
} 55 
avg = sum / n; 80 
printf("Average marks= %.2f\n",avg); Average marks= 71.00
for (i=0; i<n; i++) No. of students securing
if( *(a+i) >= avg ) count++; marks >= average marks= 3
free(a);
printf("No. of students securing marks >= average marks= %d",count);
}
CABSMJ-1001 [2024-25]

Prob:

Write a C program that reads n integers into a 1D dynamic


array (for which storage is allocated dynamically) and finds
biggest using function.
/* dynamicarray1b.c */ 0 1 2 3 4
CABSMJ-1001 [2024-25]
5 6 7 8 9
#include<stdio.h> a
#include<stdlib.h>
int biggest(int *a, int n)
{ int big = *(a+0), i; a+1 a+2
for (i=1; i<n; i++)
{ if ( *(a+i) > big ) /* a[i] */
big = *(a+i);
}
return big; Output
} Enter no. of integers (n): 5
main() Enter 5 integer numbers
{ int n, *a, i;
50 
printf("Enter no. of integers (n): ");
scanf("%d",&n); 75 
a = (int*) malloc(n * sizeof(int)); 40 
printf("Enter %d integer numbers\n",n); 90 
for (i=0; i<n; i++) 30 
{ scanf("%d",(a+i)); /* &a[i] */ Biggest = 90
}
printf("Biggest = %d",biggest(a,n));
}
CABSMJ-1001 [2024-25]

Prob:
Write a C program that reads a string str and stores it in
reverse order in another string revstr for which storage is
allocated dynamically.
/* revstrdma.c */ CABSMJ-1001 [2024-25]
0 1 2 3 4 5 6 99
#include<stdio.h>
str[100] M U M B A I \0 ……..
#include<stdlib.h>
#include<string.h>
#define N 100 0 1 2 3 4 5 6
main() revstr I A B M U M \0
{ char str[N], *revstr; revstr+len
int len, i;
printf("Enter a string (max length %d characters)\n",N-1);
gets(str);
len = strlen(str);
revstr = (char *)malloc(sizeof(char)*(len+1));
if ( revstr == NULL ) /* check whether memory allocation is successful */
{ printf("Memory allocation failed. Exiting...");
exit(1); }
/* store str in revstr in reverse order */ Output
for (i = 0; i <= len-1; i++) Enter a string (max length 99 characters)
*(revstr+i) = str[len-1-i]; C Programming 
*(revstr+len) = '\0'; Reversed string is
printf("Reversed string is\n"); gnimmargorP C
puts(revstr);
}
CABSMJ-1001
0 1 2 3 …..[2024-25]
n-1
**a 0
Allocating Storage for 1
: :
2D mxn Dynamic Array m-1
Array of ptrs to int of size m
 To allocate a mxn int array:
 first declare a pointer to pointer to an int,
 then allocate 1D array of pointers to int of size m and store its
base address in the pointer to pointer:

int **a; /* pointer to pointer to int */


a = (int**) malloc(m*sizeof(int*)); /* array of ptrs of size m */

 Then allocate storage for m rows each of size n and store their
base addresses in the array of pointers:

for (i=0; i<m; i++)


a[i] = (int*) malloc(n*sizeof(int)); /* or *(a+i) */
CABSMJ-1001
0 1 2 3 …..[2024-25]
n-1
**a 0
Allocating Storage for 1
: :
2D mxn Dynamic Array m-1
Array of ptrs to int of size m

 Now we can read the input in the dynamic 2D array:


for(i=0; i<m; i++)
{ for(j=0; j<n; j++)
{ scanf("%d", &a[i][j] ); /* or *(a+i)+j */
}
}
 We can retrieve the data from the dynamic 2D array:
for(i=0; i<m; i++)
{ for(j=0; j<n; j++)
{ printf("%d", a[i][j] ); /* or *(*(a+i)+j) */
}
}
CABSMJ-1001 [2024-25]

Prob:

Write a C program that reads input in a mxn integer matrix


for which memory is allocated dynamically and finds the
sum of all its elements.
/* dynamicarray2.c */ 0 1 2 3 …..[2024-25]
CABSMJ-1001 n-1
**a 0
#include<stdio.h> 1
#include<stdlib.h> :
main() m-1
{ int **a, m, n, i, j, sum=0; Array of ptrs to int of size m
printf("Enter No. of rows and columns in the matrix: ");
scanf("%d %d",&m,&n);
a = (int**) malloc(m*sizeof(int*)); /* array of ptrs of size m */
for (i=0; i<m; i++)
a[i] = (int*) malloc(n*sizeof(int)); /* or *(a+i) */
printf("Enter %d x %d matrix elements (row-wise)\n",m,n);
for(i=0; i<m; i++)
{ for(j=0; j<n; j++)
{ scanf("%d",&a[i][j]); /* or *(a+i)+j */
sum = sum + a[i][j]; /* or *(*(a+i)+j) */
}
}
printf("Sum of all elements= %d",sum);
}
CABSMJ-1001 [2024-25]

Output
Enter No. of rows and columns in the matrix: 3 4
Enter 3 x 4 matrix elements (row-wise)
1 2 3 4
5 6 7 8
1 2 3 4
Sum of all elements= 46
CABSMJ-1001 [2024-25]

Prob:
Write a C program that reads m names into a 2D char array
for which memory is allocated dynamically and finds the
longest/lengthiest name.

**name 0 A R I F A L I \0
1 M D R I Z W A N \0
2 S H AM I M A H M A D \0

: :
m-1 R AM K U M A R \0
Array of ptrs to char of size m
/* dynamicarray3.c */ **name 0
CABSMJ-1001 [2024-25]
A R I F A L I \0
#include<stdio.h>
1 M D R I Z W A N \0
#include<stdlib.h> S H AM I M A H M A D \0
2
#include<string.h>
:
main()
m-1 R A M K U M A R \0
{ int m, i, size, loc;
char **name, s[41]; Array of ptrs to char of size m
printf("How many names to be stored: ");
scanf("%d",&m);
name = (char**) malloc(m*sizeof(char*)); /* array of ptrs of size m */
fflush(stdin);
printf("Enter %d names\n",m);
for (i=0; i<m; i++)
{ gets(s);
size = strlen(s)+1;
name[i] = (char*) malloc(size*sizeof(char)); /* *(name+i) */
strcpy(name[i],s); /* *(name+i) */
}
Contd...
CABSMJ-1001 [2024-25]

loc = 0; /* index of longest name */


for (i=1; i<m; i++)
{ if ( strlen(name[i]) > strlen(name[loc]) )
loc = i;
}
printf("Longest name is\n");
puts(name[loc]);
} Output
How many names to be entered: 5
Enter 5 names
Faiz Ahmad
Rashid Ali Khan
Ramesh Kumar Singh
Navin Kumar
Shahzad Ahmad
Longest name is
Ramesh Kumar Singh
CABSMJ-1001 [2024-25]

Dynamic Allocation of Storage For Array of Structures

Prob:
Write a C program that reads product data (name, qty, price)
of n products in a 1D array of structures for which the
storage is allocated dynamically.
Then the program allows searching by product-name and
displays the details of the product.
/* struct5.c */ CABSMJ-1001 [2024-25]

#include<stdio.h> p name qty price


#include<stdlib.h> [0] [1] [2]
(p+1) (p+2)
#include<string.h>
struct data Array of structures
{ char name[21];
int qty;
float price;
};
typedef struct data proddata;
main()
{ proddata *p;
char nm[21], more;
int i, n;
printf("Enter total number of products: ");
scanf("%d",&n);
fflush(stdin);
p = (proddata*) malloc(n*sizeof(proddata)); Contd...
CABSMJ-1001 [2024-25]

p name qty price


[0] [1] [2]
(p+1) (p+2)
Array of structures

for (i=0; i<n; i++) /* reading input */


{ printf("Product data-%d:\n",i+1);
printf("Enter prod Name: ");
gets((p+i)->name); /* or p[i].name */
printf("Enter quantity: ");
scanf("%d",&(p+i)->qty); /* or &p[i].qty */
printf("Enter price: ");
scanf("%f",&(p+i)->price); /* or &p[i].price */
fflush(stdin);
}
Contd...
do CABSMJ-1001 [2024-25]

{ printf("Enter product name to search: ");


gets(nm);
for(i=0; i<n; i++)
{ if ( strcmp(nm,(p+i)->name)==0 ) /* or p[i].name */
{ printf("%-20s %5d %10.2f\n",(p+i)->name,(p+i)->qty,(p+i)->price);
break;
} p name qty price

} [0] [1] [2]


(p+1) (p+2)
if ( i==n )
printf("Not found\n");
printf("Search more (y/n)?");
more = getchar();
fflush(stdin);
} while (more=='y' || more=='Y');
}
CABSMJ-1001 [2024-25]
Output
Enter total number of products: 3
Product data-1:
Enter prod Name: Pen
Enter quantity: 50
Enter price: 10
Product data-2:
Enter prod Name: Note book
Enter quantity: 100
Enter price: 50
Product data-3:
Enter prod Name: Pen drive
Enter quantity: 25
Enter price: 300
Enter product name to search: Note book
Note book 100 50.00
Search more (y/n)?y
Enter product name to search: Pen drive
Pen drive 25 300.00
Search more (y/n)?n
CABSMJ-1001 [2024-25]

Altering the Size of a Previously Allocated Block


 We can change (increase/decrease) the memory size of an
already allocated memory block using realloc() function.
 This process is called reallocation of memory e.g.
If the allocation was done using: 0 1 2 3 4
int *p; p 10 20 30 40 50
p = (int *) malloc(size);
0 1 2
Then reallocation may be done using: p 10 20 30
p = (int *) realloc(p, newsize);
 It allocates a new memory space of newsize and returns a
pointer to the first byte of the new memory block.
 It guarantees that old data will remain intact.
 If operation is unsuccessful then it returns NULL and the
original block is freed (lost).
CABSMJ-1001 [2024-25]
0 1 2 3 4
p 10 20 30 40 50

0 1 2 3 4 5 6
Note: 10 20 30 40 50 garbage
p

1. The new block may or may not begin at the same place as
the old one.
2. In case it is not able to find additional space in the same
region, it will create the new block in an entirely new
region and move the contents of the old block into the new
block.
3. It is necessary to test the success of reallocation operation
before proceeding further.
CABSMJ-1001 [2024-25]
0 1 2 3 4
Prob: a 1 2 3 4 5

 Write a C program that:


 allocates a storage block to store N1=5 integer values,
 stores first 5 natural numbers in it and
 prints their sum.

 Then the program:


 reallocates the storage block to store N2=10 integer
values,
 stores next 5 natural numbers in the new memory
locations and
 prints sum of all 10 numbers.
0 1 2 3 4 5 6 7 8 9
a 1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 CABSMJ-1001 [2024-25]
/* realloc1.c */ a 1 2 3 4 5
#include<stdio.h>
#include<stdlib.h>
#define N1 5 0 1 2 3 4 5 6 7 8 9
#define N2 10 a 1 2 3 4 5
main()
{ int *a, i, sum = 0;
a = (int *) malloc(N1*sizeof(int));
for (i=0; i<N1; i++)
{ a[i] = i+1; /* or *(a+i) */
printf("%d ",a[i]);
sum = sum + a[i];
}
printf("\nSum = %d\n",sum);
a = (int *) realloc(a, N2*sizeof(int)); /* reallocation of storage block */
Contd...
if ( a == NULL ) /* check the success of reallocation[2024-25]
CABSMJ-1001 */
{ printf("Reallocation failed");
exit(1); 0 1 2 3 4 5 6 7 8 9
} a 1 2 3 4 5 6 7 8 9 10
for (i=N1; i<N2; i++)
{ a[i] = i+1;
sum = sum + a[i]; /* adds new elements to sum */
}
for (i=0; i<N2; i++) /* prints all numbers */
printf("%d ",a[i]);
free(a); Output
printf("\nSum = %d",sum); 1 2 3 4 5
} Sum = 15
1 2 3 4 5 6 7 8 9 10
Sum = 55
0 1 2 3 4CABSMJ-1001
5 6 7 [2024-25]
8 9

Prob: str H Y D E R A B A D \n

 Given two strings "HYDERABAD" and "SECUNDERABAD". Write


a C program that:
 stores the first string "HYDERABAD" in a block of memory
created by malloc() and
 prints the string.

 Then it:
 modifies the size of the storage block to store the second
string "SECUNDERABAD",
 prints the contents of the modified storage block,
 stores the second string in the block and prints it.

0 1 2 3 4 5 6 7 8 9 10 11 12
str S E C U N D E R A B A D \0
/* realloc2.c */ 0 1 2 3 4CABSMJ-1001
5 6 7 [2024-25]
8 9
#include<stdio.h> str
H Y D E R A B A D \n
#include<stdlib.h>
#include<string.h>
main()
{ char *s1="HYDERABAD", *s2="SECUNDERABAD" ,*str;
int size = strlen(s1)+1, newsize = strlen(s2)+1;
str = (char *) malloc(size*sizeof(char));
if ( str == NULL )
{ printf("Memory allocation failed");
exit(1); 0 1 2 3 4 5 6 7 8 9 10 11 12
} str H Y D E R A B A D \0 garbage
strcpy(str,s1);
printf("str contains: %s\n",str);
str = (char *) realloc(str,newsize*sizeof(char));
if ( str == NULL )
{ printf("Memory allocation failed");
exit(1);
} Contd...
CABSMJ-1001 [2024-25]
printf("Size of str modified.\n");
printf("str still contains: %s\n",str); /* old conents are intact */
strcpy(str,s2);
printf("str now contains: %s\n",str);
}
0 1 2 3 4 5 6 7 8 9 10 11 12
str H Y D E R A B A D \0 garbage

0 1 2 3 4 5 6 7 8 9 10 11 12
str S E C U N D E R A B A D \0

Output
str contains: HYDERABAD
Size of str modified.
str still contains: HYDERABAD
str now contains: SECUNDERABAD
CABSMJ-1001 [2024-25]

File
Handling or
File Management
in C
CABSMJ-1001 [2024-25]

Important File Handling Functions Available in C Library


Function
name Operation
fopen() • To open an existing file for use or
• To create a new file.
fclose() To close an opened file.
fgetc() To read a character from a file.
fputc() To write a character into a file.
fscanf() To read a set of data values from a file.
fprintf() To write a set of data values to a file.
fgets() To read a string from a file.
fputs() To write a string to a file.
CABSMJ-1001 [2024-25]

Important File Handling Functions Available in C Library

Function Operation
name
fseek() To set the position to a desired point in the file.
ftell() Gives the current position in the file (in terms of
bytes from the start).
rewind() To set the position to the beginning of the file.
feof() To check whether eof (end-of-file) condition has
reached or not. It returns a non-zero (true) value
if file has reached to eof and zero otherwise.
ferror() To check whether an error has occurred on a file.
It returns a non-zero (true) value if error exists
and zero otherwise.
CABSMJ-1001 [2024-25]

Defining a File Pointer

 First of all, we have to create a communication link between


our program and the file that we want to use.

 For this, we have to declare a pointer to the data type FILE.

 FILE is a predefined data type (a structure defined in the I/O


library).

 General form to declare a FILE type pointer:

FILE *fp;  fp is a pointer of type FILE.


 It is used as a communication link between
the physical file and the program.
CABSMJ-1001 [2024-25]

Opening a File
 General form to declare a FILE type pointer and opening a file:

FILE *fp;
fp = fopen("filename", "mode");

 fopen() – opens the file in the specified mode & returns a


pointer associated with the named file. If the file couldn’t be
opened, a NULL value is returned.
 Pointer fp:
 contains all the info about the file,
 is subsequently used as a communication link between the
file and the program.
 "mode" specifies the purpose of opening this file.
CABSMJ-1001 [2024-25]

File Opening Modes

 Commonly used File opening modes are:

r To open an existing file for reading only.


 If file is opened successfully, file pointer points to the
first character in it.
 If file does not exist, NULL value is returned.
 Operations possible: reading from the file.
w To open a file for writing only.
 If file does not exist, a new file is created.
 If file already exists, its contents are deleted and the file
is opened as a new file.
 Operations possible: writing to the file.
CABSMJ-1001 [2024-25]

File Opening Modes

a To open a file for appending only.


 If file already exists, the file is opened with current
contents safe. The file pointer points to the last
character in it.
 If file does not exist, a new file is created.
 Operations possible: adding new contents at the end of
the file.

r+ To open a file for both reading and writing.


 If file is opened successfully, file pointer points to the
first character in it.
 If file doesn’t exist, NULL value is returned.
 Operations possible: reading existing contents,
modifying existing contents and writing new contents.
CABSMJ-1001 [2024-25]

File Opening Modes

w+ To open a file for both reading and writing.


 If file does not exist, a new file is created.
 If file already exists, its contents are deleted and the
file is opened as a new file.
 Operations possible: writing new contents, reading
them back and modifying them.
a+ To open a file for both reading and appending.
 If file does not exist, a new file is created.
 If file already exists, the file is opened with current
contents safe. The file pointer points to the first
character in it.
 Operations possible: reading existing contents,
appending new contents to the end of file.
 Cannot modify existing contents.
CABSMJ-1001 [2024-25]

Examples (File Opening)


Consider the following statements:
FILE *fp1, *fp2;
fp1 = fopen("input.txt", "r");
 fopen() opens the file input.txt to the beginning for reading.
 If file doesn’t exist, fopen() returns NULL.

fp2 = fopen("output.txt", "w");


 If output.txt already exists, its contents are deleted and the
file is opened as a new file,
 Otherwise fopen() creates a new file and opens it for writing.

 We can open and use a number of files at a time.


 This number, however, depends on the system we use.
CABSMJ-1001 [2024-25]

Closing a File

 fclose() function is used to close a file. Its general form:


fclose(fp);

 It would close the file associated with the FILE type pointer fp.

Note:
 A file must be closed as soon as all operations on it have been
completed.
 This ensures that:
 all outstanding information associated with the file is
flushed out from the buffers, and
 all links to the file are broken.
CABSMJ-1001 [2024-25]

fgets() and fputs() Library Functions

fgets(): Used to read a string from a file.

General form:
fgets(str, n, fp); /* char str[n]; */

 Reads a string str from the file pointed to by fp.

 It stops reading when:


 either n-1 characters are read,
 or newline character is reached, or the EOF is reached.
CABSMJ-1001 [2024-25]

fgets() – Example:

FILE *fp;
char text[81];
fp = fopen("input.txt", "r");
fgets( text, 81, fp );

 Above fgets() function call:


 will read at most 80 characters or until newline/EOF
character is reached,
 whichever is earlier.
CABSMJ-1001 [2024-25]

fputs() Function

General form:
fputs(str, fp);

 Writes the string str to the file pointed to by fp.

Example:
FILE *fp;
char text[81];
printf("Enter text (80 char Max)\n");
gets(text);
fp = fopen("output.txt", "w");
fputs(text, fp); /* It doesn’t auto adds a newline to the output */
CABSMJ-1001 [2024-25]

fgetc() and fputc() Functions


fgetc()
General form:
ch = fgetc(fp);
 Reads a single character from the file pointed to by fp.
 It returns the character read, if successful; otherwise returns
EOF.
Example:
FILE *fp;
char ch;
fp = fopen("intput.txt", "r");
ch = fgetc(fp);
CABSMJ-1001 [2024-25]

fputc() Function

General form:
fputc(ch, fp);

 Writes the character ch to the file pointed to by fp.

Example:
FILE *fp;
char ch;
printf("Enter a character: ");
ch = getchar();
fp = fopen("output.txt", "w");
fputc(ch,fp);
CABSMJ-1001 [2024-25]

fscanf() and fprintf() Functions


fscanf()
General form:
fscanf(fp,"format string", list);

 Reads the items in the list from the file pointed to by fp


(according to the specifications contained in the format string).
 Returns the no. of items that are successfully read. Returns EOF
when the end of file is reached.
Example:
FILE *fp; char itemname[21]; int itemqty;
fp = fopen("input.txt", "r");
fscanf(fp,"%s %d",itemname, &itemqty);
CABSMJ-1001 [2024-25]

fprintf() Function

General form:
fprintf(fp,"format string", list);

 Writes the items in the list in the file pointed to by fp


(according to the specifications contained in the format string).

Example:
FILE *fp;
char name[]="Asif Akhtar";
int age=20; float height=165.00;
fp = fopen("new.txt","w");
fprintf(fp,"%s %d %f", name, age, height);
CABSMJ-1001 [2024-25]

Prob:

Write a C program that reads few lines of text from the


keyboard until CTRL+Z (EOF character) is encountered and
writes it to the file "input.txt".
CABSMJ-1001 [2024-25]
Output
/* filehandl1.c */ Input few lines of text. To finish press CTRL+Z
#include<stdio.h> I am inputting some text.
It will be read by the program and
void main()
written into the specified file.
{ FILE *fp; ^Z
char ch;
printf("Input few lines of text. To finish press CTRL+Z\n");
fp = fopen("input.txt","w");
while( (ch=getchar()) != EOF )
{ fputc(ch,fp); Contents of input.txt file
}
fclose(fp);
}

File is saved in the same folder where programs are saved.


CABSMJ-1001 [2024-25]

Testing Whether File Has Been Opened Successfully?

File *fp; /* or two statements can be combined */


fp=fopen("input.txt","r"); File *fp;
if ( fp == NULL ) if ( (fp=fopen("input.txt","r")) == NULL )
{ printf("File could not be opened"); { printf("File could not be opened");
exit(1); exit(1);
} }
..... ......

exit() is a library function defined in stdlib.h:


 It causes an immediate termination of the current program and
transfers the control to the OS.
 Return value 1 indicates abnormal program termination.
CABSMJ-1001 [2024-25]

Prob:
Write a C program that:
 reads contents of a specified file (say, "input.txt")
 displays it on the screen and
 prints number of characters, number of sentences and
number of lines in the file.
/* filehandl2.c */ CABSMJ-1001 [2024-25]
Contents of input.txt file
#include<stdio.h>
#include<stdlib.h>
void main()
{ FILE *fp;
char ch, filename[31];
int nc=0, ns=0, nl=0;
printf("Enter filename: ");
gets(filename);
fp = fopen(filename,"r");
if (fp==NULL)
{ printf("File could not be opened...Exiting.");
exit(1); }
printf("Contents of file are:\n");
while( (ch=fgetc(fp)) != EOF ) /* fgetc() returns EOF when it reaches eof */
{ putchar(ch);
nc++;
if ( ch == '.' ) ns++; /* increment no. of sentences */
if ( ch == '\n') nl++; /* increment no. of lines */
} Contd...
CABSMJ-1001 [2024-25]

fclose(fp);
printf("\nNumber of characters= %d\n",nc);
printf("Number of sentences = %d\n",ns);
printf("Number of lines = %d\n",nl);
}
Output
Enter filename: input.txt
Contents of file are:
I am inputting some text.
It will be read by the program and
written into the specified file.
Number of characters= 94
Number of sentences = 2
Number of lines =3
CABSMJ-1001 [2024-25]

feof() and ferror() Library Functions

feof(fp)
 Used to test EOF (end of file) condition for the specified file.
 Returns a non-zero value, if eof has been reached; and returns
0 otherwise.
 Example:

if ( feof(fp) != 0 ) /* if ( feof(fp) ) */
printf("End of data\n");
CABSMJ-1001 [2024-25]

ferror() Function

ferror(fp)
 Used to test error status of the specified file.
 Returns a non-zero value, if an error has been detected
during reading from or writing to the specified file; and
returns 0 otherwise.
 Example:

if ( ferror(fp) != 0 ) /* if ( ferror(fp) ) */
printf("An error has occurred\n");
CABSMJ-1001 [2024-25]

Prob:
Write a C program that:
 Reads some integer numbers from the keyboard until
CTRL+Z is pressed and writes them in a file named
"intdata.txt".
 Then it reads them from the file "intdata.txt" and finds the
number of odd and number of even integers in the file.
CABSMJ-1001 [2024-25]
/* filehandl3.c */
#include<stdio.h>
#include<stdlib.h>
main()
{ FILE *fp;
int n;
int nodd=0, neven=0;
fp = fopen("intdata.txt","w");
printf("Enter some integer numbers (press ^Z in the end):\n");
while ( (scanf("%d",&n)) != EOF ) /* read until ^Z is encountered*/
{ fprintf(fp,"%d\n",n);
}
fclose(fp);
fp=fopen("intdata.txt","r");
if ( fp == NULL )
{ printf("File counld not be opened…Exiting");
exit(1);
} Contd...
/* or this while loop can be [2024-25]
CABSMJ-1001 written*/
while (1)
{ fscanf(fp,"%d",&n);
while( (fscanf(fp,"%d",&n)) != EOF ) if ( feof(fp)!=0 ) break;
{ if ( n%2 == 0 ) if (n%2 == 0)
neven++; neven++;
else nodd++; else nodd++;
} } /* feof() returns nonzero */
fclose(fp); /*when EOF has reached */
printf("Number of odd numbers = %d\n",nodd);
printf("Number of even numbers = %d\n",neven);
} Output
Enter some integer numbers (press ^Z in the end):
465436 54254 768 5463 86796
2341 46743 566 4653443 6877
^Z
Number of odd numbers = 5
Number of even numbers = 5
CABSMJ-1001 [2024-25]

Contents of intdata.txt file


CABSMJ-1001 [2024-25]

Prob:
Suppose "intdata2.txt" contains some integer numbers. Write a
C program that:
 reads some integer numbers from the keyboard until CTRL+Z
is pressed and
 appends them in this file.
CABSMJ-1001 [2024-25]
 If file already exists, the file is
/* filehandl3a.c */ opened with current contents
#include<stdio.h> safe.
main()  If file does not exist, a new file is
{ FILE *fp; created.
int n;  Operations possible: adding new
fp = fopen("intdata2.txt","a"); contents at the end of the file.
printf("Enter some integer numbers (press ^Z in the end):\n");
while ( (scanf("%d",&n)) != EOF )
{ fprintf(fp,"%d\n",n);
}
fclose(fp);
Output
}
Enter some integer numbers (press ^Z in the end):
5051 5052
5053
^Z
CABSMJ-1001 [2024-25]

Contents of intdata2.txt file


after appending 3 integers
CABSMJ-1001 [2024-25]

Random Access to Files


 So far we have been using the library functions that are:
 useful for reading & writing the data
 sequentially in the files.

 In some situations we are interested in accessing only a


particular part of a file and not interested in reading the other
parts.

 This can be achieved with the help of following library


functions:
1. fseek()
2. ftell()
3. rewind()
CABSMJ-1001 [2024-25]

fseek() Function
 Used to move the file position to a desired location within the
file. Note: Position of first byte in the file is 0.
General form: No. of bytes to be From the location
moved (long int) specified by position

fseek( fp, offset, position );

 +ve offset means move forward, and –ve means move backwards.
 Position can take one of the following 3 values:
Position Meaning
0 or SEEK_SET Beginning of file
1 or SEEK_CUR Current position
2 or SEEK_END End of file
CABSMJ-1001 [2024-25]
Note: If we attempt to move the file
position beyond the file boundaries, then
fseek() Function
an error occurs and fseek() returns -1.
 If operation is successful, it returns 0. If an error occurs, it
returns nonzero value.
 Examples of fseek() operations:
Statement Meaning
fseek(fp,0L,0); Go to the beginning of file - similar to rewind()
fseek(fp,0L,1); Stay at the current position (rarely used)
fseek(fp,0L,2); Go to the end of file (past the last character of the file)
fseek(fp,m,0); Move to mth byte from beginning
fseek(fp,m,1); Go forward by m bytes from current position
fseek(fp,-m,1); Go backwards by m bytes from current position
fseek(fp,-m,2); Go backwards by m bytes from the end
(positions the file to the mth character from the end)
CABSMJ-1001 [2024-25]

ftell() Function
 Used to find the current file position of the file.
General form:
long n = ftell(fp);

 It returns the current file position (a long type value) of the


specified file with respect to the starting of the file, e.g.
fseek(fp,3L,0); /* move the fp forward by 3 bytes from BOF */
printf("%ld",ftell(fp)); /* output = 3 */
 We can get the total size of a file as below:
fseek(fp,0L,2); /* move the fp to the end of file */
n = ftell(fp); /* will give the size of the file in bytes */
CABSMJ-1001 [2024-25]

rewind() Function
 Resets the file position of the specified file to the beginning
of the file.
General form:
rewind(fp);

 It can be used to read a file more than once, without having


to close and open the file.
 Example:
1. rewind(fp); /* move the position at the start of the file. */
2. n = ftell(fp); /* would assign 0 to n (first byte in the file */
/* is numbered as 0, second as 1, …. ) */
CABSMJ-1001 [2024-25]

Prob:

Write a C program that reads following decimal digits as char


data from the keyboard until newline character is encountered
and writes them in a file "random.txt".
0123456789
Then it reads "random.txt" file and
1. prints position of digits 0, 3, 6 and 9
2. reads and prints digits in reverse order.
CABSMJ-1001 [2024-25]
/* filehandl6.c */
#include<stdio.h>
#include<stdlib.h>
main()
{ FILE *fp;
char ch;
int i;
fp = fopen("random.txt","w");
printf("Enter digits 0 to 9 and press <ENTER>\n");
while ( (ch=getchar()) != '\n' )
{ fputc(ch,fp);
}
fclose(fp);
if ( (fp=fopen("random.txt","r")) == NULL)
{ printf("File could not be opened");
exit(1);
} Contd...
CABSMJ-1001 [2024-25]
printf("1. Print position of digits 0,3,6,9 in 0123456789\n");
for( i=0; i<4; i++ )
{ printf("Position of %c is %d\n",fgetc(fp),ftell(fp));
fseek(fp,2L,1); /* move 2 bytes forward from current position*/
}
printf("\n2. Read the digits in reverse order and print them\n");
fseek(fp,-1L,2); /* move 1 byte backwards from EOF */
do /* i.e. set the fp to the last digit (9) */
{ ch = fgetc(fp);
putchar(ch);
} while ( fseek(fp,-2L,1) == 0 );
/* fseek() returns 0 if operation is successful, nonzero otherwise */
fclose(fp);
}
CABSMJ-1001 [2024-25]

Output
Enter digits 0 to 9 and press <ENTER>
0123456789
1. Print position of digits 0,3,6,9 in 0123456789
Position of 0 is 0
Position of 3 is 3
Position of 6 is 6
Position of 9 is 9
2. Read the digits in reverse order and print them
9876543210
CABSMJ-1001 [2024-25]

Prob:
Suppose a file "customers1.txt" contains some records about
customers as per the following format:
custid int (5 digits)
name 30 chars
phone no. 15 chars
Write a program to add new customers in the file.
CABSMJ-1001 [2024-25]
/* filehandl7a.c */
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
main()
{ int custid;
char name[31], phone[16], ans;
FILE *fp;
while (1)
{ printf("\nEnter customer details to be added\n");
printf("Enter custid (5 digits) or Enter 0 to exit : ");
scanf("%d",&custid);
if ( custid == 0 )
exit(0); /* normal program termination */
fflush(stdin);
printf("Enter name (Max 30 chars): ");
gets(name);
Contd...
CABSMJ-1001 [2024-25]

printf("Enter phone no. (Max 15 chars): ");


gets(phone);
printf("Add above data? (y/n): ");
ans = getchar();
fflush(stdin);
if ( toupper(ans) == 'Y' )
{ if ( (fp = fopen("customers1.txt","a"))==NULL )
{ printf("File could not be opened…data not added");
exit(1); /* abnormal program termination */
}
fprintf(fp,"%5d%-30s%-15s\n",custid,name,phone);
fclose(fp);
printf("Data added...\n");
}
}
} /* end of main() */
CABSMJ-1001 [2024-25]
Output
Enter customer details to be added
Enter custid (5 digits) or Enter 0 to exit : 10004
Enter name (Max 30 chars): Shameem Ahmad
Enter phone no. (Max 15 chars): +918485671215
Add above data? (y/n): y
Data added...

Enter customer details to be added


Enter custid (5 digits) or Enter 0 to exit : 10005
Enter name (Max 30 chars): Javed Muneer
Enter phone no. (Max 15 chars): +919358853205
Add above data? (y/n): y
Data added...
Enter customer details to be added
Enter custid (5 digits) or Enter 0 to exit : 0
CABSMJ-1001 [2024-25]

File after adding two records


CABSMJ-1001 [2024-25]

Prob:
Write a program to update phone number of customers by
custid in the file "customers1.txt" which contains customers
data as per the following format:
custid int (5 digits)
name 30 chars
phone no. 15 chars
.
/* filehandl7b.c */ CABSMJ-1001 [2024-25]
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
main()
{ int custid, custid2;
char name[31], phone[16], newphone[16], update, nl, found;
FILE *fp;
while (1)
{ found = 'F';
printf("\nEnter custid (5 digits) whose phone number to be updated\n");
printf("or enter 0 to exit\n");
scanf("%d",&custid2);
if ( custid2 == 0 )
exit(0); /* normal program termination */
fflush(stdin);
if ( (fp = fopen("customers1.txt","r+"))==NULL )
{ printf("File could not be opened");
exit(1); /* abnormal program termination */
}
Contd...
while( (fscanf(fp,"%5d",&custid))!=EOF ) CABSMJ-1001 [2024-25]

{ fgets(name,31,fp); /* reads 31-1=30 characters */


fgets(phone,16,fp);
if ( custid == custid2 )
{ printf("%d %s %s\n",custid,name,phone);
found = 'T';
printf("Enter new phone number (Max 15 digits): ");
gets(newphone);
printf("Update phone number (y/n): ");
update = getchar();
fflush(stdin);
if ( toupper(update) == 'Y' )
{ fseek(fp,-15L,1); /* move file position 15 bytes backward */
fprintf(fp,"%-15s",newphone);
printf("Phone number updated...\n");
}
break;
}
nl = fgetc(fp);
} Contd...
CABSMJ-1001 [2024-25]

if ( found == 'F' )
printf("%d - not found\n",custid2);
fclose(fp);
} /* end of while (1) */
}
CABSMJ-1001 [2024-25]
Output
Enter custid (5 digits) whose phone number to be updated
or enter 0 to exit
10003
10003 Rashid Ali Khan +918743254765
Enter new phone number (Max 15 digits): +919358246255
Update phone number (y/n): y
Phone number updated...

Enter custid (5 digits) whose phone number to be updated


or enter 0 to exit
10005
10005 Javed Muneer +919358853205
Enter new phone number (Max 15 digits): +919358246256
Update phone number (y/n): y
Phone number updated...
Enter custid (5 digits) whose phone number to be updated
or enter 0 to exit
0
CABSMJ-1001 [2024-25]

File after updation


CABSMJ-1001 [2024-25]

The C
Preprocessor
CABSMJ-1001 [2024-25]

C Preprocessor

Source Expanded Object Executable


Preprocessor
code Compiler Linker
code code code
hello.c hello.obj hello.exe
Object codes of
other Library modules as needed
 C preprocessor - is a unique feature of C language that is not
available in other high-level languages.
 It is a system s/w that is used automatically by the C compiler to
process the source code before it is passed to the compiler.
 When we compile a C program:
 First the preprocessor processes the preprocessor directives
inserted in the source code & generates expanded code.
 Then this expanded source code is passed to the C compiler.
CABSMJ-1001 [2024-25]

C Preprocessor

Source Expanded Object Executable


Preprocessor
code Compiler Linker
code code code
hello.c hello.obj hello.exe
Object codes of
other Library modules
as needed

 C preprocessor performs preliminary operations like:


 macro substitution,
 Inclusion of files,
 conditionally compiling code etc.

specified by the preprocessor directives inserted/used in the


C source code.
CABSMJ-1001 [2024-25]

C Preprocessor Directives
 C Preprocessor directives:
 allow additional actions to be taken on the C source code
before it is compiled.
 begin with the # symbol in column-1 (don’t require a
semicolon at the end).
 Preprocessor directives are not part of the C language itself.
Commonly used preprocessor directives & their functions
Directive Function
1. Macro Substitution directives
#define Defines a macro substitution
#undef Undefines a previously defined macro
CABSMJ-1001 [2024-25]

Preprocessor Directives & Their Functions

Directive Function
2. File Inclusion directive
#include Specifies the file to be included
3. Compiler Control directives
#ifdef Tests for a macro definition
#ifndef Tests whether a macro is not defined
#if Used to test a compile-time condition
#else Specifies alternatives when #if test fails
#endif Specifies the end of #if
CABSMJ-1001 [2024-25]

1. Macro Substitution
 It is a process that provides a string substitution.
 It is achieved through #define preprocessor directive.

General form of macro definition (or simply a macro):


#define IDENTIFIER string

 If above macro is included in a program at the beginning, then


the preprocessor replaces every occurrence of the IDENTIFIER
in the source code by the string.
 There are 3 different forms of macro substitution:
(i). Simple Macro Substitution
(ii). Argumented “ “
(iii). Nested “ “
CABSMJ-1001 [2024-25]

(i). Simple Macro Substitution


 It is the most commonly used macro substitution.
 It is used to define symbolic constants.
 Examples: Symbolic constant
#define MAX 10 /*all occurrences of MAX are replaced by 10*/
#define PI 3.1415926
#define CAPITAL "DELHI"
 It is a convention to write macros in capitals to identify them
as symbolic constants.
2 lines of a C source code After preprocessing
total = MAX * value; total = 10 * value;
printf("MAX = %d\n", MAX); printf("MAX = %d\n", 10);
String is left unchanged
CABSMJ-1001 [2024-25]

(i) Simple Macro Substitution


 A macro definition may include expressions also:
 Examples:
#define AREA 5 * 12.45
#define SIZE sizeof(float)*4
#define TWO_PI 2 * 3.1415926

C Source code After preprocessing


#define A (78+32)
#define B (45-22)
........ ..........
printf("A/B = %d\n", A/B); printf("A/B = %d\n", (78+32)/(45-22);
Note: It is a wise practice to enclose the expressions within
parentheses to prevent an unexpected order of evaluation.
CABSMJ-1001 [2024-25]
#define STRING1 string2
(i). Simple Macro Substitution #define PI 3.1415926
 We have seen that in macro substitution, C preprocessor
performs a string substitution whenever the defined string
occurs in the C source code.
 So, we can use a macro to define almost anything, e.g.
C Source code After preprocessing
#include<stdio.h>
#define TEST if ( x<y )
#define AND . . . . . . . /* contents of stdio.h */
#define PRINT printf("Very Good"); . . . . . . . /* will be inserted here*/
main() main()
{ int x=10, y=20; { int x=10; y=20;
TEST AND PRINT if ( x<y ) printf("Very Good");
} }
CABSMJ-1001 [2024-25]

(i). Simple Macro Substitution


Example2:
C Source Code After preprocessing
/* preprocessor1.c */
#include<stdio.h>
#define PRINT main() . . . . . . . /* contents of */
#define FROM { int i; . . . . . . . /* stdio.h file */
#define ONE for(i=1; i<=10; i++) main() { int i;
#define TO { printf("%d ",i); } for(i=1; i<=10; i++)
#define TEN } { printf("%d ",i); }
PRINT FROM }
ONE
TO
TEN
CABSMJ-1001 [2024-25]

(ii). Argumented Macros (Macros with Arguments)


 are used to perform more complex and more useful form of
substitutions.
 They consist of a name followed by formal macro arguments.

A simple example:
#define CUBE(x) ((x)*(x)*(x)) /* use parentheses as shown*/
 If above macro is defined in a program then the preprocessor
would expand the following source code statements as:
C Source code After preprocessing
volume1= CUBE(side); volume1= ((side)*(side)*(side));
volume2= CUBE(a+b); volume2= ((a+b)*(a+b)*(a+b));
Known as macro calls
CABSMJ-1001 [2024-25]

(ii). Argumented Macros (Macros with Arguments)


 Examples of some commonly used macros with arguments
used in C programs:

#define MAX(a,b) ( ((a)>(b)) ? (a) : (b) )

#define MIN(a,b) ( ((a)<(b)) ? (a) : (b) )

#define ABS(x) ( ((x)>0) ? (x) : (-(x)) )

#define STREQ(s1,s2) ( strcmp((s1),(s2)) == 0 )

#define STRGT(s1,s2) ( strcmp((s1),(s2)) > 0 )


CABSMJ-1001 [2024-25]

Example (Argumented macros)


output
/* preprocessor7.c */
#include<stdio.h> str1 < str2
#define STREQ(s1,s2) ( strcmp((s1),(s2)) == 0 )
#define STRGT(s1,s2) ( strcmp((s1),(s2)) > 0 )
main() Program after preprocessing
{ char *str1="computer",*str2="science"; …………… /* contents of stdio.h file */
if STREQ(str1,str2) main()
printf("Strings are equal"); { char *str1="computer", *str2="science";
else if STRGT(str1,str2) if ( strcmp((str1),(str2)) == 0 )
printf("str1 > str2"); printf("Strings are equal");
else else if ( strcmp((str1),(str2)) > 0 )
printf("str1 < str2"); printf("str1 > str2");
} else
printf("str1 < str2");
}
CABSMJ-1001 [2024-25]

Prob:
Write a C program that implements an argumented macro
BIG(x,y) which compares x with y and returns bigger value.
Then the program finds biggest among three given integers a,
b and c using this macro with arguments.
CABSMJ-1001 [2024-25]

/* preprocessor2.c */
#include<stdio.h>
#define BIG(x,y) ( ((x)>(y)) ? (x) : (y) )
main()
{ int a, b, c, big;
printf("Enter 3 integer numbers\n"); /* or we can write */
scanf("%d %d %d",&a,&b,&c); big = BIG(a,b);
big = BIG(BIG(a,b),c); big = BIG(big,c);
printf("Biggest number is: %d\n",big);
}
CABSMJ-1001 [2024-25]

(iii). Nesting of Macros


 We can also use one macro in the definition of another macro.
 Preprocessor expands each defined macro, until no more
macros appear in the text.
Example1:
#define M 5
#define N (M+1) /* N is defined in terms of another macro M */

float value = N/2; /* consider this source code statement */

value = (M+1)/2; /* first macro N is expanded by the preprocessor */

value = (5+1)/2; /* then macro M is expanded by the preprocessor */


printf("%f",value); /* output: value = 3.000000 */
CABSMJ-1001 [2024-25]

(iii). Nesting of Macros


Example2:
#define SQUARE(x) ((x) * (x))
#define CUBE(x) (SQUARE(x) * (x))
#define SIXTH(x) ( CUBE(x) * CUBE(x) )

float value = SIXTH(2); /* consider this statement */

value = ( CUBE(2) * CUBE(2) ); /* First SIXTH(2) is expanded */

value = ( (SQUARE(2) * (2)) * (SQUARE(2) * (2)) ); /*then CUBE(2) */

value = ( (((2) * (2)) * (2)) * (((2) * (2)) * (2)) ); /* then SQUARE(2) */


printf("%f",value); /* output: value = 64.000000 */
CABSMJ-1001 [2024-25]

#undef Preprocessor Directive

 It is used to undefine a macro that was previously defined


using #define directive.

General form:
#undef IDENTIFIER

 It is useful when we want to restrict the macro definition to a


particular part of the program.
CABSMJ-1001 [2024-25]

Example (#undef Preprocessor Directive)


/* preprocessor3.c */
#include<stdio.h>
#define PI 3.14
#define R 5
float area1 = PI*(R*R);
#undef PI
#define PINEW 3.1415926
main()
{ float area2;
printf("Area of circle using PI is = %f\n",area1);
area2 = PINEW*(R*R); /* if we write PI here, [comp.error] PI undeclared */
printf("Area of circle using PINEW is = %f\n",area2);
}
CABSMJ-1001 [2024-25]

2. File Inclusion Directive ( #include directive)


 An external file containing functions, macro definitions etc.:
 can be included as a part of a program
 so that we need not rewrite those functions/macro definitions.

 This is achieved as below:

#include "filename" Preprocessor inserts entire contents of


the specified file into the source code at
#include<filename> the point where #include is written.

 #include "filename" - searches for the file - first in the current


directory and then in the standard directories.
 #include<filename> - searches for the file - only in the
standard directories.
CABSMJ-1001 [2024-25]

Example:
/* file2.c */
/* present in the current folder */ bigger.c (after preprocessing)
int big(int x, int y)
{ if ( x>y ) return x; . . . . . . . . /* contents of stdio.h */
else return y; int big(int x, int y)
} { if ( x>y ) return x;
else return y;
/* bigger.c */ }
#include<stdio.h> main()
#include "file2.c" { int x = 10, y = 20, big1;
main() big1 = big(x,y);
{ int x = 10, y = 20, big1; printf("Bigger value=%d",big1);
big1 = big(x,y); }
Output
printf("bigger value=%d",big1);
} Bigger value=20
CABSMJ-1001 [2024-25]

Prob:
Write a function max(int a[],int n) that returns maximum
element and a function min(int a[],int n) that returns
minimum element in the array and save them in a file, say
myfun.c
Then write a C program that includes the myfun.c file, reads n
integer values in a 1D array and finds biggest and smallest
using the max() and min() functions.
/* myfun.c */ CABSMJ-1001 [2024-25]

int max(int a[], int n) /* finds maximum array element */


{ int big, i;
big = a[0];
for(i=1; i<=(n-1); i++)
{ if ( a[i]>big )
big = a[i];
}
return big;
}
int min(int a[], int n) /* finds minimum array element */
{ int small, i;
small = a[0];
for(i=1; i<=(n-1); i++)
{ if ( a[i]<small )
small = a[i];
}
return small;
Contd...
}
CABSMJ-1001 [2024-25]
/* preprocessor4.c */
#include<stdio.h>
#include "myfun.c"
main()
{ int a[100], i, n, biggest, smallest;
printf("How many integers you want to input (1-100)?\n");
scanf("%d",&n); Output
for (i=0; i<n; i++) How many integers you
{ printf("Enter value-%d: ",i+1); want to input (1-100)?
scanf("%d",&a[i]); 5
} Enter value-1: 100
biggest = max(a,n); Enter value-2: 150
smallest = min(a,n); Enter value-3: 130
printf("Biggest= %d\n",biggest); Enter value-4: 180
printf("Smallest= %d\n",smallest); Enter value-5: 160
} Biggest= 180
Smallest= 100
CABSMJ-1001 [2024-25]

3. Compiler Control Directives


 These preprocessor directives are used to implement
conditional compilation.
 They enable to compile a specific portion of the program or
skip compilation of some specific part of the program based
on specified conditions. These are following six directives:
#ifdef Tests for a macro #ifdef MACRO_NAME
definition one/more statements;
#endif
#ifndef Tests whether a #ifndef MACRO_NAME
macro is not defined one/more statements;
#endif
#endif Specifies the end of
#if, #ifdef, #ifndef
CABSMJ-1001 [2024-25]

3. Compiler Control Directives (Contd….)


#if These directives #include<stdio.h>
#elif work together to #define AGE 18
#else control the main()
compilation of {
specific portions of #if AGE>=18
the program using printf("Eligible for vote");
specified #else
conditions. printf("Not eligible for vote");
#endif
}
........
Code after main()
preprocessing: {
printf("Eligible for vote");
}
CABSMJ-1001
/* mymacro.c */ [2024-25]
#define PI 3.1415926
Example-1 #define R 10

 Suppose we have included a file "mymacro.c" containing


some macro definitions in our program.
 It is not known whether a particular macro (say, PI) has been
defined in this file or not.
 However, we want to be certain that PI must be defined in
the file. If it is not defined in the file then we need to define it
in our program.
 Also we want to undefine macro R if it is already defined in
the file.
CABSMJ-1001
/* mymacro.c */ [2024-25]
#define PI 3.1415926
/* preprocessor5.c */
#include<stdio.h> #define R 10
#include "mymacro.c"
/* We want to ensure that PI must be defined */
#ifndef PI
#define PI 3.14
#endif
/* We want to undefine R, if it is already defined */
#ifdef R
#undef R
#endif
main()
{ float r;
printf("Enter radius: ");
scanf("%f",&r);
printf("Area of circle with radius %f is = %f\n",r,PI*r*r);
}
CABSMJ-1001 [2024-25]

Code after Preprocessing:

.......... . /* contents of stdio.h */


main()
{ float r; Value of PI substituted
printf("Enter radius: "); by the preprocessor
scanf("%f",&r);
printf("Area of circle with radius %f is = %f\n",r,3.1415926*r*r);
}
CABSMJ-1001 [2024-25]

Example-2
Write a C program to illustrate the use of compiler control
directives as below:
 Define a macro: #define WHICH_PART 1
 In the main(), test the value of WHICH_PART macro. If it is
equal to 1 then:
 one set of statements (that compute the area of a
rectangle) are compiled
 otherwise another set of statements (that compute the
volume of the rectangle) are compiled.
CABSMJ-1001 [2024-25]
/* preprocessor6.c illustrates conditional compiling of code */
#include<stdio.h>
#define WHICH_PART 1
main() Preprocessor will include this part
{ in the expanded code and it will be
compiled.
#if WHICH_PART==1
float l, b;
printf("Enter length and breadth of the room: "); Not included in
scanf("%f %f",&l, &b); the expanded
code and not
printf("Area of the room is = %f\n", l*b);
compiled.
#else
float l, b, h;
printf("Enter length, breadth and height of the room: ");
scanf("%f %f %f",&l, &b, &h);
printf("Volume of the room is = %f\n", l*b*h);
#endif
}
CABSMJ-1001 [2024-25]

Code after preprocessing:


/* preprocessor6.c */
............ /* contents of stdio.h */
main()
{
float l, b;
printf("Enter length and breadth of the room: ");
scanf("%f %f",&l, &b);
printf("Area of the room is = %f\n", l*b);
}
CABSMJ-1001 [2024-25]

Exercise #1.
Write a C program to find power of any given number (e.g. xn)
using recursion.
Exercise #2.
Write a C program to find sum of all odd numbers in given range
(for example, start=101 to end=120) using recursion.
Exercise #3.
Write a C program to find sum of all natural numbers between 1 to
n using recursion.
Exercise #4.
Write a C program that reads a positive integer n and counts the
number of digits in n using recursion.
Exercise #5.
Write a C program that reads a positive integer n and finds their
LCM using recursion.
CABSMJ-1001 [2024-25]

Exercise #6.
Write a C program that reads n integers in a 1D array (storage for
which is allocated using dynamic memory allocation) and prints
the mean (average) of the array elements.

Exercise #7.
Write a C program that reads n integers in a 1D array (storage for
which is allocated using dynamic memory allocation) and finds the
largest value using function.

Exercise #8.
Write a C program that reads the dimensions and elements of the
two matrices a and b for which memory is allocated dynamically
and finds their addition matrix c = a + b.
CABSMJ-1001 [2024-25]

Exercise #9.
Write symbolic constants for the binary arithmetic operators +, -, *
and /. Write a short program to illustrate the use of these symbolic
constatnts.

Exercise #10.
Define a macro ARGS that receives an integer array and the
number of elements in the array as function arguments. Write a
program that reads n integers in an array and computes the sum of
all elements of the array using function whose arguments are
ARGS.
CABSMJ-1001 [2024-25]
Exercise #11.
Write a C program that reads following data about fixed deposits
from the keyboard and appends it in a file named "fd.txt":
custid 10 chars
amount float (%10.2f)
rate float (%5.2f)
period (in years) float (%5.2f)
Exercise #12.
Write a C program that:
 reads input from the file named "fd.txt" (created by the previous
program):
 and displays a report showing final amounts to be paid to each
customer on maturity of his/her FD using the following formula:
Final amount = amount * ( 1+rate/100)years
FINAL AMOUNTS TO BE PAID ON MATURITY
Cust-id Amount Rate Period Final-amount
1234567891 100000.00 6.00 5.00 133822.52
1234567892 150000.00 5.00 2.00 165374.98
1234567893 200000.00 5.50 3.00 234848.23
CABSMJ-1001 [2024-25]

End of
Unit-IV

You might also like