Computer Programming
Computer Programming
Computer Programming
This is the second iteration of preparing our own courseware material, after successful
completion of a similar task undertaken a few years ago. These contents have been carefully
prepared and should serve as excellent auxiliary material for both instructors and students.
The Special Academic Group, Autonomy (SAGA) was formed for the sole purpose of
preparing courseware contents primarily in the first-year theory subjects; a few second-year
subjects were also included. The subjects for the first year were - Basic Electrical Engineering,
Basic Electronics Engineering, Computer Programming, Data Structures and Algorithms,
Engineering Mathematics I and II, Engineering Physics, Engineering Chemistry, Constitution
of India, Environmental Science and Engineering and Communicative and Technical English.
For the second year, the subjects for which courseware material was prepared were Analog
Electronic Circuits, Digital Systems Design, Circuit Theory and Measurements and
Instruments.
Faculty members from all the departments contributed to the task. They were, in no particular
order, Nalini Singh, Bimal Meher, Saumyaranjan Dash, Mukti Routray, Susmita Biswal,
Manasa Dash, Bipin Tripathy, Sibasankar Nayak, Janmejay Senapati, Subrat Sahu, Pradeep
Moharana, Rupambika Pattanaik, Dhananjay Tripathy, Jagadish Patra, Sachin Das, Deepak
Ranjan Nayak, Amulya Roul, Bodhisattva Dash, Sanghamitra Das, Gyana Ranjan Biswal,
Nibedita Swain and Rajan Mishra.
The entire group worked diligently to successfully complete the task which included a peer
review of the material. I take this opportunity to thank all the members of the SAGA group for
a job well done.
I sincerely hope that this courseware material comes in handy and is utilized to the fullest
extent. These are readily available additional resources prepared in accordance with the Silicon
autonomy syllabus, to complement textbooks and classroom lectures. If there are any errors, I
would be grateful if they are brought to my notice so that we can correct them in subsequent
versions.
Computer
A computer is an electronic device, operating under the control of instructions stored in its
own memory that can accept data (input), process the data according to specified rules,
produce information (output), and store the information for future use.
Computer Components
A modern computer consists of hardware and software.
Hardware
Computer hardware is the collection of physical devices that constitute a computer system. It
refers to the input devices such as mouse, keyboard; output devices such as monitor, printer;
memory devices like primary and secondary storage, system units (graphic cards, sound cards,
motherboard and chips), and central processing unit (CPU).
Input Device
An input device provides data and control signals to a computer system. It translates data
from a form that human understands to a form that the computer can understand. Most
common input devices are keyboard and mouse.
Output device
An output device is used to communicate the results of data processing carried out by the
computer to the human. It converts the electronically generated data into human-readable
form.
A CPU is the brain of a computer. It carries out the instructions of a computer program by
performing the basic arithmetic, logic, control, and input/output (I/O) operations specified by
the instructions.
Arithmetic Logic Unit (ALU): It is a digital circuit used to perform arithmetic and logic
operations. It represents the fundamental building block of the central processing unit (CPU)
of a computer. Modern CPUs contain very powerful and complex ALUs.
Control Unit (CU): It controls and co-ordinates different computer components. A brief list
of its functioning is given below:
1. Read the code for the next instruction to be executed.
2. Increment the program counter so it points to the next instruction.
3. Read whatever data the instruction requires from memory cells.
4. Provide the necessary data to an ALU or CPU register.
5. If the instruction requires an ALU or specialized hardware to complete, instruct the
hardware to perform the requested operation.
Registers: Processor registers are normally at the top of the memory hierarchy, and provide
the fastest way to access data into the processor. Registers get data from primary memory
which is slower devices. So, it helps to reduce the speed mismatch between CPU and
memory. There may be a no. of registers inside the CPU depending on the processor
architecture.
Memory Devices
Primary Memory
1. RAM: Random Access Memory (RAM) is a memory scheme within the computer system
responsible for storing data on a temporary basis, so that it can be promptly accessed by the
processor as and when needed. It is volatile in nature, which means that data will be erased
once supply to the storage device is turned off. RAM stores data randomly and the processor
accesses these data randomly from the RAM storage. RAM is considered "random access"
because you can access any memory cell directly if you know the row and column that
intersect at that cell.
2. ROM (Read Only Memory): ROM is a permanent form of storage. ROM stays active
regardless of whether power supply to it is turned on or off. ROM devices do not allow data
stored on them to be modified.
Secondary Memory
Secondary Memory stores data and programs permanently even after the power is turned
off.
1. Hard Disk Drive (HDD): A hard disk stores and provides relatively quick access to large
amounts of data on an electromagnetically charged surface or set of surfaces.
2. Optical Disk: An optical disc drive (ODD) is a disk drive that uses laser light as part of the
process of reading or writing data to or from optical discs. Compact discs, DVDs, and Blu -ray
discs are common types of optical media which can be read and recorded by such drives.
Machine Language
It consists of binary number 0s and 1s which are readable by the digital computer. It is the 1 st
generation language.
Assembly Language
It is the 2nd generation language which consists of English like phrases called mnemonics e.g.
ADD is used for addition. Assembly Language is not readable by computer directly; hence
assembler is used to convert from Assembly Language to Machine Language.
High level Language
It is the 3rd generation language which is very similar to English like languages. Languages like
C, C++, FORTRAN, COBOL, BASIC, PASCAL, Java etc. comes under it. High level Language is also
not readable by computer, so compiler is used to convert from High level Language to
computer readable Language.
Operating System
The operating system (OS) is the most important program that runs on a computer. Every
general-purpose computer must have an operating system to run other programs
and applications. Computer operating systems perform basic tasks, such as recognizing input
from the keyboard, sending output to the display screen, keeping track of files and directories
on the storage drives, and controlling peripheral devices, such as printers.
For large systems, the operating system has even greater responsibilities and powers. It is like
a traffic cop — it makes sure that different programs and users running at the same time do
not interfere with each other. The operating system is also responsible for security, ensuring
that unauthorized users do not access the system.
Operating systems provide a software platform on top of which other programs,
called application programs, can run. The application programs must be written to run on top
of a particular operating system. The choice of operating system, therefore, determines to a
great extent the applications you can run. For desktops/laptops, the most popular operating
systems are Windows and Linux.
Compiler: It is a translator which translates High level Language program to Low level
language (assembly Language or machine language) code for execution.
Assembler: It is a translator program used to convert assembly language code to machine
language code.
Linker: A linker is a program which links another precompiled object file or library and creates
the executable file.
Loader: A loader is a program which loads the executable program into primary memory called
RAM for execution.
Preprocessor: The main job of a C preprocessor is to process some of the statements like
inclusion of header files, macro expansions, and conditional compilation before the actual
compilation by the compiler starts. Such statements starts with a # (called hash) symbol. For
example, if a statement is given as # include <stdio.h>, the preprocessor replaces the line
#include <stdio.h> with the text of the file 'stdio.h', which declares the printf() function among
other things. Sometimes it is also written as # include “stdio.h”. If the filename is enclosed
within angled brackets, the file is searched for in the standard compiler include paths. If the
filename is enclosed within double quotes, the search path is expanded to include the current
source directory.
Compiler Interpreter
Reads the program one line at a time and
Reads entire program and converts to object code
converts to object code
It takes more time to analyze the code but
Execution is slower than compiler
execution is faster
Generates intermediate object code which furtherNo intermediate object code is generated,
requires linking, hence requires more memory. hence are memory efficient.
Algorithm
A. Definiteness
B. Finiteness
C. Input & Output
D. Effectiveness
Example 1: Write an algorithm to find the area of a rectangle by taking its width and length.
Algorithm
Step1: Input W and L
Step2: Compute A = W*L
Step3: Print A
Step4: Exit
Algorithm
Step1: Input num1 and num2
Step2: Compute sum= num1+num2
Step3: Print sum
Step4: Exit
Pseudo-code
It is an informal way of writing an algorithm or program in human readable form. As the name
suggests, it may not follow the exact syntax of any programming language. Therefore, a
machine directly can’t be able to understand it. Programmers may also start a project by
sketching out the code in pseudo-code on paper before writing it in its actual high-level
language for better understanding of the problem/algorithm.
Flowchart
Start/Stop
Input/output
Process
Decision
Control Flow
Example1: Draw the flow chart to find out the area of a rectangle
Start
by taking its width and length.
Input W &
L
A=W*L
Print A
Example 2: Draw a flowchart for finding the sum of two numbers. Stop
Start
sum=num1+num2
Print sum
Stop
Example 3: Write an algorithm to read two numbers and
find the greater one. Draw the flow chart for this algorithm. Start
Algorithm
Step1: Input num1 and num
Step2: If num1 > num2 Input num1 & num2
greater=num1
Else True False
num1>num
greater=num2 2
Step3: Print greater
greater=num1 greater=num2
Step 4: Exit
Print greater
Stop
Example 4: Write an algorithm to compute the greatest among three inputted numbers.
Draw the flowchart for this algorithm.
Algorithm
Step 1: Enter any three numbers a, b, and c
Assignments
Write algorithms and draw flowcharts for the following problems:
1. To calculate the simple interest for an amount deposited in a Bank.
2. Input a number and check whether it is even or odd.
3. To calculate the sum of first ten numbers.
Structure of a C Program
C is a programming language developed at AT & T’s Bell Laboratories of USA in 1972. It was
written by Brian Kernighan and Denis Ritchie. This was to be the1st language that Unix was
written to be the first portable language. BCPL was used for writing OS and compiler and
developed in 1967 by Martin Richards used for creating early versions of UNIX OS by Ken
Thompson in 1970.
Dialects of C:
1. Common C
2. ANSI C (American National Standard Institute)
The main function is the part of ever C program. ‘( ) ‘ is the symbol of a function that distinguish
from other names. This symbol ( ) is used to pass input to the function. Here it is not taking
any input. We may specify void also inside the ( ) .
Overview of a C program
Documentation Section contains comment line
Link Section links to system library
Definition Section Define symbolic constant
Global Declaration Section contains global variable that can be
used by more than one functions
main()
{
Declaration Part It is a mandatory function that all
Executable Part programs must contain
}
Character set
Alphabets : A to Z ,a to z
Digits: 0 to 9
Special Smbols :- ~ ‘ ! @ # % ^ & * ( ) _ - + = | \ { }
[ ] : ; " ' < > , . ? /
Keywords
Keywords are the reserve words whose meaning has already been defined to the C compiler.
These are reserved for doing a specific task. There are 32 keywords in C compiler.
Identifiers
These are user defined words which are used to give names to variable, function, array and
structure. Rules for an identifier are given below:
1. The first character must be an alphabet or underscore.
2. Keywords can’t be used as an identifier.
3. Case-sensitive.
4. Special characters (except underscore) can’t be used.
Constants
A constant is an entity whose value doesn’t change during the program execution. C constants
can be divided into two major categories:
1. Primary Constants
2. Secondary Constants
Primary constants: Integer, Real/Float, Character, String
Secondary Constants: Array, Pointer, Structure, Union, Enum
At this stage we would restrict our discussion to only Primary Constants, namely, Integer,
Real and Character constants.
Integer Constants
Numbers without decimal point are integers. Rules for Constructing Integer Constants :
1. It must not have a decimal point.
2. It can be either positive or negative.
3. If no sign precedes an integer constant it is assumed to be positive.
4. No commas or blanks are allowed within an integer constant.
Example:
465
-323
Real Constants
Numbers having decimal point are real/float constants. It could be written in two forms.
Floating Constants
Example:
325.5
-465.6
Exponential Constants
It is usually used if the value of the constant is either too small or too large. Here real constant
is represented in two parts, the part appearing before ‘e’ is called mantissa and the part
following ‘e’ is called exponent
Mantissa e exponent
Example :
3.2 e 5
-4.5 e -7
Character Constants
A character constant is a single character from the C character set that enclosed within single
inverted commas.
Example :
‘ A’
‘$’
‘5’
‘=’
String Constants: It is sequence of characters enclosed within double quotes.
Example:
“Silicon”
“1st. Sem. B.Tech”
Variables
Variable names are the names given to the locations in the memory. These locations can
contain integer, real or character constants. In other word, a variable is a named container
which contains constant values. The values stored in the variables can be changed.
Example :
_sal
Si_int
Area
Num
Data-type
A datatype is a set of values and set of operations that are permitted to apply on those values.
It is used to specify the type of values a variable can contain in memory. It als o specifis the
range of values a variable can take. Some basic data type int, float, char.
If a variable is required to contain an integer value then it should be specify to be ‘int’ type.
Similarly if a variable is required to contain a floating point value then it should be specify to
be ‘float’ type.
Specifying the type of data a variable can contain is called declaration of a variable. The rule
(syntax) to declare a variable is as follows.
Syntax:
datatype variable_list ;
Here datatype can be any one from the list of datatype and the variable list can be any number
of identifier separated by comma (,).
Example1:
int x ; Here x is called an integer variable which can store integer values.
Example2:
int x , y , z; Here x, y, z are integer variables which can store integer values.
A variable can contain only one value but the value must belong to a specific set of values
which is called the range of the datatype. The range of datatype depends on the predefined
size of it. The size of a datatype determines the no of bytes a variable occupies in memory.
There are two types of integer variable signed integer (contains both +ve and –ve numbers)
and unsigned integer (contains only +ve numbers). Hence the number range change
accordingly. Here signed and unsigned are called qualifiers. Here int, char, float, signed,
unsigned are belongs to the 32 keywords in C.
The range of a variable is calculated from its size. Let’s declare an integer variable x as follows.
int x;
Here x is a signed integer. The default sign qualifier of a variable is signed. Its range is -232 to
232 – 1. Here 16 is the no of bits the variable occupy. To calculate the range of integer and
character datatype, we use the following formula.
The size and range of all types of data type is given in the following table.
Operators in C
An operator is a symbol that tells the computer what kind of operation to be carried
out on the given operands (data). The operators can be broadly classified as unary, binary or
ternary depending on the number of operands (i.e. one, two or three respectively) they take.
In C language, there are sixteen different types of operators defined with the compiler. Let us
discuss some of them which are commonly used for writing programs.
1. Arithmetic Operators
2. Relational Operators
3. Logical Operators
4. Assignment Operators
5. Conditional Operators
6. Increment / Decrement Operators
7. Bitwise Operators
8. sizeof Operators
9. Comma Operators
Arithmetic Operators
Assignment operator ( = )
This operator is used to assign a value to a variable. It can be done during the variable
declaration or after the declaration when there is a need in any part of the program.
Syntax:
<Variable name> = <constant>
Example:
int x ; assignment after declaration
x=5;
For character variable assignment, the character should be enclosed within single quote as
follows.
ii. int x = 5, y =6 , z;
z=x+y; Here value of z is 11
iii. int x = 5;
float y =5.5 , z ;
z=x+y; Here value of z is 10.5
Arithmetic statement
A C arithmetic instruction consists of a variable name on the left-hand side of = and variable
names & constants on the right-hand side of =. The variables and constants appearing on the
right-hand side of = are connected by arithmetic operators.
Relational Operators
Relational Operators are used to compare two expressions which give either TRUE (1) or FALSE
(0) value. There are six relational operators in C. They are < , > , <= , >= , = =, != . Operator = =
is called ‘equal to’ operator which is used to compare the equality of two expression.
Example:
int x=5 , y=6, z;
z=x<y;
Here the value of Z is 1 as x<y is true.
z = x= =5;
Here the value of Z is 1 as x==5 is true.
All relational operators have lower precedence from arithmetic operators.
Logical Operators
Logical operators are used to combine the true or false value of expressions. There are three
logical operators && , ||, !.
If one of the two expressions i.e. either expr1 or expr2 has false value then x is false . So if
expr1 has false value then expr2 will not be evaluated.
OR Operator ( || )
x= expr1 || expr2
If one of the two expression i.e. either expr1 or expr2 has true value then x is true. So if expr1
has true value then expr2 will not be evaluated.
Not Operator ( ! )
x= ! expr1
If expr1 has false value then x is true and If expr1 has true value then x is false.
Except the ! (NOT) operator both && and || have lower precedence than Logical operators.
Increment operator ++
It is an unary Operator. It increases the operand value by one. Two variants are there i.e.
postfix and prefix. In case of postfix, the operator is placed after the operand, where the value
of operand is assigned to the LHS variable first then the operand is incre mented. In case of
prefix the operator is placed before the operand, where the value of operand is incremented
first then the incremented operand value is assigned to the LHS variable.
Example:
x
int x=5 , y ; 5
x++ ; 6
x y
Now, let us take y = x++;
7 6
Here value of x (i.e. 6) is assigned to y first then x is increased by one as shown above.
x
Then let us take only ++x ;
8
Here the value of x is changed from 7 to 8 as shown above.
x y
Now let us take y = ++x ; 9 9
Here value of x (i.e. 8) is increased by one first then x is assigned to y. So, both the values are
9 as sown above.
Decrement Operator ( - - )
It is similar to the ++ operator but only difference is that, it decreases the operand value by
one. Two variants are there postfix and prefix. In case of postfix the operator is placed after
the operand, where the value of operand is assigned to the LHS variable first then the operand
is decremented. In case of prefix the operator is placed before the operand, where the value
of operand is decremented first then the decremented operand is assigned to the LHS
variable.
Example:
x
int x = 5, y ; 5
x--; 4
Here the value of x is changed to 4.
x y
Now let us take y = x - -;
3 4
Here value of x (i.e. 4) is assigned to y first then x is decreased by one. So x becomes 3 as
shown above.
x
Now consider - -x ;
2
++ and - - operator are unary operators. They have right to left associativity and have higher
precedence over arithmetic operators.
Conditional Operator (? :)
The whole expression can returns value which can be assigned to a variable x as follows:
x= expr1 ? expr2 : expr3
Explanation: The value of x depends on the true and false value of expr1. If expr1 value is true
then x will have the value of expr2. If expr1 value is false then x will have the value of expr3.
Example:
int x=2, y=3, z;
z= x>y ? x : y;
We can also assign the value to z in the true and false part of conditional operator as follows:
Bitwise operators
These operators work on a bit by bit basis on the operands. The operators are follows.
Op Operator Name Rule Type
& AND Anyone 0 is 0 Binary
| OR Anyone 1 is 1 Binary
~ NOT If 1 then 0 ,If 0 then 1 Unary
^ Ex-OR If both are 0 or both are 1 then 0 else 1 Binary
>> Right shift rightmost digit was shifted out and a new 0 was Binary
shifted into the rightmost position
<< Left shift leftmost digit was shifted out and a new 0 was Binary
shifted into the rightmost position
Example:
5= 101 in binary
4= 100 in binary
&
----------------
100 in binary whose decimal equivalent is 4
The value of z is 4.
Or operator ( I )
int x = 5, y = 4, z;
z= x y;
5= 101 in binary
4= 100 in inary
|
----------------
101 in binary whose decimal equivalent is 5
The value of z is 5.
EX-OR operator ( ^ )
int x = 5, y = 4, z;
z= x ^ y;
5= 101 in binary
4= 100 in binary
^
----------------
001 in binary whose decimal equivalent is 1
The value of z is 1.
NOT operator ( ~ ) Its an unary operator.
int x = 5 , y ;
y = ~ x;
5= 101 in binary
~
----------------
010 in binary whose decimal equivalent is 2
The value of z is 2.
int x = 23,y = 1 , z;
z= x << y ;
int x = 23, y = 1, z;
z= x << y ;
It is an unary operator. It returns the size of its operand in terms of byte. The operand can be
a variable, constant or any datatype.
Example :
int x=5 , y ;
y= sizeof(x) ;
Here the value of y is 4 ( Since x is an int variable , its memory requirement is 4
bytes).
Comma Operator
It has the Lowest Precedence than all operators. It returns the value of the rightmost operand
when multiple comma operators are used inside an expression. Comma Operator Can acts as
–
Example:
int x;
x= 1,2,3;
int x;
x=(1,2,3);
Here value of x is 3 as Bracket has highest priority and Associativity from Left to Right and
return Right most operand.
Compound assignment operators provide a shorter syntax for assigning the result of an
arithmetic or bitwise operator. They perform the operation on the two operands before
assigning the result to the first operand. There are eleven compound assignment operators
which are as follows.
Operators Equivalent to
y += x y = y+x
y -= x y = y-x
y *= x y = y*x
y /= x y = y/x
y %= x y = y%x
y &= x y = y&x
y |= x y = y|x
y ^= x y = y^x
y <<= x y = y<<x
y >>= x y = y>>x
Typecast operator
It is used to convert the datatype of an operand from one type to another type explicitly by
the programmer. It is an unary operator. Its format is as follows.
i. Left-to-right ( evaluation done from left side operator to right side operator)
ii. Right-to-left ( evaluation done from right side operator to left side operator)
Type Conversion
It is used to convert the datatype of an operand from one type to another type. It is of two
types:
When a C-expression is evaluated, the resulting value has particular data type. If all the
operands in the expression are of same type, the resulting type is of same type as well. If both
x and y are of int type, the expression x+y is of int type. If the operands of an expression is of
different type then type of expression is of largest size data type present in the expression.
Evaluating expression a/b causes a to converted float type before expression is evaluated. This
does not mean that type of variable is changed. The value of expression is float type. This type
of automatic conversion is known as implicit type conversion. If operands are of different
types the lower type is automatically converted to higher type before the operation takes
place. This type of conversion is known as implicit type conversion.
Example :
char c;
int j;
float f;
double d, r;
r= (c * j) + (f / j) - (f + d) ;
In the above the above example before c is multiplied with j first c implicitly converted to
integer. Similarly j implicitly converted to float before division with j. Similarly f implicitly
converted to double before addition.
But in assignment expression, the type of expression is the type of left hand side operator. If
in the assignment expression two operator may not be of same type, In such case value of
right hand side expression is promoted or demoted depending on type of variable on left
hand side of =.
int i, j;
float f;
i=12;
j=5;
f= i / j; // f=2.000000
Thus while storing the value of an expression always takes type of variable into which its value
is being stored.
main( )
{
float ctemp, ftemp;
printf (“Enter temperature in centigrade”);
scanf(“%f” , &ctemp);
ftemp= 9.0 / 5 * ctemp +32; // 9/5=1 not 1.8 but 9.0/5=1.8
printf(“temperature in farenahite=%f”,ftemp);
}
Output:
Enter temperature in centigrade 70
temperature in Fahrenheit =158
Type conversion also can be done by programmer not by compiler. If the type co nversion is
done by programmer is called explicit type conversion. To convert an expression to a particular
data type expression must be preceded by the name of desired data type enclosed in
parenthesis i.e
float f=5.5;
((int)f)%2;
float a=7,b=4;
(a+b)%2 ; //(wrong) because % operator takes only integer arguments
((int)(a+b))%2; //(right)
main( )
{
int input1,input2,sum;
float avg;
printf(“Enter two number”);
scanf(“%d%d”,&input1,&input2);
sum= input1+input2;
avg= ((float) (a+b)) / 2;
printf(“Sum=%d\n average=%f”,sum,avg);
}
Output:
Enter two number 3 4
Sum=7
Average=3.5
MODULE – 2
Decision making and branching - if, if-else
Decision making structures require that the programmer specifies one or more
conditions to be evaluated or tested by the program, along with a statement or statements to
be executed if the condition is determined to be true, and optionally, other statements to be
executed if the condition is determined to be false.
if statement:
Branching:
1. if statement
2. if-else statement
3. nested if statement
4. if-else-if statement (else-if ladder)
expr True
Stmts
False
Next statement
after if block
The expression following keyword if must be enclosed in parenthesis. If the value of the
expression expr is true (that is non zero) statement in if block (stmt T) will be executed. If the
value of the expression expr is false (that is zero) then statement in if block (stmt T) will be
ignored. The stmt T can be simple or compound statement. If stmt T is compound statement
then it must be enclosed within braces. Next statement will be executed if the condition is
true or false.
#include<stdio.h>
int main( )
{
int input;
printf(“Enter a number ”);
scanf(“%d”,&input);
if (input%3= =0) //no semicolon
printf(“%d is divisible by 3\n”,input);
printf(“Thanks for using this program”); //next statement after if block
}
o/p-
Enter a number 6
3 is divisible by 3
Thanks for using this program
Example: Find the output of the following code:
int main( )
{
int input;
printf(“Enter a number\n”);
scanf(“%d”,&input);
if(input= =5) ; // no error
printf(“\n You have entered 5”);
}
OUTPUT-
Enter a number 10
You have entered 5
Explanation: Irrespective of whether condition is true or false, 2nd printf statement is bound
to execute. Here the condition of the “if” statement is true. So null statement (;) gets executed
which does nothing on execution.
if -else statement (two way decision)
“if- else” statement can execute one group of statements. When the ‘if’ condition is true, a block
of statements are executed and the else part is totally skipped. And when the condition is found
false, if part is skipped and else part will be executed.
Syntax of if-else statement:
if (expr)
stmt T1 ;
else
stmt T2 ;
False True
Exprn
If the expr has non zero value (expr is true) then stmt T1 will be executed otherwise (expr is
false) stmt T2 will be executed. Do not give semicolon at the end of if ( ) or else .
#include<stdio.h>
main( )
{
int input;
printf(“Enter a number ”);
scanf(“%d”,&input);
if (input%2= =0) //no semicolon
printf(“%d is even number”,input);
else //no semicolon
printf(“%d is odd number”,input);
printf(“Thanks for using this program”); //next statement after if –else block
}
OUTPUT:
Enter a number
5
5 is odd number
Thanks for using this program
Example: Program to calculate the gross salary of an employee. If basic < 1500 then HRA =
75% of the basic, DA = 80 % of the basic. Otherwise HRA =85% of the basic, DA = 87% of the
basic.
main( )
{
int basic;
float da,hra,gross;
printf(“Enter basic salary of the employee ”);
scanf(“%d”,&basic);
if (basic<1500) //no semicolon
{
da=0.87*basic;
hra=0.75*basic;
}
else //condition for else block to execute basic>=1500
{
da=0.80*basic;
hra=0.85*basic;
}
gross=basic+da+hra; //next statement of if –else block
printf(“Gross Salary=%f”,gross);
printf(“Thanks for using this program”);
}
OUTPUT:
Enter basic salary of the employee 5000
Gross salary=16100
Thanks for using this program
#include<stdio.h>
main()
{
int input1=10,input2 = 25;
if (input1=input2)
printf(“Equal\n”);
else //no semicolon
printf(“Not Equal\n”);
printf(“Thanks for using this program”); //next statement after if –else
block
}
OUTPUT- Equal
Thanks for using this program
As the value of the expression input1=input2 is 25 which is non zero value means that
expression is true. So if block is executed. Here we are not comparing the values of input1 and
input2 rather the assignment operator ( = ) will assign value of input2 to input1.
Point to noted- It is not mandatory to have else block for if block. But else block is always
preceded by if block.
Nested if-else
When a series of decision is required, nested if-else is used. Nesting means using one
if-else construct within another one. We can define an ‘if’ block or an ‘else’ block within the
body of another ‘if’ block or else block.
It is also possible that both if block and else block can be nested.
return 0;
}
Syntax of if-else-if :
if ( expr1)
stmt t1;
else if ( expr2)
stmt t2;
........
else if (expr n)
stmt tn;
else
stmt f;
Expression expr1 is evaluated first if it true then statement stmt t1 is executed. If it is false
expr2 is evaluated, if it is true stmt t2 is executed and so on. If none of the expression (1 to n)
is true then stmt f is executed. The expr is evaluated in order. If any expr is t rue the stmt
associated with it is executed and this terminates the whole chain. The last else part is
executed when none of the above case is satisfied.
Output 3:
Please type in a number: -10
Sign = -1
Press any key to continue . .
Example: WAP to print the grade of a student by inputting marks of 3 subjects through the
keyboard. Full mark for each subject is 100. Grade is calculated as follows:
Grade O if avg mark >=90
E if avg mark >=80
A if avg mark >=70
B if avg mark >=60
C if avg mark >=50
D if avg mark >=40
F for others.
Use else-if ladder in your program.
#include<stdio.h>
main( )
{
int sub1,sub2,sub3;
int avg;
printf(“Enter marks in 3 subject”);
scanf(“%d%d%d%d”,&sub1,&sub2,&sub3);
avg = (sub1+sub2+sub3) / 3;
printf(“Average=%d\n”,avg);
if(avg >= 90)
printf(“O Grade”);
else if(avg >= 80)
printf(“E Grade”);
else if(avg >= 70)
printf(“A Grade”);
else if(avg >= 60)
printf(“B Grade”);
else if(avg >= 50)
printf(“C grade”);
else if(avg >= 40)
printf(“D Grade”);
else
printf(“F grade”);
}
OUTPUT-
Enter marks in 3 subjects
80 98 91
Average=89
E grade
switch (expression)
{
case expr1:
stmt t11;
stmt t12;
..
case expr2:
stmt t21;
stmt t22;
....
...........
case expr n:
stmt tn1;
stmt tn2;
....
...........
default:
Stmt tn1;
.......
}
Here switch, case and default are the keywords.
The expression following keyword switch must evaluate to an integer value. The expression
may also be character type because each character has equivalent integer value. First
statement of each group must be preceded by one case label.
The case label identify different group of statements and distinguish them from one another.
So the case label must be unique within a switch statement. The case label must be followed
by semicolon. The case label must represent constant integer valued expres sion. Each
individual group following the case label may be simple or complex.
When switch statement is executed the expression is evaluated and control is transferred to
group of statement whose case label matches with the value of the expression.
When a match is found execution start from that case and all the subsequent case and default
as well. If none of the case label matches the statement under default case is executed. The
default part is optional in switch statement. If no default case is used and none of the case
label is matched, then control is transferred directly to the next statement after switch. Curly
brackets are not necessary to group the statement under a particular case, even if multiple
statements are there inside a case.
main( )
{
int i;
printf(“Enter a number”);
scanf(“%d”,&i);
switch( i )
{
case 1:
printf(“i am in case1\n”);
case 2:
printf(“i am in case 2\n”)
case 3:
printf(“i am in case 3\n”);
default:
printf(“ i am in Default\n”)
}
}
This is because, here the matching case block is 2 as the value of variable i is 2. So from case
block2 , execution will be started. case block2 then case block3 and then the default block will
be executed.
If you want that only case 2 should be executed and the control should go out of switch
statement immediately then use break statement as the last statement in each case block but
not in the default block.
Example : Program to carry out basic arithmetic operations (+, -, *, /) based on a chosen
operator.
Loops
In programs, sometimes we need to repeat a block of statements either for a specified number
of times or until a particular condition is being satisfied. This can be achieved by using loops
or looping statements. There are 3 loop statement in C :
1. while
2. for
3. do while
Again, a loop can be classified as either entry controlled or exit controlled. I n entry-controlled
loop, the condition is tested first and if it returns true value, then the control enters into the
body of the loop. If the condition returns false value, then the control comes out of the loop.
This is also called a pre-test loop. But, in an exit-controlled loop, first the body of the loop is
executed and then the condition is tested. If the condition returns true value, then it goes to
the beginning of the loop and continues again, otherwise it leaves the loop. This is also called
a post-test loop.
while loop: It is an entry-controlled loop.
We can also keep multiple number of statements inside the body of the while loop but those
statements must be enclosed within a pair of curly brackets { }. The syntax to keep multiple
statements inside the body of the while loop is :
OUTPUT- silicon
silicon
silicon
silicon
silicon
The number of times body of the loop is executed, is known as iteration of the loop. In the
above example there are 5 iterations. In each iteration, the value of the loop control variable
is updated.
Example : Program to find out the sum of squares from 1 to 5 i.e. 12 + 22 +........+ 52
#include<stdio.h>
int main( )
{
int i=1; // initialization of loop control variable
int sum=0;
while ( i<=5 ) //test expression/condition
{
sum = sum + i * i;
i++; //update
}
printf(“SUM=%d”,sum);
return 0;
}
OUTPUT- SUM= 55
Here the while loop condition will remain true for i value to be 1, 2, 3, 4, 5. So the body of the
loop will be executed for 5 times. When i value will be 6 then the condition will be false and
the control will come out of the loop.
Example : Program to find factorial of n, where the value of n will be inputted by the user.
OUTPUT :
Enter a number: 3
Factorial of 3 = 6
Explanation:
Initially, fact = 1 and i=1. The values of fact and i are shown below, when the loop executes:
Here if we enter the value of input as 3 , the if condition will be false. So the else part will be
executed. In the else part, while loop condition will be true as the initial value of i is 1 and
input value is 3 ( i.e i <= input is true ) . So body of the loop will be executed and the new
value for fact will be 1 and i will be 2. Then in the next iteration of the loop, again the loop
condition will be true as i value is 2 and input is 3 ( i.e i <= input will be true) . Hence the body
of the loop will be executed again. So fact will be 2 and i will be 3. Now in the next iteration of
the loop, again the condition will be true as i is 3 and input is 3 ( i.e i <= input is true) . Hence
the body will be executed which will cause fact to be 6 and i to be 4 . Now the loop condition
will be false as i is 4 and input is 3 ( i.e i <= input is false) . So the control will come out of the
while loop and the printf( ) will be executed which will print factorial of 3 = 6 .
do while loop
It is an exit-controlled loop.
Body of the loop
false
Test Expr.
true
First the statement Stmt t or body of the loop is executed and then the test expression is
evaluated. If the expression returns false, then the control comes out of the loop. If the
expression returns true then the control enters into the body again. Stmt t keeps on executing
as long as the value of the expression is true. When the value of the expression becomes false
the loop terminates and control goes out of the loop. There must be one statement in the
body of the loop that alters the loop control variable so that expression becomes false
ultimately at some point to avoid infinite looping.
Important point to note that, body of the do while loop will be executed at least once, since
the test for the condition does not occur until the end of the first iteration.
We can also keep multiple statements inside the body of the do-while loop but those
statements must be enclosed within a pair of curly brackets { } . The syntax to keep multiple
statements inside the body of the do-while loop is:
do
{
stmt 1;
stmt 2;
------- ;
-------- ;
-------- ;
-------- ;
stmt n ;
} while ( test expression);
Example : Program to print the string silicon 5 times using do-while loop.
#include<stdio.h>
int main( )
{
int i=0; //initialization
do
{
printf(“silicon\n”);
i++; //update
} while ( i<5 ) ; //condition checking
return 0;
}
OUTPUT- silicon
silicon
silicon
silicon
silicon
In while loop first of all the loop condition is tested. If the condition is false then control comes
out of the loop and if the condition is true then body is executed. So while loop is an entry -
control loop. Where as in do-while loop , first the body is executed once then the loop
condition is tested. So do-while loop is an exit-control loop.
Example :
main()
{
OUTPUT- silicon
Because, first the loop body is executed and then condition is checked, whether to continue
or not.
main()
{
int i=0; //initialization
while (i<0) //condition checking
{
printf(“silicon\n”);
i++; //update
}
}
OUTPUT- No output
Because first the condition is checked and then the body of the loop is executed if it is true.
#include<stdio.h>
main()
{
int n,count=0;
printf(“\nEnter a number:”);
scanf(“%d”,&n);
do
{
n = n/10;
count++;
} while (n>0) ;
printf(“\nNo of digits=%d”,count);
}
OUTPUT-
for loop
for loop is another entry controlled loop.
expr1
Syntax of for loop:
true
Next statement
Stmt t
expr3
Each expression expr must be separated by semicolon. expr1 is executed only once when the
loop starts and is used to initialize the loop control variable. expr2 is a condition that
determines whether body of the loop is to be continued or not and it is tested before each
iteration. expr3 modifies the loop control variable at the end of each iteration.
Although task of while loop and for loop is same. for loop is used when number of iteration
known in advance and while loop is used when number of iteration are not known.
#include<stdio.h>
main()
{
int i;
for(i=0; i < 5 ; i++)
{
printf(“silicon\n”);
}
}
#include<stdio.h>
main()
{
int i=0;
for(; i < 5 ; i++)
{
printf(“silicon\n”);
}
}
#include<stdio.h>
main()
{
int i;
for(i=0; i < 5 ;)
{
printf(“silicon\n”);
i++;
}
}
#include<stdio.h>
main()
{
int i=0;
for(; i < 5 ;)
{
printf(“silicon\n”);
i++;
}
}
silicon
silicon
silicon
silicon
silicon
Note:
If the 2nd expression of the for loop is omitted, compiler assumes that it has value 1. So, for
loop is executed indefinitely unless interrupted by some means.
The initialization expression or update expression of the for loop can contain more than one
expression separated by comma. This is called as multiple initialization in for loop.
Example :
main()
{
int i, j ;
for(i=1 , j=5; i<j ; i++ , j--)
printf(“*\t”)
}
OUTPUT - * *
#include<stdio.h>
main()
{
int i,j;
for(i=5,j=1; j <=10 ; j++)
{
printf(“%d\t”,i*j);
}
}
OUTPUT - 5 10 15 20 25 30 35 40 45 50
Example : Program to evaluate x + x/2 +..........+ x/n for a given value of x and n by the user.
#include<stdio.h>
main()
{
int x,n,count;
float sum=0.0;
printf(“Enter the value of x and n:\n”);
scanf(“%d%d”,&x,&n);
for(count=1; count<=n ; count++)
{
sum = sum + x / (float) count;
}
printf(“Sum of the given series=%f”,sum);
}
Nesting of Loops
When a loop is defined inside the body of another loop, it is known as nesting of loops. It is
similar to the nesting of if-statements. Any types of loop can be nested inside one another.
Following example shows how a while loop can be nested inside another while loop.
Example
main()
{
int i, j;
i=1;
while ( i <= 3 ) //outer loop
{
OUTPUT-
123
123
123
Explanation- inner loop terminates when value of j exceeds 3 and outer loop terminates when
value of i exceeds 3. In the beginning of iteration 1 of outer loop i=1 and j value can go from 1
to 3. So 1 to 3 will be printed in the first line. In the beginning of iteration 2 of the outer loop,
i=2 and j value can go from 1 to 3. So 1 to 3 will be printed in the second line. In the beginning
of iteration 3 of the outer loop, i=3 and j value can go from 1 to 3. So 1 to 3 will be printed in
the third line
Following example shows how a while loop can be nested inside a for loop.
Example
main()
{
int i, j;
OUTPUT- 123
123
123
OUTPUT -
2 4 6 8 ........ 20
3 6 9 12.........30
4 8 12 15 ......40
5 10 ..............50
Following example shows how a for loop can be nested i nside another for loop.
Example
main()
{
int r,c;
for(r=1 ; r <=2 ; r++) // outer loop
{
for(c=1;c<=2;c++) // inner loop
{
printf(“r=%d\t c=%d \t sum=%d \n”,r,c,r+c);
}
}
}
* ** *
* **
**
*
main()
{
int r,c;
for(r=1 ; r <=4 ; r++) // outer loop
{
for( c=1;c<=4-i+1;c++) // inner loop
{
printf(“* \t”);
}
printf(“\n”);
}
}
OUTPUT- * * **
***
**
*
1234
123
12
1
main()
{
int r, c, n ;
Printf(“Enter number of rows”);
Scanf(“%d”,&n);
for(r=1 ; r <=n ; r++)
{
for( c=1;c<=n-i+1;c++)
{
printf(“%d \t”,c);
}
printf(“\n”);
}
}
OUTPTUT-
Jump statements
Loops perform a set of operations repeatedly until the control variable fails to satisfy the test
condition. The number of times a loop is repeated is decided in advance and the test condition
is written to achieve this. Sometimes, when executing a loop it becomes desirable to skip a
part of the loop or to leave as soon as certain condition occurs. C permits a jum p from one
statement to another within a loop as well as a Jump out of a loop. The break and continue
statements help us to achieve this in the programs.
break statement
We often come across situations where we want to jump out of a loop instantly, witho ut
waiting to get back to the conditional test. The keyword break allows us to do this. When a
break statement is encountered inside a loop, the loop is immediately exited and the control
automatically passes to the first statement after the loop.
A break is usually associated with an if statement. Following example shows the use of break.
Example 1:
int i = 10;
while ( i > 0 )
{
if ( i = = 5 )
break;
printf(“%d\t”, i ) ;
i- -;
}
The above code segment will display 10 9 8 7 6.
Explanation: When i value will be 5, the if condition returns true and the break statement will
be executed which will take the control out of the while loop.
When loops are nested, the break would only exit from the loop containing it. That is, the break
will exit only a single loop.
Example 2:
int x, y ;
for( x=5; x>=1; x- -)
{
for( y=1; y<=2; y++)
{
if( y= = x)
break ;
printf( ‘‘x=%d \t y=%d\n’’, x,y) ;
}
printf(‘‘\n out of inner loop\n’’) ;
}
x=5 y=1
x=5 y=2
out of inner loop
x=4 y=1
x=4 y=2
out of inner loop
x=3 y=1
x=3 y=2
out of inner loop
x=2 y=1
out of inner loop
out of inner loop
Explanation: When x is 2 and y is also 2, the if condition will be satisfied and break statement
will be executed which will take the control out of the inner for loop. After the inner fo r loop,
the printf( ) which is present inside the body of the outer for loop will be executed. Similarly
when x is 1 and y is 1, the if condition will be satisfied and break statement will be executed
which will take the control out of the inner for loop. After the inner for loop, the printf( ) which
is present inside the body of the outer for loop will be executed.
continue statement
During the loop operations, it may be necessary to skip a part of the body of the loop under
certain conditions. The keyword continue allows us to do this. The continue statement causes
the loop to be continued with the next iteration after skipping any statements in between.
The continue statement tells the compiler, “ SKIP THE FOLLOWING STATEMENTS AND
CONTINUE WITH THE NEXT ITERATION”.
Example 1:
int i = 10;
while ( i > 0 )
{
if ( i = = 5 )
continue;
printf(“%d\t”, i ) ;
i- -;
}
Explanation: When i will be 5, the if condition in the while loop will be satisfied and the
continue statement will be executed which will skip the execution of the following statements
inside the while loop and will take the control to the beginning for the next iteration of the
while loop if the condition returns true.
Example2:
int x, y ;
for( x=1; x<=2; x++)
{
for( y=1; y<=2; y++)
{
if( y= = x)
continue ;
printf( ‘‘x=%d \t y=%d\n’’, x,y) ;
}
}
The output of the above code segment will be
x =1 y=2
x =2 y=1
Explanation: When x = y, the if condition in the inner for loop will be satisfied and the continue
statement will be executed which will skip the execution of the statements following the
continue in the inner for loop and will take the control to the beginning of the next iteration
of the inner for loop.
GoTo statement
A goto statement can transfer the control to any place in a program. But it is a good practice
to avoid goto statement. It obscures the flow of control and makes the program totally
unstructured. Therefore, the use of goto statement should be strictly avoided.
Example:
#include<stdio.h>
main( )
{
int num1 , num2;
printf(“\nEnter two numbers: ”);
scanf(“%d%d”, &num1 ,&num2);
if (num1 > num2)
goto sos;
else
printf(“num2 is largest”);
sos:
printf(“num1 is largest”);
}
Explanation: When if condition is satisfied the goto statement transfers the control to the label
‘sos’, causing printf( ) following sos to be executed. The label can be on a separate line or on
the same line as the statement following it as in
sos: printf(“ num1 is largest”);
Jumping out of the program (exit( ))
We can jump out of a program by using the library function exit( ). The exit( ) takes an integer
value as its argument. Normally zero is used to indicate normal termination of the program
and non-zero value to indicate termination due to some error or abnormal condition. The use
of exit( ) requires the inclusion of the header file <stdlib.h> .
MODULE – 3
ARRAY
Basic Concepts
An array is a collection of data items, all of the same type, accessed using a common name. A
one-dimensional array is like a list; A two-dimensional array is like a table; The C language
places no limits on the number of dimensions in an array, though specific implementations
may. Some texts refer to one-dimensional arrays as vectors, two-dimensional arrays
as matrices, and use the general term arrays when the number of dimensions is unspecified
or unimportant.
Array Applications
Array is used to store the number of elements belonging to same data type. We can store
elements to be sorted in an array and then by using different sorting technique we can sort
the elements.
Matrix operations can be performed using the 2-D array. CPU Scheduling is generally managed
by Queue. Queue can be managed and implemented using the array. Array may be allocated
dynamically i.e. at run time. When the function calls another function or the same function
again then the current values are stores onto the stack and those values will be retrieving
when control comes back. This is similar operation like stack. Stack can be implemented using
array.
Declaration of an array
• Array variables are declared identically to variables of their data type, except that the
variable name is followed by one pair of square [ ] brackets for each dimension of the
array.
• Uninitialized arrays must have the dimensions of their rows, columns, etc. listed within
the square brackets.
• Dimensions used when declaring arrays in C must be positive integral constants or
constant expressions.
• To declare a one-dimensional array, the syntax is:
data_type array-name[ size] ;
where, data_type specifies the type of data to be stored (int, float, char etc.), array name
must a valid identifier and size indicates the number of elements of the array. So array
size must be a integer constant. The [ ] indicates that we are dealing with an array.
Example:
int group[10]; // declares the group as array capable of storing maximum 10 integers
char name[10]; //declares name as an array which can store at most 20 characters.
Initialization
• Arrays may be initialized when they are declared, just as any other variables.
• Place the initialization data in curly {} braces following the equals sign. Note the use of
int b[] ={1,2,3,20,10,5}; //This array is taken as size six by the compiler
• Elements of an array are accessed by specifying the index of the desired element within
square [ ] brackets after the array name.
• Array subscripts must be of integer type. ( int, long int, char, etc. )
• VERY IMPORTANT: Array indices start with zero in C, and go to one less than the size of
the array. For example, a five-element array will have indices zero through four. This is
because the index in C is actually an offset from the beginning of the array. (The first
element is at the beginning of the array, and hence has zero offset.)
• The most common mistake when working with arrays in C is forgetting that indices start
at zero and stop one less than the array size.
• Arrays are commonly used in conjunction with loops, in order to perform the same
calculations on all (or some part) of the data items in the array.
• Example: int a[6] ={10,20,30,40,50,60}
10 20 30 40 50 60
508 510 512 514 516 518 520
The above array stores six integers. The base address of the array is 508. Here we have
assumed that integer is occupying 2 bytes. The second cell of the array therefore has the
memory location 510. The next 512 and so on. To access the value 10 we need to write a[0],
to access the value 20 we need to write a[1] and so on. The last element can be accessed by
writing a[5].
Example 1: Program to store first ten natural numbers in an array and then display them.
#include<stdio.h>
main( )
{
int i, arr[10];
for (i=0; i<10; i++)
{
arr[i] = i+1;
printf(“%d\t”, arr[i]);
}
}
The above program runs a loop 10 times and then allocates the natural numbers and stores in
array named as arr.
output: 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
Example 2: Program to swap elements of an array of size six, i.e. exchanging the values at
the odd and even positions
#include<stdio.h>
main( )
{
int arr[12] , i , temp;
printf(“enter array elements”);
for( i=0 ; i <=5 ; i++)
scanf(“%d”, &arr[i]); // input the elements of the array
for(i=0; i<=5; i=i+2)
{
temp=arr[i]; //swapping the values using a third variable
arr[i]= arr[i+1] ;
arr[i+1]=temp;
}
for( i=0;i <=5;i++)
printf(“\n %d”, arr[i]) ; // printing the new values of the array
}
Input:
7 1 5 8 3 9
Output:
1 7 8 5 9 3
Array Operations
In Data structures, Array is viewed as a linear data structure involving the following common
operations:
1. Searching an element in the array
2. Inserting an element into the array
3. Deleting an element from the array
4. Sorting the elements of the array
The array concept in C helps us to implement the above operations easily. We explain here
the algorithms to achieve each of these operations. Also, we convert some of the algorithms
into programs and rest is left as exercises.
Linear Search
Here we start searching the element from the beginning of the array until we found the
element or reached to the last element of the array. If we have reached to the last element,
then we conclude that the element is not found in the array and we stop. The algorithm is
given below:
Binary Search
The precondition for binary search is that the elements of the array should be in sorted
order (either in ascending or descending order). Here, we assume the array given to us is
sorted in ascending order.
First we find the middle index by adding the first index and last index and dividing by
2 (This is a integer division). Then we compare the element to be searched (key) with the
element at the middle index. If key is greater than the eleme nt at middle index, then we
narrow down our search to the second half after the middle index. Since the elements are
already sorted in ascending order, the elements to left of the middle index are definitely
smaller than the element at the middle index. On the other hand, we search the first half if
the key is smaller than the element at the middle index. We update the first or last index
depending on which half we are searching. This process is repeated until first>last. The
algorithm is given below:
1. first=0
2. last=n-1
3. Repeat steps while (first<=last)
4. mid=(first+last)/2
5. if (a[mid] < key)
6. first=mid+1
7. else if (a[mid]>key)
8. last=mid-1
9. else return mid
10. if (first>last)
11. return -1
Assignment:
1. Write a program to search an element in an array by using linear search.
2. Write a program to search an element in an array by using binary search.
Let there be an array a[] with n elements. We want to insert an element ‘key’ in some position
‘pos’, where pos<=n. So, we need to shift the elements starting with the last element until
i<pos. Then we insert the element key at a[pos]. Following algorithm helps to insert an
element into the array.
Let there be an array a[] with n elements. We want to delete an element from the array with
the given position ‘pos’, where pos<=n. We keep a copy of the element from the pos in to key
and then shift the elements backward to fill up the gap until i>(n-1). Following algorithm helps
to delete an element from the array.
Algorithm Delete(a[],n,pos,key)
1. key=a[pos]
2. set i=pos
3. repeat steps while (i<=n-1)
4. set a[i]=a[i+1]
5. set i=i+1
6. n=n-1
7. exit
Assignment:
1. Write a program to delete an element from the array whose position is given.
2. Write a program to delete an element from the array whose value is given.
We often need to arrange a list of numbers either in ascending or descending order. Although
we can do it manually for a small list of numbers, but a systematic algorithm is essential for
sorting a large list.
Computer scientists have developed numerous algorithms for efficient sorting. Some
of the popular algorithms include Heap sort, Quick sort, Merge sort etc. Here we shall discuss
one of the simplest algorithms known as Selection sort. Though it is not much efficient, but
useful to understand the concept of sorting easily.
Selection Sort
First the n number of elements to be sorted are kept in an array. This algorithm in
every step, finds the minimum element (assuming ascending order of sorting) and swaps it
with the element from the beginning of the array. Therefore, this algorithm logically maintains
two sub-arrays for a given physical array as follows:
i) The sub-array which is already sorted
ii) The remaining sub-array which is unsorted
In each iteration, the minimum element from the unsorted sub-array is picked up and moved
to the sorted sub-array. This process needs a maximum of n-1 number of passes (as shown in
the example)
Algorithm
3. Set j=0
4. Repeat steps (3-9) while (j<n-1)
5. min=j;
6. i=j+1;
7. Repeat steps (6-7) while (i<n)
8. If (a[i]<a[min])
9. min=i;
10. if (min !=j)
11. Swap a[j] and a[min]
12. Exit
Example :
Let n=5. So, five elements are in the array. Let A={50, 40, 320, 30, 10}. It shows the passes by
using Selection sort algorithm.
50 40 20 30 10 Min.
Pass 1: 10 40 20 30 50
Pass 2: 10 20 40 30 50
Pass 3: 10 20 30 40 50
Pass 4: 10 20 30 40 50
Assignment: Write a program for the above algorithm and test for some values of n.
Two dimensional arrays consist of two dimensions where the first dimension is
commonly considered to be the number of rows, and the second dimension is the number
of columns. Example: int arr[5][6] refers to a two dimensional integer array having five rows
and six columns.
One dimensional arrays do not require the dimension to be given if the array is to be
completely initialized. By analogy, two-dimensional arrays do not require the first dimension
to be given explicitly if the array is to be completely initialized. The second dimension must
be specified.
35 40 45
50 55 60
65 70 75
80 85 90
Example 5: Program to input two matrices, add them and then display the resultant matrix.
main( )
{
int a[10][10], b[10][10], c[10][10];
int i, j, m ,n;
printf(“\n Enter row and column:”);
scanf(“ %d %d”, &m, &n);
printf(“ \n Enter the first matrix:”);
for( i=0 ; i<m ; i++ )
for(j=0 ; j< n; j++)
scanf(“%d” , &a[i][j] );
Strings
'\0'
A string constant is simply a list of characters within double quotes e.g. "Hello" with the '\0'
character being automatically appended at the end by the compiler.
Again the size specification may be omitted allowing the compiler to determine the size
required.
Manipulating Strings
We can print out the contents of a string using printf( ) as we have seen already or by using
puts().
printf( "%s", s ) ;
puts( s ) ;
scanf( "%s", s ) ;
where we do not require the address-of operator( & ) with the array name, as the name of an
array without any index or square braces represents the address of the first element of the
array (base address of the array).
#include<stdio.h>
main( )
{
char str[20];
printf(“\nEnter a string: ”);
scanf(“%s”,str); //& is not required when you read string
Input: Hello
Output: Hello
The above way of reading a string by using %s format specifier, has a drawback. It will
stop reading the string as soon as it encounters a white space. Therefore, we can’t able to
input a sentence having space in between words. For example, the name of a student having
first name, middle name and surname separated by spaces.
To overcome the above drawback, we can use another format specifier as follows:
scanf("%[^\n]",s); //This will read the string until a new line is encountered.
Example : Program that will read a string and display it (String may have white space or tab.
#include<stdio.h>
main( )
{
char s[20];
printf("\nEnter a string (having multiple words): ");
scanf("%[^\n]",s);
printf("%s",s);
}
Input: Hello World
Output: Hello World
Read a string by using gets(): A string can also be read by using gets( ) library function. It
passes a string name as its argument.
Program: Program that will read a string and count the length and number of words of the
string.
#include<stdio.h>
main( )
{
char str[50]; int i=0, countc=0, countw=0;
printf("\nEnter the string: ");
scanf("%[^\n]",str);
while( str[i] !=’\0’)
{
countc++;
Example: Program to read a string and check whether it is palindrome or not. A string is known
to be palindrome if it is the same string when read from last character to first character. That
is the string is same as its reversed string. Example: MADAM is a palindrome string, but SIR is
not.
#include<stdio.h>
#include <string.h>
main( )
{
char str[30];
int i=0, j, length, flag=0;
printf("\nEnter the string: ");
scanf("%[^\n]",str);
length = strlen(str); // compute length of the string
j=length-1;
while(i<j)
{
if(str[i] != str[j])
{
flag=1;
break;
}
else
{
i++;
j--;
}
}
if (flag==0)
printf("The string is a palindrome\n");
else
printf("The string is not a palindrome\n");
}
Arrays of Strings
An array of strings is in fact a two-dimensional array of characters but it is more useful to view
this as an array of individual single dimensional character arrays or strings.
Example:
char str_array[ 10 ] [ 30 ] ;
where the row index is used to access the individual row strings and where the
column index is the size of each string, thus str_array is an array of 10 strings each with
a maximum size of 29 characters leaving one extra for the terminating null character.
Assignment:
Write a program to input a list of strings and sort them lexicographically (i.e. as per dictionary
style)
C library supports the following string handling functions which are declared under the header
file string.h.
strlen()
It counts the number of characters in a string excluding the null(‘\0’) character. That means
the counting ends when a null character is encountered. Its function call syntax is strlen(str);
where str is a string.
Example:
int n;
char str[]=”Silicon”;
n=strlen(str); // It will return the value 7 to n.
strcpy()
It copies one string to another string. Its function call syntax is strcpy(str1,str2);
Where, str1 and str2 are strings. Here str2 is copied to str1. Therefore size of str1 should be
large enough to store str2.
Example:
Char city1[20]=”Delhi”;
Char city2[2]]=”Bhubaneswar”;
strcpy(city1,city2); // It will overwrite Bhubaneswar over Delhi.
Also we can use following syntax to directly pass the string “Bhubaneswar” into the function.
strcpy(city1,”Bhubaneswar”);
strcat()
It joins two strings. It has the function call syntax strcat(str1, str2);
where, str1 and str2 are strings declare before the function call. The result of the function call
is that, str2 is appended at the end of str1.
Example:
char str1[20]=”very”;
char str2[20]=“good”;
Then strcat(str1,str2) will store “verygood” in str1.
strcmp()
It compares two strings given by str1 and str2. It returns a value 0, if both the strings are
identical. That means the function compares the ASCII value of each character of both the
strings one by one.
It returns -1 when the str1 comes before str2 lexicographically. It returns +1 when the str1
comes after str2 lexicographically. Note that this function returns positive or negative value
as soon as it finds the first ASCII non-matching character and stops comparing there.
The function call syntax is strcmp(str1,str2).
Example:
char str1[]=”bat”;
char str2[]=”ball”;
int n=strcmp(str1,str2); //The function will return value +1 as “bat” comes after “ball” in
dictionary.
strncpy()
It copies only the leftmost n characters of the source string to the destination string variable.
It can be called as strncpy(str1, str2, n); where, str1 is the destination and str2 is the source.
strncat()
It concatenates the leftmost n characters of the second string (str2) to the end of the first
string (str1). It can be called as strncat(str1,str2,n);
Example:
char str1[20]=”Silicon”;
char str2[20]=”Institute”;
By calling the function as strncat(str1, str2, 4), the output “SiliconInsti tute” will be stored in
str1.
strncmp()
It compares the leftmost n characters of strings str1 and str2 and returns the following:
It returns 0 if both are identical
It returns negative value if the substring of str1 is less than str2 and returns positive value
otherwise. It can be called as strncmp(str1, str2, n);
strstr()
It is used to locate a substring in a given string. It can be called as strstr(str1, str2); It means
this function searches the string str1 to see whether the string str2 is present in str1. If yes,
then it returns the position of the first occurrence of the substring, otherwise returns a NULL
pointer.
MODULE – 4
User-defined functions
Monolithic vs. Modular Programming
In Monolithic programming, it is possible to code the entire program using only main ( ).
Disadvantages:
In Modular programming, a program is divided into number of functional parts which may be
independently coded and later combined into a single unit. These independently coded
subprograms are called as functions.
Advantages:
1. Easy to understand
2. Easy to test, debug and maintain.
Introduction to Function
A function is a self-contained block of code that performs a particular task. C function can be
classified into two categories:
1. Library Function
2. User-defined Function
The Library Functions are pre-defined functions whereas User-defined function has to be
developed by the user at the time of writing a program.
Function Declaration
Return type of a function indicates what type of value the function is going to return. If a
function returns an integer value, then its return type is int. Similarly, if the function returns
a floating type value, then its return type is float. When a function does not return any value
then its return type is void.
Function Name is a valid identifier. The name should be appropriate to the task performed by
the function.
A function can have any number of parameters depending on the requirements. Even a
function does not have any parameter also. When a function contains parameters, then the
parameter list must be separated by commas. Only the type of the parameter is mandatory
in the function declaration part where as parameter name is optional.
Like variable declaration, a function declaration statement must be ended with a semicolon.
Examples:
void sum( ); Here the function sum won’t take any parameter and
int sum ( void); Here the function sum won’t take any parameter but
int sum( int, int); Here the function sum will take two parameters, both
an int value .
float sum (int, float); Here the function sum will take two parameters, first
A function can be called by using the function name followed by a list of actual arguments (or
parameters) if any, enclosed in parentheses.
Here only the name of the parameters must be mentioned in the parameter list, not the type.
If the function won’t take any parameter, then the parentheses must be empty.
sum( ) ;
sum ( x , y) ;
sum (10, 20) ;
When a function call statement is executed, the execution of the rest of the statements of
the program will be temporarily suspended and the control is transferred automatically to
the function definition part.
Function Definition
1. return type
2. function name
3. list of parameters ( both type and name of each parameter )
4. local variable declaration
5. function statements
6. a return statement
All the six elements are grouped into two parts:
-------------------- ;
Here the return type of the function and the function name must be matched exactly
with the same which has already mentioned in the function declaration part. The types must
match the types of parameters in the function declaration, in number, in types and in order.
When types do not match with the types in the declaration, compiler will produce an error.
The parameter names do not need to be the same in the prototype declaration and the
function definition.
Notes:
1. The function, who is calling, is called as the calling function and the function which will
be called, is called as the called function.
2 Parameters mentioned in the function calling part are called as the actual parameters
or actual arguments. Parameters mentioned in the function definition part are called as
the formal parameters or formal arguments.
3 In the function body, the function statements are executed sequentially one after
another. When a return statement is executed in the body of a function, the control is
transferred back to the calling function. In the absence of a return statement in the body,
the closing brace of the function definition acts as a void return which automatically
returns the control back to the calling function.
4 A function need not always receive value from calling function. In such cases, function
has no parameters. To indicate that the parameter list is empty, we use the keyword void
between the parentheses as in
void sum ( void )
{
----------- ;
----------- ;
5 A local variable is a variable that is defined inside the body of a function and used without
having any role in the communication between functions.
6 A function may or may not send back any value to the calling function. If it does, it is
done through the return statement. The called function can only return one value per
call. The return statement can take one of the following forms :
Example 2:
Parameter Passing
In C, there are two standard methods to pass the parameters from the calling function to
the called function.
In the call by value method, the called function creates a new set of variables and then copies
the values of the actual arguments into them. So, the formal arguments are the photocopies
of the actual arguments. Values of the actual arguments are passed from the calling function
to the called function. So, any changes to the formal arguments in the called function won’t
affect the value of the actual arguments in the calling function.
10 and 20 as the values of num1 and num2 respectively, then the printf( ) will display the
values of num1 and num2 to be 10 and 20 .Hence the first output of the program will be :
Then the function calling statement swap( num1, num2) will be executed and the control is
transferred to the called function swap( ) . In the swap( ), value of the actual arguments num1
and num2 are copied into the formal arguments num1 and num2 respectively. Hence num1
and num2 in the called function swap( ) initially becomes 10 and 20. Then as per the lo gic in
the swap( ), we have swapped the values of num1 and num2. Hence in the swap( ), num1
value will be 20 and num2 value will be 10. The printf( ) inside the body of the swap( ) will
print 20 and 10 for num1 and num2 respectively. Hence the second output of the program
will be :
But when the control will be returned back to the main( ), inside the main( ) value of num1
and num2 are still 10 and 20. Hence the last printf( ) inside the body of the main( ), will print
10 and 20 as the values of num1 and num2 respectively. Hence the last output of the program
will be :
Example 2: Write a program to find out the largest between two numbers using function.
#include <stdio.h>
int max ( int, int ); // Function Prototype
main( )
{
int num1, num2, largest ;
printf(“ Enter any two numbers”) ;
scanf(“%d %d” , &num1, &num2) ;
largest = max( num1, num2 ); // Function Calling
printf(“ Largest number=%d” , largest) ;
}
int max( int var1, int var2) // Function Definition
{
In the call by reference/address method, address of the actual arguments is passed from the
calling function to the called function. So, the formal arguments in the called function are
basically the pointers to the actual arguments. Therefore, any changes to the formal
arguments in the called function will directly affect the actual arguments in the calling
function.
main( )
{
int num1, num2 ;
printf(“ Enter any two numbers”) ;
scanf(“%d%d” , &num1, &num2);
printf(“ Before swapping num1= %d and num2= %d”, num1,num2);
swap( &num1, &num2 ); // Function Calling
printf(“ After swapping num1= %d and num2= %d”, num1,num2);
}
void swap( int *num1, int *num2 ) // Function Definition
{
int temp;
temp = *num1;
*num1 = *num2;
* num2 = temp;
printf(“ In the called function num1=%d and num2= %d” , *num1,*num2);
}
In the above program if we input num1 value as 10 and num2 value as 20 then the output will
be :
Example:
int large (arr, n); // where large is the name of the function, arr is the name of the array
consisting of n number of elements.
In C the name of the array represents the address of the 0th element of the array which is
also called the base address.
By passing the name of the of the array, the address of the 0th element of the array is passed
to the called function.
#include<stdio.h>
void modify(int [] , int); /*function prototype parameter 1 telling that 1 st argument passed
is an integer array and second argument passed is an integer number. */
main( )
{
int i, arr[5];
printf(“enter elements”);
for(i=0 ; i<5 ; i++)
scanf(“%d” , &arr[i]);
modify(arr ,5); // function calling with arguments
for(i=0 ; i<5; i++)
printf(“%d”, arr[i]);
}
void modify( int arr[], int k) // function definition
{
int i ;
for(i=0 ; i < k ; i++)
arr[i]=arr[i]+2;
}
Input: enter elements
12345
Output: 3 4 5 6 7
In the modify function, value of each array element is incremented by 2. Hence output is 3 4
5 6 7.
Passing two-dimensional array to function
Two dimensional arrays can be passed by only passing the array name. Function definition
must indicate that array has two dimensions. Size of the second dimension must be specified.
The prototype declaration should be similar to the function definition header.
int r ,c;
printf(“ Enter row and column”);
scanf(“ %d %d”, &r, &c);
printf(“ \n Enter the first matrix”);
input(a, r, c);
printf(“\n Enter the second matrix”);
input(b, r, c);
add(a, b, r, c);
}
void input(int x[][10], int m, int n) // input function definition to initialize the mat rix
{
int i, j ;
for( i=0 ; i<m ; i++ )
{
for(j=0 ; j< n; j++)
scanf(“%d” , &x[i][j] );
}
}
void add ( int x[10][10], int y[10][10], int m , int n) // add function to add the two matrices
{
int i , j , c[10][10];
for( i=0; i < m; i++)
{
for(j=0; j<n ; j++)
{
c[i][j] = x[i][j] + y[i][j] ;
printf(“ %d\t” , c[i][j]);
}
printf(“\n”);
}
}
3 3
123
456
789
123
456
789
Output:
2 4 6
8 10 12
14 16 18
Recursion
Recursion is the process of defining something in terms of itself. For an example: Suppose we
want to find out factorial value of 5. As we know that, the factorial of a number is the product
of all integers between 1 and that number. So
5! = 5 * 4 * 3 * 2 * 1
5! = 5 * 4!
A function is called as a recursive function, if any statement within the body of the function
calls the same function. Recursive functions can be effectively used to solve problems where
solution is expressed in terms of successively applying the same solution to the subsets of the
problem.
Example:
{ | .
---------- ; |
---------- ; |
---------- ; |
---------- ;
Example: Write a program to find out the factorial of a number using recursion.
return( f ) ;
}
Factorial of 3 is 6
Let us see how recursion works? Assume x = 3 in the called function rec( ). Since the value of
x is not 1, the statement f = x * rec( x – 1 ) ; will be executed with x = 3. That is ,
f = 3 * rec( 2 ) ;
will be executed. This expression on the right hand side includes a call to rec( ) with x = 2. This
call will return the following value :
2 * rec( 1 )
Once again, rec( ) is called with x = 1. This time, the function returns 1. The sequence of
operations can be summarized as follows :
f = 3 * rec( 2 )
= 3 * 2 * rec( 1 )
= 3 * 2 *1
= 6
Note: When we write recursive functions, we must have an if statement (terminating
condition) somewhere to force the function to return without the recursive call being
executed. Otherwise the function will never return.
Example: Write a program to print the Fibonacci series up to the nth term using Recursion.
int n, i;
printf(“ Enter the value of n “) ;
scanf(“%d” , &n) ;
for( i = 0; i < n; i++ )
printf(“%d\t” , fibo( i ) ) ;
}
Output : 0112358
Storage: Memory
Default Initial Value: An unpredictable value called as Garbage Value
Scope: Local to the block in which the variable is defined
Lifetime: Till the control remains within the block in which the variable is defined.
Automatic variables are defined inside a function in which they are to be used. They are
created when the function is called and destroyed automatically when the function is exited,
hence the name automatic. Automatic variables are therefore private or local to the function
in which they are defined.
Example 1:
Example 2:
In the above program, compiler will treat three I’s as the totally different variables, since they
are defined in different blocks. All three I’s are available to the innermost printf( ) .This is
because the innermost printf( ) lies in all three blocks in which the three I’s are defined. This
printf( ) prints 3 because even if all three I’s are available, but the one which is moat local is
given a priority. Once the control comes out of the innermost block, the variable I with value
3 is lost (dead) , hence the I in the second printf( ) refers to I with value 2. Similarly, when the
control comes out of the next innermost block, the variable I with value 2 is lost ( dead )
.Hence third printf( ) refers to the variable I with value 1 .
Note: A variable defined inside a function without storage class specification, is by default,
an automatic variable.
Example :
register int I ;
for ( I =1; I < = 10; I++ )
printf(“%d” , I );
}
Static Storage Class
Storage: Memory
Default Initial Value: Zero
Scope: Local to the block in which the variable is defined
Lifetime: Value of the variable persists until the end of the program
Example:
#include < stdio.h >
void increment( );
main( )
{
increment( );
increment( );
increment( );
}
void increment( )
{
static int x = 1;
printf( “%d\n” , x ) ;
x= x + 1 ;
}
The output of the above program will be:
1
2
3
A static variable is initialized only once, when the program is compiled. It is never initialized
again. During the first call to increment ( ), static variable x is initialized to 1 and it is displayed
by the printf( ). Then x is incremented to 2. Since x is static, this value persists and therefore,
in the second call to increment( ), printf( ) will display 2. Then x is incremented to 3. Since x is
static, this value also persists. Therefore in the third call to increment( ), printf( ) will display
3.
Storage: Memory
Default Initial Value: Zero
Scope: Global
Lifetime: As long as the program execution doesn’t come to the end
Variables that are both alive and active throughout the entire program are known as the
external variables. They are also known as global variables. Unlike local variables, global
variables can be accessed by any function in the program. External variables are declared
outside a function.
Example:
printf(“%d” , x ) ;
increment( ) ;
decrement( ) ;
}
void increment ( )
{
void decrement ( )
{
0
1
0
Here the global variable x is alive and available for use in all three functions i.e main( ),
increment( ) and decrement( ). The default initial value of x which is 0 will be printed by the
printf( ) inside the main( ). Then during the call to the increment( ), x is incremented to 1 which
will be printed by the printf( ) inside the increment( ). Then during the call to decrement( ), x
is decremented to 0 which will be printed by the printf( ) inside the decrement( ).
Example: In case a local variable and a global variable have the same name, the local variable
will have precedence over the global one in the function where it is declared.
void fun( )
{
Example: One other aspect of a global variable is that it is available only from the poi nt of
declaration to the end of the program.
int main( )
{
y=5;
----- ;
----- ;
----- ;
}
int y ;
fun( )
{
y=y+1;
}
In the above code segment, main( ) can’t access the variable y as it has been declared after it
. So the compiler will issue an error message. This problem can be solved by declaring the
variable with the storage class extern as in the following example:
main( )
{
extern int y ; // External Declaration
-------------- ;
-------------- ;
}
fun( )
{
extern int y ; // External Declaration
-------------- ;
-------------- ;
}
int y ; // Definition
Although variable y has been defined after both the functions, the external declaration of y
inside the functions informs the compiler that y is an integer type defined somewhere else in
the program.
For example, storing the details of a book (title: string type, author: string type, page: integer
type, price: float type). In such cases an array cannot be used as they are of different data
types. To fulfil this requirement, we need to understand a new concept called structure to
represent a book with all data items related to it.
Definition of Structure
Structure is a user defined data type, which is defined as a collection of one or more variables
possibly of heterogeneous data type. Structures help to organize complicated data by
permitting a group of related variables to be treated as a unit instead of as separate entities.
Structure Declaration
Syntax:
struct Structure_name
data_type variable_name1;
data_type variable_name2;
--- - - - - - - - - - - - - - - - - - ;
--- - - - - - - -- - - - - -- - - - - ;
};
The keyword struct declares a structure with the given Structure_name. Its body consists of
different data fields. These fields are also called structure elements or members. Each
member may belong to a different data type.
Example:
struct book
{
char title[20];
char author[15];
int pages;
float price;
};
Here the keyword struct declares a structure book to hold the details of four data fields,
namely title, author, pages and price.
After defining a structure format we can declare variables of that type. A structure variable
declaration is similar to the declaration of variables of any other data types.
Syntax:
For example, the statement struct book b1, b2, b3; declares b1, b2, and b3 as variables of
type struct book.
Note: It is also allowed to combine both the structure definition and variables declaration in
one statement as follows:
struct book
{
char title[20];
char author[15];
int pages;
float price;
} b1, b2, b3;
Note: A structure declaration/definition statement never allocates any memory, but
memory will be allocated whenever a structure variable is declared.
Accessing Structure Members
Structure members can be accessed using ‘.’ and is called member operator or dot operator.
We can also use scanf( ) to enter values through the keyboard as follows:
Like any other variable, structure variable can also be initialized at compile time.
Copying the content of one structure variable to another variable is not possible directly. For
example the following assignment statement is not allowed.
b6.pages = b5.pages ;
b6.price = b5.price ;
Note: The comparison between two structure variables using relational operators is not
possible directly, To compare structure variables we need to compare individual structure
members as we have done above.
Nested Structure
struct book
{
char title[20];
struct author
{
char name[20];
char affiliation[100];
};
int pages;
float price;
2. Structure
}; variable inside structure definition
Example: struct author
{
char name[20];
char affiliation[100];
};
struct book
{
char title[20];
struct author Auth;
int pages;
float price;
};
Members of a nested structure can be accessed by using another dot operator as in the
following example.
Example:
struct book b1;
strcpy(b1.Auth.name,”Balagurusamy”); // dot operator is used twice
Unions
A union is a variable that may hold (at different times) objects of different types and sizes,
with the compiler keeping track of size and alignment requirements. Unions provide a way to
manipulate different kinds of data in a single area of storage, without embedding any
machine-dependent information in the program.
Union declaration
union union_name
{
…
…
};
Example:
union item
{
int x;
float y;
char name[20];
};
Union variable declaration
Note: The compiler allocates a piece of storage that is large enough to hold the largest
variable type in the union. We can use only one of them at a time.
Initialization
union item a;
a.x=50;
a.y=123.3;
printf(“%d”,a.y); // this will print 123.3
printf(“%d”,a.x); // this will give garbage value
Union variables can only be initialized with first union member type data at the time of
declaration. We cannot initialize other data members at the time of declaration.
Example:
union item a={50}; // valid
union item b={123.1}; //invalid
typedef
C provides a facility called typedef for creating new data type names. For example, the
declaration
typedef int Length;
makes the name Length a synonym for int. Now, the type Length can be used as a synonym
to the int type and can be written as: Length a, b;
As a more complicated example, we could make typedef for the structure declaration in
either of the following two forms.
Array of Structures: An array of structures, where each element of the array represents a
structure variable.
Declaration syntax:
Example:
struct book b[10]; Defines an array called b that consists of 10 elements. Each element is
defined to be of the type struct book.
Example: Define a structure student with elements as name, roll no and total mark. Write a
program to input the details of 5 students and display the details.
#include <stdio.h>
main( )
{
int i;
struct student
{
char name[15];
int roll;
int mark;
};
struct student s[5];
printf(“ ENTER THE NAME, ROLL NO AND TOTAL MARK: ”);
for( i=0; i<5; i++)
scanf(“ %s%d%d”, s[i].name, s[i].roll, s[i].mark);
printf(“\n DETAILS OF THE STUDENTS: ”);
for( i=0; i<5; i++)
printf(“%s\t%d\t%d\n”, s[i].name, s[i].roll, s[i].mark);
}
Example: Array of structure and array within a structure.
struct car
{
char make[20];
char model[30]; // Array within structure
int year;
};
struct car arr_car[10];
Structures and Functions; Self-referential Structures
Structure and Function
C supports the passing of structure values as arguments to functions. The general format of
sending a copy of a structure variable (pass by value) to the called function is:
function_name(structure_variable_name);
Note: It is also possible to pass the structure variables to the functions by using the pass by
reference concept.
Self-referential Structures
It is a structure which contains a pointer(member) that points to the same structure. That
means a variable of this structure can point to another variable of the same structure.
A self referential structure is used to create data structures like linked lists, stacks, queue
etc. Following is an example of this kind of structure:
struct struct_name
{
data_type variable_name;
struct struct_name * pointer_variable_name;
};
Example:
struct node
{
int data;
struct node *next;
};
In the above example, the node is a self-referential structure – because the *next is of the
type struct node. If we create three variables of structure node i.e. n1, n2, and n3, then we
can write a program so that n1 points to n2 and n2 points to n3. That means next pointer
field of n1 hold the address of node n2 and next pointer field of n2 holds the address of n3.
Following figure illustrates this concept.
n1 n2 n3
#include <stdio.h>
main()
{
struct node n1, n2, n3;
n1.data=10;
n1.next=NULL; // n1 is not pointing to n2 at this moment, holding NULL
n2.data=20;
n2.next=NULL; // n2 is not pointing to n3 at this moment, holding NULL
n1.next=&n2; // Now node n1 points to node n2
n3.data=40;
n3.next=NULL; //n3 will not pointing to any other node as it is the last node
n2.next=&n3; // Now node n2 points to node n3
printf(“%d %d %d, n1.data, n1.next->data, n2.next->data);
return 0;
}
Output: 10 20 40
MODULE – 5
Pointers
A pointer is a variable that is used to store a memory address. Most commonly the address
is the location of another variable in memory.
If one variable holds the address of another then it is said to point to the second variable.
In the above figure, ivar is a variable of type int with a value 23 and stored at memory address
1012. ivar_ptr is a variable of type pointer to int which has a value of 1012 and is stored at
memory address 1004. Thus ivar_ptr is said to point to the variable ivar and allows us to refer
indirectly to it in memory.
Note: It should be remembered that ivar_ptr is a variable itself with a specific piece of
memory associated with it, in this 32-bit case four bytes at address 1004 which is used to
store an address.
Pointer Variables
Pointers like all other variables in C must be declared as such prior to use.
It indicates that ptr is a pointer to a variable of a particular data type. For example
int *ptr ;
It declares a pointer ptr to variables of data type int. So, here the * is called a pointer
declaration operator.
Note: The type of the pointer variable ptr is int *. The declaration of a pointer variable
normally sets aside just two or four bytes of storage for the pointer whatever it is defined to
point to.
In 16-bit systems two byte pointers are termed near pointers and are used in small memory
model programs where all addresses are just segment offset addresses and 16 bits in length.
In larger memory model programs addresses include segment and offset addresses and are
32 bits long and thus pointers are 4 bytes in size and are termed far pointers.
In 32-bit systems we have a flat address system where every part of memory is accessible
using 32-bit pointers.
indirection
count i m
125 125 1000
1000 1724 1824
One of the most frequent causes of error when dealing with pointers is using an uninitialised
pointer. Pointers should be initialized when they are declared or in an assignment statement.
Like any variable if you do not specifically assign a value to a pointer variable it may contain
any value. This is extremely dangerous when dealing with pointers because the pointer may
point to any arbitrary location in memory, possibly to an unused location but also possibly to
a memory location that is used by the operating system. If your program tries to change the
value at this address it may cause the whole system to crash. Therefore it is important to
initialize all pointers before use either explicitly in your program or when defining the pointer.
Call by Reference
Recall that, when we wanted to swap two values using a function we were unable to actually
swap the calling parameters as the call by value mechanism was employed. The solution to
the problem is to use call by reference/pass by reference which is implemented in C by using
pointers as is illustrated in the following example.
Example: Program to swap two values by using pass by reference
#include <stdio.h>
void swap( int *, int * ) ;
main( )
{
int a, b ;
printf( "Enter two numbers" ) ;
scanf( " %d %d ", &a, &b ) ;
printf( "a = %d ; b = %d \n", a, b ) ;
swap( &a, &b ) ;
printf( "a = %d ; b = %d \n", a, b ) ;
}
The swap() function is now written to take integer pointers as parameters and so is called in
main() as: swap( &a, &b ) ;
where, the addresses of the variables are passed and copied into the pointer variables in the
parameter list of swap(). These pointers must be de-referenced to manipulate the values, and
it is values in the same memory locations as in main() we are swapping unlike the previous
version of swap where we were only swapping local data values.
In our earlier call-by-value version of the program we called the function from main()
as swap(a,b); and the values of these two calling arguments were copied into the formal
arguments of function swap.
In our call-by-reference version above our formal arguments are pointers to int and i t
is the addresses contained in these pointers, (i.e. the pointer values), that are copied here
into the formal arguments of the function. However when we de -reference these pointers we
are accessing the values in the main() function as their addresses do not change.
There is a very close relationship between pointer and array notation in C. As we have seen
already the name of an array (or string) is actually the starting (or base) address of the array
in memory and so it is essentially called as a constant pointer.
Example:
char str[80], *ptr ;
ptr = str ; /* causes ptr to point to start of string str */
ptr = &str[0] ; /* this performs the same as above */
Addition / Subtraction
The value a pointer holds is just the address of a variable in memory, which is normally a four
byte entity. It is possible to modify this address by integer addition and subtraction if
necessary. Consider the following we assume a 32-bit system and hence 32-bit integers.
We now have the pointer variable ptr pointing at the start of array which is stored at memory
location 2008 in our figure above. Since we know that element array[1] is stored at address
2012 directly after element array[0] we could perform the following to access its value using
the pointer
ptr =ptr+1 ;
This surprisingly will cause ptr to hold the value 1012 which is the address of array[1], so we
can access the value of element array[1]. The reason for this is that ptr is defined to be a
pointer to type int, which are four bytes in size on a 32-bit system. When we add 1 to ptr, the
compiler increments the ptr by 4 bytes, since an integer takes four bytes of storage as per our
discussion
above. Likewise a pointer to type char would be incremented by 1 byte, a pointer to float by
4 bytes etc.
Similarly we can carry out integer subtraction to move the pointer backwards in memory.
ptr = ptr - 1 ;
ptr -= 10 ;
The shorthand operators ++ and -- can also be used with pointers. In our continuing example
with integers the statement ptr++ ; will cause the address in ptr to be incremented by 4 and
so point to the next integer in memory and similarly ptr-- ; will cause the address in ptr to be
decremented by 4 and point to the previous integer in memory.
Note: Two pointer variables may not be added together as it does not make any logical sense.
char *p1, *p2 ;
p1 = p1 + p2 ; /* illegal operation */
However, two pointers may be subtracted if they point to the same array as follows:
int *p1, *p2, array[3], count ;
p1 = array ;
p2 = &array[2] ;
count = p2 - p1 ; /* legal operation*/
The result of such an operation is not however a pointer, it is the number of elements of the
base type of the pointer that lie between the two pointers in memory.
Comparisons
We can compare pointers using the relational operators ==, <, and > to establish whether
two pointers point to the same location, to a lower location in memory, or to a higher location
in memory. These operations are again used in conjunction with arrays when dealing with
sorting algorithms etc.
Example: Writing our own version of the puts() standard library function.
1. Using array notation
void puts( const char s[ ] ) /* const keyword makes string contents read only */
{
int i ;
for ( i = 0; s[i] ; i++ )
putchar( s[i] ) ;
putchar( '\n' ) ;
As you can see by comparing the two versions above the second version using pointers is a
much simpler version of the function. No extra variables are required and it is more efficient
as we will see because of its use of pointer indirection.
Example: Program to check a string is palindrome on not by using pointers.
#include <stdio.h>
int palin( char * ) ; /* Function to determine if array is a palindrome. returns 1 if
it is a palindrome, 0 otherwise */
main( )
{
char str[30], c ;
puts( "Enter test string" ) ;
gets( str ) ;
if ( palin( str ) )
printf( "%s is a palindrome\n", str ) ;
else
printf( "%s is not a palindrome\n") ;
}
//Function definition
int palin ( char *str )
{
char *ptr ;
ptr = str ;
while ( *ptr )
ptr++ ; /* get length of string i.e. increment ptr while *ptr != '\0' */
ptr-- ; /* move back one from '\0' */
while ( str < ptr )
if ( *str++ != *ptr-- )
return 0 ; /* return value 0 if not a palindrome */
return 1 ; /* otherwise it is a palindrome */
}
C's standard library string handling functions use pointers to manipulate the strings. For
example the prototype for the strcmp() function found in <string.h> is
Array of Pointers
Like array of integers, array of characters, we can also have array of pointers. So, array of
pointers is nothing but a collection of addresses. These addresses can be addresses of
isolated variables or addresses of array elements or any other addresses.
Example 1:
main()
{
int *arr[3];
int i=3,j=5,k=10;
arr[0]=&i;
arr[1]=&j;
arr[2]=&k;
for(m=0;m<3;m++)
printf(“%d\t”,*(arr[m]));
}
Output: 3 5 10
Example 2:
main()
{
int a[]={0,1,2,3,4};
int *p[]={a,a+1,a+2,a+3,a+4};
printf(“\n%u\t%u\t%d”,p,*p,**p);
}
Pointer to an array
A pointer pointing to an array is known as pointer to an array.
Declaration:
Syntax: datatype (*pointervar)[sizeofthearray];
Example: int (*p)[2];
Example 1:
main()
{
int arr[3][2]={ {1234,51},{1235,52},{1236,53}};
int (*p)[2]; //p is a pointer to an array of two integers.
int i,j,*pint; //print is a normal integer pointer.
for(i=0;i<3;i++)
{
p=&arr[i];
pint=p;
for(j=0;j<2;j++)
printf(“%d\t”,*(pint+j));
printf(“\n”);
}
}
Output:
1234 51
1235 52
1236 53
Example 2:
void print(int (*q)[4],int row, int col)
main()
{
int a[3][4]={
1, 2, 3, 4,
5, 6, 7, 8,
9, 0, 1, 6
};
print(a,3,4);
}
void print(int (*q)[4],int row, int col)
{
int i,j;
int *p;
for(i=0;i<row;i++)
{
p=q+i;
for(j=0;j<col;j++)
printf(“%d\t”,*(p+j));
printf(“\n”);
}
}
Output: 1 2 3 4
5 6 7 8
9 0 1 6
#include <stdio.h>
#include <time.h>
void Change(int *);
int main ()
{
int x=5;
printf("Before change: x= %d\n", x );
Change(&x);
printf("After change: x= %d\n", x );
}
#include <stdio.h>
double getAverage(int *arr, int size);
int main ()
{
int balance[5] = {1000, 2, 3, 17, 50};
double avg;
avg = getAverage( balance, 5 ) ;
printf("Average value is: %f\n", avg );
return 0;
}
double getAverage(int *arr, int size)
{
int i, sum = 0;
double avg;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = (double)sum / size;
return avg;
}
When the above code is compiled together and executed, it produces the following res ult:
Average value is: 214.40000
Output: Silicon
Limitations of pointers:
➢ Uninitialized pointers might cause segmentation fault.
➢ Dynamically allocated block needs to be freed explicitly. Otherwise, it would lead to
memory leak.
➢ Pointers are slower than normal variables.
➢ If pointers are updated with incorrect values, it might lead to memory corruption.
Basically, pointer bugs are difficult to debug. It is programmer’s responsibility to use pointers
effectively and correctly.
This function reserves a single block of memory (contiguous bytes) of specified size and
returns a pointer of type void. If it is successful it returns a pointer (of the cast type) to the
allocated memory else it returns NULL. The allocated memory will be filled with garbage
values.
Syntax: ptr=(cast type *) malloc(byte-size);
main()
{
int *p,n,i;
printf(“Enter the no of elements:”);
scanf(“%d”,&n);
p=(int *) malloc(n*sizeof(int));
for(i=0;i<n;i++)
{
printf(“Enter a no:”);
scanf(“%d”,p+i);
}
for(i=0;i<n;i++)
{
printf(“%d”,*(p+i));
}
}
calloc():
This function reserves multiple blocks of memory (contiguous bytes) of specified size and
returns a pointer of type void. If it is successful it returns a pointer (of the cast type) to the
allocated memory else it returns NULL.
The allocated memory will be filled with zeros.
Syntax: ptr=(cast type *)calloc(n,ele-size);
Example: ptr=(int *)calloc(10,sizeof(int));
free():
realloc():
This function allocates a new memory space of size newsize to the pointer variable ptr and
returns a pointer to the first byte of the new memory block. The new memory block may or
may not begin at the same place as the old one. In case it is not able to find additional space
in the same region, it will create the same in an entirely new regi on and move the contents
of the old block into the new block. If the function is unsuccessful in locating additional space,
it returns a NULL pointer and the original block is freed (lost).
Memory Leak:
A memory leak is memory which hasn't been freed, there is no way to access (or free it) now,
as there are no ways to get to it anymore. (E.g. a pointer which was the only reference to a
memory location dynamically allocated (and not freed) which points somewhere else now.)
void func()
{
char *ch;
ch = (char*) malloc(10);
}
In the above function ch is not valid outside, no way to access malloc-ed memory. The char
pointer ch is a local variable that goes out of scope at the end of the function, leaking the
dynamically allocated 10 bytes.
File Handling
We use printf() and scanf() to write and read data. These are console oriented I/O functions.
The console input device is keyboard and console output device is monitor. The console
oriented I/O operations have two major drawbacks.
1. It becomes difficult and time consuming to handle large volumes of data through
keyboard
2. The entire data is lost when the program is terminated
We frequently use files for storing information which can be processed by our programs. In
order to store information permanently and retrieve it when we need.
A file is a place on the disk where a group of related data is stored. File s are not only used for
data. Our programs are also stored in files. The editor which you use to enter your program
and save it, simply manipulates files for you. The Unix/Linux commands cat, cp, cmp are all
programs which process your files.
The standard library functions supported by C programming are given in the table below. To
use these function we need to include header file stdio.h
We will see that file I/O is almost identical to the terminal I/O that we have been using so far.
The primary difference between manipulating files and doing te rminal I/O is that we must
specify in our programs which files we wish to use. As you know, you can have many files on
your disk. If you wish to use a file in your programs, then you must specify which file or files
you wish to use.
The general syntax of opening the file is
FILE *fp;
fp = fopen(“filename”, “mode”);
Where FILE is a pre defined structure which is already defined in stdio.h. fp is pointer of data
type FILE. fopen() returns the address of this structure. Filename is string of characters that
make up a valid filename for the operating system. Mode specifies the purpose of opening a
file. Mode can be on the following:
Mode Purpose
r Open the file for reading only
w Open the file for writing only
a Open the file for adding data to it
r+ Open existing file for both read and write
w+ Same as w but both reading and writing
a+ Same as a but both reading and writing
Note: Because you may use a number of different files in your program, you must specify
when reading or writing which file you wish to use. This is accomplished by using a variable
called a file pointer.
Every file you open has its own file pointer variable. When you wish to write to a file you
specify the file by using its file pointer variable.
You declare these file pointer variables as follows:
FILE *fp1, *fp2, *fp3;
The variables fp1, fp2, fp3 are file pointers. You may use any name you wish.
The file <stdio.h> contains declarations for the Standard I/O library and should always be
included at the very beginning of C programs using files. Constants such as FILE, EOF and NULL
are defined in <stdio.h>. You should note that a file pointer is simply a variable like an integer
or character. It does not point to a file or the data in a file. It is simply used to indicate which
file your I/O operation refers to.
The function fopen is one of the Standard Library functions and returns a file pointer which
you use to refer to the file you have opened e.g.
The above statement opens a file called prog.c for reading and associates the file pointer fp
with the file prog.c. When we wish to access this file for I/O, we use the file pointer variable
fp to refer to it.
Note: While opening files, always check that fopen succeeds in opening the files
appropriately.
If the file cannot be opened, fopen() returns a NULL pointer. Thus by checking the file pointer
returned by fopen, you can determine if the file was opened correctly and take appropriate
action e.g.
fp = fopen (filename, “r”) ;
if ( fp == NULL)
{
printf(“Cannot open %s for reading \n”, filename );
exit(1) ; //Terminate program
}
Closing the file
The function fclose is used to close the file if we have finished processing the file by using the
following syntax:
fclose ( fp );
Note that, once the file is closed the buffer associated with the file is removed from the
memory. Once file is closed you cannot do any operation on that file unless the file is
reopened.
Input and operation on files: standard I/O
Once the file has been opened for reading using fopen(), then file’s content are brought into
the buffer and file pointer is set to the first character in the buffer. A predefined function
fgetc() is used to read the content of the file from memory. Thus the statement
c = getc(fp);
reads the next character from the file referenced by file pointer fp. Note that, getc( ) is used
to read a character from a file that has opened in read mode
#include <stdio.h>
main( )
{
FILE *fp; //declaration of file pointer
char c ;
fp = fopen( “prog.c”, “r” ); //open a file prog.c
//read content of the file until end of file has been reached
while ( (c=getc(fp)) != EOF )
{
putchar( c );
}
fclose( fp );
}
Output: (Assuming the prog.c file has the following content)
#include<stdio.h>
main()
{
printf(“Hello”);
}
In this program, we open the file prog.c for reading. Prog.c must exist in the present working
directory
We then read a character from the file. If the file is empty, we are at the end, so getc returns
EOF a special value to indicate that the end of file has been reached. The while loop simply
keeps reading characters from the file and displaying them, until the end of the file is reached.
This program is in effect a special purpose cat command in Linux. It displays file contents on
the screen, but only for a file called prog.c.
#include <stdio.h>
main( )
{
FILE *fp;
int nc=0, nlines=0;
char filename[40],c ;
printf(“Enter file name: “);
gets( filename );
fp = fopen( filename, “r” );
if ( fp == NULL )
{
printf(“Cannot open %s for reading \n”, filename );
exit(1); /* terminate program */
}
while ( (c =gets(fp))!=EOF )
{
if ( c == ‘\n’ )
nlines++ ;
nc++ ;
}
fclose( fp );
if ( nc != 0 )
{
printf(“There are %d characters in %s \n”, nc, filename );
printf(“There are %d lines \n”, nlines );
}
else
printf(“File: %s is empty \n”, filename );
}
The function exit() is a special function which terminates your program immediately. exit(0)
mean that you wish to indicate that your program terminated successfully whereas a nonzero
value means that your program is terminating due to an error condition.
Writing to a file
If the file does not exist already, it will be created. If the file does exist, it will be overwritten!
So, be careful when opening files for writing. Opening files for writing can also fail. If you try
to create a file in another users directory where you do not have access you will not be
allowed and fopen will fail.
putc( ) is used to write character to a file opened in write mode.
putc(c,fp);
This function writes the character c into file referenced by file pointer fp.
Example 3: Program to read data from keyboard write it to a file. Then read the data from the
data file and display it on the monitor.
#include<stdio.h>
main( )
{
FILE *fp;
char c;
fp=fopen(“input.dat”,”w”);
while((c=getchar())!=EOF)
{
//write char to input.dat
putc(c,fp);
}
//close the file input
fclose(fp);
//reopen
fp=fopen(“input.dat”,”r”);
//read from file input
while((c=getc(fp))!=EOF)
{
//display character from file
printf(“%c”,ch);
}
fclose(fp)
}
Output:
a
b
c
ctrl+z
a
b
c
#include <stdio.h>
main( )
{
FILE *fp1, *fp2;
char c ;
fp1 = fopen( “prog.c”, “r” ); /* open for reading */
fp2 = fopen( “prog.old”, “w” ) ; /* open for writing */
if ( fp1 == NULL ) /* check does file exist etc */
{
printf(“Cannot open prog.c for reading \n” );
exit(1); /* terminate program */
}
else if ( fp2 == NULL )
{
printf(“Cannot open prog.old for writing \n”);
exit(1); /* terminate program */
}
}
fclose ( fp1 ); /* Now close files */
fclose ( fp2 );
printf(“Files successfully copied \n”);
}
}
The fprintf() and fscanf() are predefined functions identical to printf() and scanf() except that
they work on files. The first argument of these functions is a file pointer which specifies the
file to be used. fprintf() is used to write to a file. The general form of fprintf() is:
fprintf(fp,%s%d%f”,name,age,y);
In the above example name is a string, age is an int variable and y is a float variable. fscanf ()
is used to read data from the file. The general form of fscanf () is
fscanf(fp,”controlstring”,list);
fscanf(fp,”%d”,&x);
Example 1: Program to write 1 to 30 to a data file and read these numbers and then write all
odd numbers to a file odd and all even numbers to a file even.
#include<stdio.h>
main( )
{
FILE *f1,*f2,*f3;
int i,x;
f1=fopen(“data”,”w”);
for(i=1;i<=30;i++)
{
//write 1 to 30 to file
fprintf(fp, “%d\t”,i);
}
fclose(f1);
f1=fopen(“data”,”r”);
f2=fopen(“even”,”w”);
f3=fopen(“odd”,”w”);
//read from data file and write to even and odd file
while( fscanf(f1,”%d”,&x) !=EOF )
{
if(x%2==0)
{
fprintf(f2, “%d\t”,i);
}
else
{
fprintf(f3, “%d\t”,i);
}
}
fclose(f1);
fclose(f2);
fclose(f3);
}
Example 2: Program to write employee information to a file and read them back
#include <stdio.h>
/* structure to hold employee information */
typedef struct employee {
char name[30];
int grade;
float salary;
}emp;
int main( )
{
FILE *fp;
char ch;
emp e;
fp = fopen("emp_info.txt", "w"); /* open file in write mode */
if (fp == NULL)
{
printf("Error opening file ...");
return 0;
}
do
{
printf("Employee Name : ");
scanf("%s", &e.name);
printf("Enter Grade : ");
scanf("%d", &e.grade);
printf("Enter Salary : ");
scanf("%f", &e.salary);
fprintf(fp, "%s %d %f\n", e.name, e.grade, e.salary) ; /* file write */
printf ( "Do you want to add another record (Y/y) " ) ;
fflush(stdin);
scanf("%c", &ch);
} while(ch == 'y' || ch == 'Y');
fclose(fp); /* close the file after writing */
printf("\nEmployee information saved in the file ... ");
printf("\nLet's read those information ...\n");
fp = fopen("emp_info.txt", "r"); /* open file in write mode */
if (fp == NULL) {
printf("Error opening file ...");
return 0;
}
/* read the file one record at a time */
while (fscanf(fp, "%s %d %f", e.name, &e.grade, &e.salary) != EOF) {
printf("\nName: %s\nGrade: %d\nSalary: %f\n", e.name, e.grade, e.salary);
}
fclose(fp); /* close the file after reading */
return 0;
}
#include<stdio.h>
main( )
{
FILE *fp;
long int len;
fp= fopen("file.txt", "r");
if( fp == NULL )
{
printf(“Error in opening file”);
exit(1);
}
fseek(fp,0,SEEK_END);
len=ftell(fp);
fclose(fp);
printf("Total size of file.txt = %d bytes\n", len);
}
rewind( ) - It moves the control to beginning of a file.
The C library function void rewind(FILE *stream) sets the file position to the beginning of the
file of the given stream.
fseek( ) - It is used to moves the file pointer to desired location with the file.
The C library function int fseek(FILE *stream, long int offset, int positon) sets the file position
of the stream to the given offset.
The offset to use (in bytes) when determining the new file pointer position.
The position can take one of the following 6 values:
Values Meaning
Note: The offset may be positive meaning move forward or negative means move backward.
}
The variable argc is an argument counter that counts the number of arguments on the
command line. The variable argv is an argument vector and represents an array of strings.
The size of this array will be equal to the value of argc.
In the above example the value of argc is 3. argv[0], argv[1], argv[2] contains ./a.out, 2 & 4
respectively.
Example:
main(int argc,char *argv[])
{
int sum=0,n,i;
for(i=1;i<argc;i++)
{
n=atoi(argv[i]);
sum+=n;
}
printf("Sum=%d",sum);
}
Run: ./a.out 2 4
Output: Sum=6
The C Preprocessor
Conceptually, the ``preprocessor'' is a translation phase that is applied to your source code
before the actual compilation starts. Generally, the preprocessor performs textual
substitutions on your source code, in three sorts of ways:
• Macro substitution: replacing instances of one piece of text with another.
• File inclusion: inserting the contents of another file into your source fi le
Now, if we ever want to change the size, we only have to do it in one place, and it's more
obvious what the words MAXLINE sprinkled through the program mean than the magic
numbers 100 did.
Since the replacement text of a preprocessor macro can be anything, it can also be an
expression, although you have to realize that, as always, the text is substituted (and perhaps
evaluated) later. No evaluation is performed when the macro is defined. For example,
suppose that you write something like
#define A 2
#define B 3
#define C A + B
Nesting of Macros
One macro can be defined inside another macro called nesting of macro.
Example:
#define SQUARE(x) ( (x) * (x) )
#define CUBE(x) (SQUARE(x) * (x))
#define SIXTH(x) (CUBE(x) * CUBE(x))
File Inclusion
causes the contents of the file filename.h to be read, parsed, and compiled at that point.
(After filename.h is processed, compilation continues on the line following the #include line.)
Example, suppose you got tired of retyping external function prototypes such as
extern int getline(char [], int);
at the top of each source file. You could instead place the prototype in a header file, perhaps
getline.h, and then simply place
#include "getline.h"
at the top of each source file where you called getline. (You might not find it worthwhile to
create an entire header file for a single function, but if you had a package of several related
function, it might be very useful to place all of their declarations in one header file.)
As we may have mentioned, that's exactly what the Standard header files such as stdio.h are -
-collections of declarations (including external function prototype declarations) having to do
with various sets of Standard library functions. When you use #include to read in a header
file, you automatically get the prototypes and other declarations it contains, and you should
use header files, precisely so that you will get the prototypes and other declarations they
contain.
Note: The difference between the < > and " " forms is where the preprocessor searches for
filename.h.
- It searches for files enclosed in < > in standard directories
- It searches for files enclosed in " " in the current directory, or the directory containing
the source file that's doing the including.
- The extension .h, stands for header file.
DISCLAIMER:
The courseware material prepared may contain some text, figures and diagrams taken
from google images and other readily available web sources. The contents are prepared for the
use of students in Silicon Institute of Technology as additional reference material, and not for
any commercial purpose.