programming in c and data structuresalphace.ac.in/downloads/notes/basic science/15pcd13.pdf ·...
TRANSCRIPT
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 1
MODULE I
INTRODUCTION TO C LANGUAGE: Pseudo code solution to problem, Basic
concepts of a C program, Declaration, Assignment & Print statement, Types of operators
and expressions, Programming examples and exercise.
INTRODUCTION TO COMPUTERS
Computer Systems: A computer is a system made up of 2 major components: hardware
and software. The computer hardware is the physical equipment. The software is the
collection of programs that allow the hardware to do its job.
Computer Hardware: The hardware component of the computer system contains 5
parts: input devices, CPU, primary storage, output devices and auxiliary devices.
Computer software: There are 2 categories: System software and Application software.
System software manages computer resources. It provides the interface between
the hardware and users but does nothing to directly serve the user needs.
Ex: There are 3 classes – OS, system support, system development.
Application software on the other hand is directly responsible for helping users
solve their problems.
Ex: 2 classes – General Purpose software and application specific software.
Computing Environments:
1. Personal Computing Environment
A personal computer (PC) is any general-purpose computer whose size,
capabilities, and original sales price make it useful for individuals, and which is intended
to be operated directly by an end-user with no intervening computer operator.
2. Time sharing Environment
In this many users are connected to one or more computers. These computers may
be mini computers or main frames. All computing must be done by central computer.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 2
3. Client/server Environment
This environment splits the computing function between a central computer and
user computer.
Computer Languages:
Machine language – made up of 0‘s and 1‘s.
An assembly language is a low-level language for programming
computers. It implements a symbolic representation of the numeric
machine codes and other constants needed to program a particular CPU
architecture. This representation is usually defined by the hardware
manufacturer, and is based on abbreviations (called mnemonics) that help
the programmer remember individual instructions, registers, etc. An
assembly language is thus specific to a certain physical or virtual
computer architecture (as opposed to most high-level languages, which are
portable).
A utility program called an assembler is used to translate assembly language
statements into the target computer's machine code. The assembler performs a
more or less isomorphic translation (a one-to-one mapping) from mnemonic
statements into machine instructions and data. This is in contrast with high-level
languages, in which a single Examples are MASM (Microsoft Assembler), TASM
(Turbo Assembler). If the inputted file is ADD.Asm, the assembler translates the
source code into object file ADD.OBJ that contains equivalent machine codes i.e.
binary instructions. The main disadvantage of assemblers is that, they are unique
to a particular model of computer.For example, 8086-based assembler is different
from PDP-11 assembler
Assembler is a language translator for low level assembly language's instructions.
It translates assembly programs into equivalent machine language's instructions or
ASSEMBLY
PROGRAM
(Source Program)
Machine Level
Program
(OBJECT CODE)
ASSEMBLER
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 3
binary codes.
statement generally results in many machine instructions.
A compiler, analogous to an assembler, is used to translate high-level language
statements into machine code.
Assembler- A computer program that takes computer instructions and converts
them into a pattern of bits that the computer can understand and perform by it
certain operations.
In 1950‘s symbolic language – soon it became – assembly language.
Assembler a special program is found to translate symbolic code into machine
language.
High level languages are portable and concentrate more on application problem.
Compiler- This is a special program that processes statements written in a
programming language and turns them into machine language that a computer's processor
uses
Conversion of high level to machine languages is done by compiler.
Machine-level -> Symbolic -> High-level -> Natural(evolving)
1940‘s 1950‘s 1960-80‘s 1990‘s
Writing, Editing, Compiling and linking programs:
It is the job of the programmer to write the program and then turn into an
executable (machine language) file. There are 3 steps in this process.
i. writing and editing program.
ii. Compiling
iii. Linking program with required library modules.
The software used to write programs is known as Text Editor.
Compiler: translates the code in the source file into machine language.
C compiler is actually 2 separate programs: preprocessor and the translator.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 4
The preprocessor reads the source code and prepares it for the translator. While
preparing the code, it scans for special commands known as preprocessor directives.
These directives tell the preprocessor to look for special code libraries, make substitution
in the code and in other ways prepare the code for translation into machine language. The
result of preprocessing is called Translation Unit.
The linker assembles all of these functions, ours and systems into final executable
program.
Program Execution:
Once program has been linked, it is ready for execution.
To execute our program, it must be loaded into primary memory. It is the function
of an Operating System program called Loader.
Operating System:
The system responsible for direct control and management of hardware and basic system
operations is called as an operating system.
Algorithm and Flowchart:
Algorithm:
It is a step by step process to solve specific problem (or) an algorithm is
composed of a finite set of steps each of which may require one or more operations.
Properties:
1. Definiteness.
2. Effectiveness.
3. Termination (finiteness)
4. Generality.
5. Input/output.
Flowchart:
It is a diagrammatic or pictorial representation of an algorithm
Symbols: A typical flowchart may have the following kinds of symbols
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 5
Memory Cell:
Entire RAM has been divided into number of equal parts, which are known as
memory cells. Each cell can store one byte of data.
ASCII (American Standard Code for Information Interchange):
ASCII is a standard alphanumeric code that represents numbers, alphabetic
characters and symbols using a 7-bit code format. The standard ASCII character set
consists of 128 decimal numbers ranging from 0 through 127, which are assigned to
letters, numbers, punctuation marks and the most common special characters.
Programming Languages:
Machine Languages (low-level [0‘s, 1‘s]).
Assembly (symbolic) languages.
Procedure Oriented Languages (high-level).
Programming Environment:
It comprises of all those components that facilitates development of a program.
Programming Tools API are the basic building blocks of any programming language.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 6
The software application which is used for the development, maintenance and
debugging of a software program is known as Programming Tool. Categories of
programming tools:
IDE.
Debugging tool (tool that helps to detect and remove bugs).
Memory usage tool (manages memory resources in a efficient manner).
Software Development Life Cycle (SDLC):
Analysis.
Designing.
Development.
Implementation and Testing.
Translator Programs:
1. Assembler: It is a computer program that translates assembly language
statements into machine language code.
2. Compiler: It is a computer program that translates the source code written in a
high-level language into the corresponding object code of low-level language. This
process is called Compilation.
3. Interpreter: It is a translator program that converts each high-level program
statement into machine code.
Example: BASIC and PERL.
Problem solving with Computers
As we know that the computer has no common sense, it is just an obedient servant, so a
lot of preparatory work concerned with problem solving has to be done before handing
over the work to the computer. The computer always demands unambiguous (non-
confusing) definition of the problem, which is simple to carry out and straight forward to
implement in order to solve the problem. At this level the user or programmer assumed to
have certain amount of background knowledge, reasoning skills and hints for problem
solving.
Steps involved problem solving using computers
Make a closer study of given problem and analyze it
Redefine the problem if necessary such that it should reveal clearly what is to
be done
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 7
Specify what is expected as an outcome of processing i.e. the result
Find a suitable solution method to solve the given problem
Based on above analysis, formulate a set of steps or procedural steps (known
as Algorithm) of the chosen method of solution.
Express the algorithm in precise notation and feed it to computer and compute
the results and reevaluate it.
Repeat the above steps till you get correct solution of given problem
Algorithms:
The finite set of procedural steps, where as each step is precise, unambiguous and
capable of being carried out by a machine in a finite time is known as Algorithm.
As computer expects unambiguous, precise and definite instructions or command
to solve a problem so the algorithm must be expressed in a ‗precise notation‘.
An algorithm when it is expressed in one of the precise notation is called as a
computer program. Before writing the computer program from algorithm an intermediate
step i.e. flow-charting is used.
Flow-chart:
A flow-chart is the pictorial representation of algorithmic steps to be performed
sequentially to arrive at the result. Actually the computer
program is written only after writing the flow-chart.
Ex 1) Problem Statement: - Find sum and average of three
numbers and print the result
Redefined problem: - Write a program to find the sum and
average of 3 float number. Accept 3 numbers from standard
input device and display the result on monitor
Outcome of process is sum and average of three numbers given
from input device.
Algorithm to add 3 numbers and prints sum and average.
Step 1. [First input the 3 numbers]
Input a, b, c
START
INPUT
A,B,C
SUM A+B+C
AVG SUM/3.0
SUM,AVG
END
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 8
Step 2. [Finding the sum of given numbers]
Sum <-- (a+b+c)
Step 3. [Finding the average]
Average <--- sum/3.0
Step 4. [Print the results]
Write sum, average
Step 5. [End of the algorithm]
End
Flowchart: - to find sum and average of three numbers
Characteristics of Algorithms
1. Input
Algorithm starts with a procedural step to accept input data. The subsequent steps in the
algorithm process these data elements. But this input step is optional and is used only
when the algorithm needs data at the time of execution.
2. Definite
Each operational step must be definite i.e. it should specify what should be done. In other
words there should not be any confusing instruction.
For example: 1) ―Compute 5/0‖
2) ―Add 5 or 10 to 5‖
Above statements are not allowed in algorithms because in first statement result of 5/0 is
infinity which is not defined in Computers and also in all branches of Mathematics. The
second statement, which of the two number 5 or 10 should be added to 4, is not clear.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 9
3. Effective
Each operation must be effective to carry out. Effectiveness property of an algorithm says
that each operational step can be at least in principle, being carried in a minimum amount
of time.
For example, analyze the mathematical formula given below
Y = PX3 + QX
2 + RX + S
The above statement can be written as C - statement as below
Y= (P*X*X*X)+(Q*X*X)+(R*X)+S;
But to execute the above statement, the computer has to do six multiplications and three
additions. We can modify the above formulas as below i.e.
===> Y=X (PX2+QX+R)+S
===> Y=X (X(PX+Q)+R)+S
In C-statement, this can be written as Y= X* (X* ((P* X) +Q) +R) +S.
Now there is only 3 multiplication and 3 additions. Therefore the above statement is more
efficient and takes less time for execution.
Let us consider another example: A = log (B2)-log (C
2) ----- (1)
In C-statement: A = log (B*B)-log(C*C);
But the equation (1) can be reduced as below: -
A = log (B2)-log (C
2)
A = log (B2/C
2)
A = log (B/C) 2
A = 2log(B/C)
In C: A = 2*log (B/C)
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 10
The above statement is more efficient because logarithmic function is called only once
and only one multiplication. This statement takes very less time for execution as only one
call for logarithmic function.
The computing speed decreases as we go from operations additions, subtractions,
multiplication, divisions, power( ) functions, logarithmic calculations, trigonometric
functions and other mathematical functions. Therefore one should try to replace slow
operations by faster operations as far as possible.
For examples:
Replace pow (x, 3) by x*x*x
Replace 3*y by y+y+y
Replace n/2.0 by n*0.5
Also try to avoid the repetitions of operations.
For example:
Repeated operations ( slow) more efficient (fast)
sum = a + b + c + d sum = a + b + c + d
avg = ( a + b + c + d ) / 4.0 avg = sum/4.0
4. Terminate
After some minimum number of operations, algorithm must come to an end i.e. the total
time to carry out all the steps in algorithm must be limited (finite).
5. Output
An algorithm is written to solve the problem therefore it must produce one or more
computed results.
In order to incorporate the definiteness property of the algorithm, algorithms will be
expressed using a precise notation called programming languages. Such computer
programming languages are designed to assign clarity, definiteness and effectiveness to
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 11
each of the instructions of the algorithm. The languages actually consist of all necessary
features to support the characteristics of an algorithm.
Basic Control structures in Algorithms
Usually the algorithm consists of finite set of sequential procedural steps. The algorithm
may have conditions, which are used to take decision, and depending upon decisions, a
particular group of statements is selected for execution. There are also situations in which
some of the statements have to execute repeatedly. So to meet above situations of
problem solving, algorithm uses 3 basic forms of control structures:
1. Sequencing
2. Branching (selections)
3. Repetitions (looping)
These are also called as program structures used in developing structured programs.
1. Sequencing
The sequence structure indicates the sequential flow of program logic i.e. step by step
execution program statement in the algorithm,
For example:
1) In algorithm:
Step 1: [Input the three numbers]
Input n1, n2, n3
Step 2: [Multiply given numbers and store the result in another variable]
Mult n1*n2*n3
Step 3: [Add all numbers and store the sum in another variable]
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 12
Sum n1+n2+n3
2) In Flowchart:
The step-by-step execution of statements in the algorithm (or in flowchart, programs) is
known as sequencing and sequential execution.
2. Branching (Selections)
Execution of a group of statements depending upon the given condition is known as
branching or selection. In algorithm if-then-else statement is used for branching
(selection). Its syntax is as below: -
if (condition) then
statement-1
statement-2
-
-
else
statement-a
statement-b
-
Here the condition is evaluated first and if the condition is true, the statements after
―then‖ is executed and if condition is false the statements after ―else‖ part is executed.
Here the ―else‖ part is optional and this is used only when it is required. For examples:
In Algorithm:
a) if ( a>0 ) then
write ―A is greater than 0‖
else
write ―A is not greater than 0‖
Input n1,n2,n3
Mul n1*n2*n3
Sum n1+n2+n3
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 13
x x+A
b) if ( a>0) then
write ―A is +ve number‖
x x + a
2) In Flowchart:
3. Repetitions (looping)
The repetitive execution of a group of statements or program
segment takes place as long as the loop condition is true and
when the loop condition became false the loop or repetition
will be terminated. This process is known as repetition or
looping.
1)In algorithms, repeat, for, do-while etc are used for
looping.
Ex: Algorithm for finding sum and numbers from 1 to N
Step 1: [Input a number]
Input N
Step 2: [Initialize the variable sum to zero]
Sum 0
Step 3: [calculate the sum by looping]
Do
Sum Sum+N
N N-1
No No Yes
Yes
condition
condtion
START
INPUT N
S 0
S S+N
N N-1
IS
N>0
END
PRINT S
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 14
while N>0
Step 4: [Print the sum of numbers]
Write Sum
Step 5:[End of the algorithm]
End
Some examples on Algorithms and Flowcharts:
1) Write and algorithm to accept temperature in Fahrenheit scale and convert into
Celsius scale and draw a flowchart.
Formula:- C = (F-32)/1.8 where F is Fahrenheit value and
C is Celsius value.
Algorithm : Temperature conversion from Fahrenheit
value to Celsius value.
Step 1: [Input temperature in Fahrenheit scale]
Input F
Step 2: [Compute centigrade temperature]
C (F-32)/1.8
Step 3: [Print the result]
Write ―Equivalent temperature in Celsius scale is ―,C
Step 5: [End of algorithm]
End
START
C (F-32)/1.8
PRINT C
READ FARH
END
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 15
2) Write an algorithm to find biggest of three numbers and draw the flowchart.
Algorithm: Finding the biggest of three numbers
Step 1: [Input three numbers from input device]
Input a,b,c
Step 2: [Store the first number in variable big assuming it as the biggest number]
Big a
Step 3: [Compare second value with big]
If b > big then big b
Step 4: [Compare second value with big]
If c > big then big c
Step 5: [Print the results]
Write ―Biggest number is ―,big
Step 6: [End of the algorithm]
End
Flowchart for biggest of three numbers.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 16
3) Write an algorithm to find the factorial of a number and also draw the flowchart.
Algorithm : To find the factorial of a given number
Step 1: [Input the number ]
Input N
Step 2: [Initialize the factorial number to 1]
START
STOP
PRINT BIG
READ A,B,C
IS C > BIG
IS B > BIG
BIG C
BIG B
BIG A
X
X
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 17
Fact 1
Step 3: [ Calculate factorial by looping]
Repeat for I=1 to N steps 1
Fact Fact * I
Loop
Step 4: [Print the factorial value]
Write ―Factorial of ―,N,‖ is‖,fact
Step 5: [End of the algorithm]
End
Flowchart to find the factorial value of given number
4) Write an algorithm to find the area of a triangle given its three sides
START
STOP
READ N
PRINT FACT
FACT 1
FACT FACT * I
NEXT
I
FOR I = 1 TO N
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 18
Algorithm: To find area of triangle given its three sides
Step 1: [Input the three sides of triangles]
Input A,B,C
Step 2: [Check the validity of given inputs and compute the area if the inputs valid]
IF ( (A+B)>C OR (B+C)>A OR(C+A)>B) then
S (A+B+C)/2
AREA = SQRT(S*(S-A)*(S-B)*(S-C))
Write ―Area of triangle is ―,AREA
ELSE
Write ―Given inputs are invalid‖
Step 3: [End of algorithm]
End.
INTRODUCTION • A computer is an electronic-device capable of manipulating
numbers and symbols under the control of a program. • A program is a sequence of
instructions written using a computer programming language to perform a specified task.
A PSEUDOCODE SOLUTION TO PROBLEM
Pseudo code is a method of describing the algorithm using a combination of
- Natural language (English like words) and
- Programming language
• This is essentially an intermediate-step towards the development of the actual code.
• Although pseudo code is frequently used, there are no set of rules for its exact writing.
• Psuedo code is used in textbooks and scientific publications to describe various
algorithms.
• For Example:
Problem 1: Input two numbers and display their sum.
1) read num1, num2
2) find sum = num1 + num2
3) display sum
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 19
Problem 2: Input the marks and display message ―passed‖ or ―failed‖ based on the marks.
1) read marks
2) if student's marks is greater than or equal to 35
print "passed"
else
print "failed"
end if
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 20
INTRODUCTION TO C
High Level Language (HLL) has been developed to facilitate easy programming
of the computers by any ordinary person. One such HLL is the C Language. It is
becoming so popular that the languages like BASIC, FORTRAN, and PASCAL are
becoming obsolete. This is because C being a High Level language satisfies the varying
requirements of programmers. It can be used for application program development as
well as system program development.
History of C
The history of C starts with a language called BCPL (Beginners Combined
Programming Language) developed by Martin Richards. In 1970, Mr. Ken Thompson, a
System Engineer at AT & T Bell Laboratories, USA, wrote an earlier version of C
language for the UNIX operating system. It is a modified version of the BCPL. Therefore
to distinguish his language from BCPL, he called the language as B language, the first
letter of BCPL. The B language was modified to a greater extent by Mr. Dennis Ritchie at
Bell Labs. This modified version of B is called as the C language, the second letter of
BCPL.
C was originally designed for UNIX operating system. But, later the whole UNIX
operating system itself was almost rewritten in C language. C is a powerful, general
purpose, procedure oriented, structured programming language.
About ANSI C Standard
For many years, the de facto standard for implementing the language has been the
original C Reference Manual by Kernighan and Ritchie published in 1978. During these
years, C has undergone many changes. Numerous different features and facilities have
been developed and added. This has resulted in minor problems in portability.
Consequently, the American National Standards Institute defined a standard for C,
eliminating much uncertainty about the exact syntax of the language. This newcomer,
called ANSI C, proclaims itself the standard version of the language. As such it will
inevitably overtake, and eventually replace common C. ANSI C does incorporate a few
improvements over the old common C. The main difference is in the grammar of the
language. The form of function declarations has been changed making them rather more
like Pascal procedures. The most important ANSI additions are:
1. A new format for declaring and defining functions.
2. Facility for doing floating point computations.
3. Two new type qualifiers const and volatile and two new data type enum and
void have been introduced.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 21
4. The preprocessor includes some new macros.
5. A standard ANSI C library has been defined.
Important features of C Language
1. C is a system programming language which provides flexibility for writing
compilers, operating systems, etc.
2. It can also be used for writing the application programs for scientific, engineering
and business applications.
3. C is famous for its portability, meaning that program written in C for one
computer can be easily loaded to another computer with little or no changes.
4. C supports variety of data types like integers, float point numbers, characters, etc.
5. C is a procedure oriented language which is most suited for structured
programming practice.
6. It provides a rich set of built in functions
7. Programs written in C are found to execute faster than compared to other
languages.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 22
Structure of the C Language
The general structure of the C language includes the following sections
1. The Documentation Section: It consists of a set of comment lines giving the name
of the program, the author and other details which the programmer would like to
use later. The comments are enclosed in a C program using /* and */ .
2. The Preprocessor directive or Link section: It provides instruction to the compiler
to link some functions or do some processing prior to the execution of the
program. It is also used to define symbolic constants of the program.
3. Global Declaration Section: There are some variables that are used in more than
one function. Such variables are called global variables and are declared in this
section that is outside of all other functions.
4. main () function section : Every C program must have one main() function. This
section contains two parts, declaration part and executable part. The declaration
part declares all the variables used in the executable part. There is atleast one
statement in the executable part. These two parts must appear between the
opening and closing braces. The program execution begins at the opening brace
and ends at the closing brace. The closing brace of the main function is the logical
end of the program. All statements in the declaration part and executable parts
must end with a semicolon.
Documentation Section
Preprocessor Directive or Link Section
Global Declaration Section
main() Function Section
{
}
Declaration Part
Executable Part
Sub program Section
Or
User Defined Function Section
/* Sample C Program */
main() {
int a,b;
clrscr();
printf(―Enter two numbers‖);
scanf(―%d%d‖, &a,&b);
sum = a + b;
printf(―Sum = %d‖, sum);
}
Example Program
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 23
5. Sub program Section: It contains all the user defined functions that are called in
the main () function. User defined functions are generally placed immediately
after the main function, although they may appear in any order.
All sections except the main () function may be absent when they are not required in
any C program.
Executing a C program
Executing a C program involves a series of following steps.
1. Creating a program
2. Compiling the program
3. Linking the program with functions that are needed from the C library.
4. Executing the program
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 24
In MS-DOS:
For Compiling press Alt-F9.
Program Code
System Ready
Enter program
Edit Source program
Source Program
Compile Source program C Compiler
Syntax
Errors?
Link with System Library System Library
Execute Object Code
Logic & Data
Errors?
Correct Output
Stop
Input Data
Data Error Logic Error
Executable Object Code
Object Code
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 25
For Compiling & Running the program: press Ctr-F9.
For viewing the results press Alt-F5.
Important points to remember:
1. Every C program requires a main() function. Use of more than one main() is
illegal. The place of main() is where the program execution begins.
2. The Execution of the function begins at the opening brace and ends at the closing
brace.
3. C programs are written in lowercase letters. However uppercase letters may be
used for symbolic names and constants.
4. All the words in a program line must be separated from each other by atleast one
space or a tab, or a punctuation mark.
5. Every statement must end with a semicolon.
6. All variables must be declared for their type before they are used in the program.
7. Compiler directives such as define and include are special instructions to the
compiler, so they do not end with a semicolon.
8. When braces are used in the program make sure that the opening brace has
corresponding ending brace.
9. C is a free form language and therefore proper form of indentation of various
sections would improve the legibility of the program.
10. A comment can be inserted almost anywhere a space can appear. Use of
appropriate comments in proper places increases the readability of the program
and helps in debugging an testing.
LEXICAL ELEMENTS OF THE C LANGUAGE
Like any other High level language, C provides a collection of basic building blocks,
symbolic words called lexical elements of the language. Each lexical element may be a
symbol, operator, symbolic name or word, a special character, a label, expression, reserve
word, etc. All these lexical elements are arranged to form the statements using the syntax
rules of the C language. Following are the lexical elements of the C language.
C Character Set
Every language has its own character set. The character set of the C language consists of
basic symbols of the language. A character indicates any English alphabet, digit or
special symbol including arithmetic operators. The C language character set includes
1. Letter, Uppercase A ….. Z, Lower case a….z
2. Digits, Decimal digits 0….9.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 26
3. Special Characters, such as comma, period. semicolon; colon: question mark?,
apostrophe‗ quotation mark ― Exclamation mark ! vertical bar | slash / backslash
\ tilde ~ underscore _ dollar $ percent % hash # ampersand & caret ^ asterisk *
minus – plus + <, >, (, ), [,], {, }
4. White spaces such as blank space, horizontal tab, carriage return, new line and
form feed.
C Tokens
In a passage of text, individual words and punctuation marks are called tokens. Similarly,
in C program, the smallest individual units are known as C tokens. C has following
tokens
1. Keywords or Reserve words such as float, int, etc
2. Constants such 1, 15,5 etc
3. Identifiers such name, amount etc
4. Operators such as +, -, * etc
5. Separators such as :, ;, [, ] etc and special characters
6. Strings
Keywords
Key words or Reserve words of the C language are the words whose meaning is already
defined and explained to the C language compiler. Therefore Reserve words can not be
used as identifiers or variable names. They should only be used to carry the pre-defined
meaning. For example int is a reserve word. It indicates the data type of the variable as
integer. Therefore it is reserved to carry the specific meaning. Any attempt to use it other
than the intended purpose will generate a compile time error. C language has 32
keywords. Following are some of them
auto break case char const continue default
do double else enum extern float for
goto if int long register return short
signed sizeof static struct switch typedef union
unsigned void volatile while
Constants
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 27
A constant can be defined as a value or a quantity which does not change during the
execution of a program. Meaning and value of the constant remains unchanged
throughout the execution of the program. These are also called as literals. C supports
following types of constant.
1. Integer Constants
An integer constant refers to a sequence of digits. There three types of integer constants,
namely decimal, octal and hexadecimal.
Decimal integer constant consists of set of digits from 0 to 9 preceded by an optional +
or – sign.
Ex: 123, -321, 0, 4567, + 78
Embedded spaces, commas and non-digit characters are not permitted between digits.
An octal integer constant consists of any combination of digits from 0 to 7 with a leading
0(zero). Ex : 037, 0435, 0567
A sequence of digits preceded by 0x or 0X is considered as hexadecimal digit. They may
also include alphabets A to F or a to f representing numbers from 10 to 15.
The largest integer value that can be stored is machine dependant; It is 32767 for 16 bit
computers. It is also possible to store larger integer constants by appending qualifiers
such U, L and UL to the constants.
2. Floating point Constants or Real Constants
The quantities that are represented by numbers with fractional part are called floating
point numbers. Ex: 0.567, -0.76, 56.78, +247.60. These numbers are shown in decimal
notation , having a whole number followed by a decimal point and the fractional part. It is
possible to omit digits before the decimal point or digits after the decimal point. Ex: 215.,
.95, -.76 or +.5
A real number or a floating point number can also expressed as in exponential notation.
Ex: 2.15E2. The general form of exponential notation is
mantissa e exponent or mantissa E exponent
The mantissa is either a real number or an integer. The exponent is an integer with an
optional plus or minus sign. Embedded white is not allowed in this notation.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 28
3. Single Character constants
A single character constant contains a any valid character enclosed within a pair of single
quote marks. Ex: ‗5‘, ‗A‘, ‗;‘ ‗ ‗. The character constants have integer values associated
with them known as ASCII values. For ex: A is having the ASCII value of 65.
4. String constants
A string constant is a sequence of characters enclosed in double quotes. The characters
may be alphabets, numbers special characters and blank space. Ex: ―Hello‖, ―2002‖,
―Wel Come‖, ―5+3‖
5. Backslash character constants or Escape sequence characters.
C supports some special backslash character constants that are used in output functions.
For ex: ‗\n‘ stands for new line characters. Each one of them represents a single character
even though it consists of two characters.
\a Audible alert or bell \b back space
\f form feed \n new line
\r carriage return \t horizontal tab
\v vertical tab \‘ single quote
\‖ double quote \? Question mark
\\ backslash \0 null
Identifiers
An identifier is a sequence of letters, digits and an underscore. Identifiers are used to
identify or name program elements such as variables, function names, etc. Identifiers give
unique names to various elements of the program. Some identifiers are reserved as
special to the C language. They are called keywords.
Variables
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 29
A variable is a data name that may be used to store data value. A value or a quantity
which may vary during the program execution can be called as a variable. Each variable
has a specific memory location in memory unit, where numerical values or characters can
be stored. A variable is represented by a symbolic name. Thus variable name refers to the
location of the memory in which a particular data can be stored. Variables names are also
called as identifiers since they identify the varying quantities.
For Ex : sum = a+b. In this equation sum, a and b are the identifiers or variable names
representing the numbers stored in the memory locations.
Rules to be followed for constructing the Variable names(identifiers)
1. They must begin with a letter and underscore is considered as a letter.
2. It must consist of single letter or sequence of letters, digits or underscore
character.
3. Uppercase and lowercase are significant. For ex: Sum, SUM and sum are three
distinct variables.
4. Keywords are not allowed in variable names.
5. Special characters except the underscore are not allowed.
6. White space is also not allowed.
7. The variable name must be 8 characters long. But some recent compilers like
ANSI C supports 32 characters for the variable names and first 8 characters are
significant in most compilers.
Data Types
Data refers to any information which is to be stored in a computer. For example, marks of
a student, salary of a person, name of a person etc. These data may be of different types.
Computer allocates memory to a variable depending on the data that is to be stored in the
variable. So it becomes necessary to define the type of the data which is to be stored in a
variable while declaring a variable. The different data types supported by C are as
follows:
int Data Type
Integer refers to a whole number with a range of values supported by a particular
machine. Generally integers occupy one word of storage i.e 16 bits or 2 bytes. So its
value can range from -32768 to +32767.
Declaration: int variable name;
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 30
Ex: int qty;
The above declaration will allocate a memory location which can store only integers,
both positive and negative. If we try to store a fractional value in this location, the
fractional data will be lost.
float Data Type
A floating point number consists of sequence of one or more digits of decimal number
system along with embedded decimal point and fractional part if any. Computer allocates
32 bits, i.e. 4 bytes of memory for storing float type of variables. These numbers are
stored with 6 digits of precision for fractional part.
Declaration: float variableName; Ex : float amount;
double Data Type
It is similar to the float type. It is used whenever the accuracy required to represent the
number is more. In others words variables declared of type double can store floating
point numbers with number of significant digits is roughly twice or double than that of
float type. It uses 64 bits i.e. 8 bytes of memory giving a precision of 14 decimal digits.
Declaration : double variableName;
char Data Type
A single character can be defined as char data type. These are stored usually as 8 bits i.e 1
byte of memory.
Declaration : char variableName ; Ex: char pass;
String refers to a series of characters. Strings are declared as array of char types.
Ex: char name[20]; will reserve a memory location to store upto 20 characters.
Further, applying qualifiers to the above primary data types yield additional data types. A
qualifier alters the characteristics of the data type, such as its sign or size. There are two
types of qualifiers namely, sign qualifiers and size qualifiers.
signed and unsigned are the sign qualifiers
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 31
short and long are the size qualifiers.
Size and range of data types on a 16 bit Machine
Type Size (bits) Range
char or signed char 8 -128 to 127
unsigned char 8 0 to 255
int 16 -32768 to 32767
unsigned int 16 0 to 65535
short int or signed short int 8 -128 to 127
unsigned short int 8 0 to 255
long int or signed long int 32 -2,147,483,648 to
2,147,483,647
unsigned long int 32 0 to 4,294,967,295
Float 32 3.4e-38 to 3.4e+38
Double 64 1.7e-308 to 1.7e+308
long double 80 3.4 e-4932 to 1.1e+4932
Assigning Values to Variables
Values can be assigned to variables using assignment operator ―=‖.
Syntax:
Variable name = value;
Ex: a = 10; initial value = 0;
It is also possible to assign a value to a variable at the time the variable is declared. The
process of giving initial value to the variable is called initialization of the variable.
Ex:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 32
int a=10, b=5;
float x=10.5, y=1.2e-9
Declaring a variable as constant
We may want the value of the certain variable to remain constant during the execution of
the program. We can achieve this by declaring the variable with const qualifier at the
time of initialization.
Ex;
const int tax_rate = 0.30;
The above statement tells the compiler that value of variable must not be modified
during the execution of the program. Any attempt change the value will generate a
compile time error.
Declaring a variable as volatile
Declaring the variable volatile qualifier tells the compiler explicitly that the variable‘s
value may be changed at any time by some external source and the compiler has to check
the value of the variable each time it is encountered.
Ex;
volatile int date;
Defining Symbolic Constants
We often use certain unique constants in a program. These constants may appear
repeatedly in number of places in a program. Such constants can be defined and its value
can be substituted during the preprocessing stage itself.
Syntax:
#define symbolic-name value of constant
ex:
#define PI 3.14
#define MAX 100
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 33
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 34
OPERATORS IN C
An operator is a symbol which acts on operands to produce certain result as output. For
example in the expression a+b; + is an operator, a and b are operands. The operators are
fundamental to any mathematical computations.
Operators can be classified as follows:
1. Based on the number of operands the operator acts upon:
a. Unary operators: acts on a single operand. For example: unary minus(-5, -
20, etc), address of operator (&a)
b. Binary operators: acts on two operands. Ex: +, -, %, /, *, etc
c. Ternary operator: acts on three operands. The symbol ?: is called ternary
operator in C language. Usage: big= a>b?a:b; i.e if a>b, then big=a else
big=b.
2. Based on the functions
a. Arithmetic operators
b. Relational operators
c. Logical Operators
d. Increment and Decrement operators
e. Assignment operators
f. Bitwise operators
g. Conditional Operators
h. Special operators
Arithmetic operators:
C provides all the basic arithmetic operators. The operators +,-,* and / all work the
same way as they do in other languages. These can operate on any built-in data type
allowed in C. The unary minus operator, in effect, multiplies its single operand by -1.
Therefore, a number preceded by a minus sign changes its sign.
Operator Meaning
+ Addition
- Subtraction
* Multiplication
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 35
/ Division
% Modulo division
Integer division truncates any fractional part. The modulo division produces the
remainder of an integer division and can be used only on integer operands.
Examples:
1) If a and b are integers and a =14
and b = 3, then
a + b = 14 + 3 = 17
a – b = 14 – 3 = 11
a * b = 14 * 3 = 42
a / b = 14 / 3 = 4
a % b = 14 % 3 = 2
2) -14 / 3 = -4
-14 / -3 = 4
14 / -3 = -4
-14 % 3 = -2
-14 % -3 = -2
14 % -3 = 2
2 % 3 = 2
2 / 3 = 0
Here a and b are variables and are known as operands. The modulo divison operator
% cannot be used on floating point data.
Arithmetic expressions:
An arithmetic expression is a combination of variables, constants and operators arranged
as per the syntax of the language. Expressions are evaluated using an assignment
statement of the form
Variable=expression;
The table below shows the algebraic expression and C language expression
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 36
Algebraic expression C expression
a b-c a*b-c
(m + n) (x + y) (m + n) *(x + y)
(a b)/c a*b/c
3x2+2x+1 3*x*x+2*x+1
Variable is any valid C identifier. When the statement is encountered, the expression is
evaluated first and the result then replaces the precious value of the variable on the left-
hand side. All variables used in the expression must be assigned values before evaluation
is attempted.
x=a*b-c;
y=b/c*a;
z=a-b/c+d;
The blank space around an operator is optional and adds only to improve readability.
When these statements are used in a program, the variables a ,b ,c and d must be defined
before they are used in the expressions.
Modes of expression:
There are three different modes of expressions.
1. Integer Arithmetic
2. Real Arithmetic
3. Mixed-mode Arithmetic
Integer Arithmetic
When both the operands in a single arithmetic expression such as a+b are integers, the
expression is called an integer expression, and the operation is called integer arithmetic.
This mode of expression always yields an integer value. The largest integer value
depends on the machine, as pointed out earlier
Example:
If a and b are integers then for a=14 and b=4
We have the following results:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 37
a - b=10
a + b = 18
a * b = 56
a / b = 3
a % b = 2
During integer division, if both the operands are of the same sign, the result is truncated
towards zero. If one of them is negative, the direction of truncation is implementation
dependent. That is,
6/7=0 and -6/-7=0
but -6/7 may be zero or -1 (Machine dependent)
Similarly, during modulo division, the sign of the result is always the sign of the first
operand(the dividend)
That is
-14 % 3 =-2
-14 % -3= -2
14 % -3=2
Real Arithmetic
An arithmetic operation involving only real operands is called real arithmetic. A real
operand may assume values either in decimal or exponential notation. Since floating
point values are rounded to the number of significant digits permissible, the final value is
an approximation of the correct result. If x, y, and z are floats, then we will have:
x=6.0/7.0=0.857143
y= 1.0/3.0 =0.333333
z= -2.0/3.0= -0.666667
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 38
The operator % cannot be used with real operands.
Mixed- mode Arithmetic
When one of the operands is real and the other is integer, the expression is called a
mixed-mode arithmetic expression. If either operand is of the real type, then only the real
operation is performed and the result is always a real number.
Thus 15/10.0=1.5 where as 15/10=1
Arithmetic operator’s precedence:-
In a program the value of any expression is calculated by executing one arithmetic
operation at a time. The order in which the arithmetic operations are executed in an
expression is based on the rules of precedence of operators.
The precedence of operators is :
Unary (-) FIRST
Multiplication(*) SECOND
Division(/) and (%)
Addition(+) and Subtraction(-) LAST
For example, in the integer expression –a *b/c+d the unary- is done first, the result –a is
multiplied by b, the product is divided by c(integer division) and d is added to it. The
answer is thus:
-ab/c+d
All the expressions are evaluated from left to right. All the unary negations are done first.
After completing this the expression is scanned from left to right; now all *, / and %
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 39
operations are executed in the order of their appearance. Finally all the additions and
subtractions are done starting from the left of the expression..
For example, in the expression:
Z=a + b* c
Initially b*c is evaluated and then the resultant is added with a. Suppose if want to add a
with b first, then it should be enclosed with parenthesis, is shown below
Z = (a + b) * c
Use of parentheses:
Parentheses are used if the order of operations governed by the precedence rules are to
overridden.
In the expression with a single pair of parentheses the expression inside the parentheses is
evaluated FIRST. Within the parentheses the evaluation is governed by the precedence
rules.
For example, in the expression:
a * b/(c+d * k/m+k)+a
the expression within the parentheses is evaluated first giving:
c+dk/m+k
After this the expression is evaluated from left to right using again the rules of
precedence giving
ab/c+dk/m+k +a
If an expression has many pairs of parentheses then the expression in the innermost
pair is evaluated first, the next innermost and so on till all parentheses are removed.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 40
After this the operator precedence rules are used in evaluating the rest of the
expression.
((x * y)+z/(n*p+j)+x)/y+z
xy, np+j will be evaluated first.
In the next scan
xy+z/np+j +x
Will be evaluated. In the final scan the expression evaluated would be:
(xy+ z/np+j+x)/y +z
Increment and Decrement operators:-
The increment operator ++ and decrement operator – are unary operators with the
same precedence as the unary -, and they all associate from right to left. Both ++ and
– can be applied to variables, but no to constants or expressions. They can occur in
either prefix or postfix position, with possibly different effects occurring. These are
usually used with integer data type.
The general syntax is:
++variable or --variable or variable++ or variable—
Some examples are
++count -kk index++ unit_one--
We use the increment and decrement statements in for and while extensively.
Consider the following example
m=5;
y=++m;
In this case, the value of y and m would be 6. Suppose, if we rewrite the above
statements as
m=5;
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 41
y=m++;
then the value of y would be 5 and m would 6. A prefix operator first adds to 1 to the
operand and then the result is assigned to the variable on left. On the other hand, a
postfix operator first assigns the value to the variable on left and then increments the
operand.
Similar is the case, when we use ++(or--) in the subscripted variables. That is, the
statement a[i++]=10;
is equivalent to
a[i]=10;
i=i+1;
The increment and decrement operators can be used in complex statements. Example
m=n++ -j+10;
Old value of n is used in evaluating the expression. n is incremented after the
evaluation.
Relational operators:
We often compare two quantities and depending on their relation, to take certain
decisions. For example, we may compare the age of two persons, or the price of two
items, and so on. These comparisons can be done with the help of relational
operators.
C supports six relational operators in all. These operators and their meanings are
shown below Relational Operators
Operator Meaning
< is less than
> is greater than
<= is less than or equal to
>= is greater than or equal to
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 42
= = is equal to
!= is not equal to
A simple relational expression contains only one relational operator and has the following
form:
ae-1 relational operator ae-2
ae-1 and ae-2 are arithmetic expressions, which may be simple constants, variables or
combination of them. Given below are some examples of simple relational expressions
and their values:
4.5 <= 10 TRUE
4.5 < 10 FALSE
-35 >= 0 FALSE
10 < 7+5 TRUE
a+b == c+d TRUE only if the sum of values of a and b is equal to
the sum c & d.
When arithmetic expressions are used on either side of a relational operator, the
arithmetic expressions will be evaluated first and then the results compared. That is,
arithmetic operators have a higher priority over relational operators. Relational
expressions are used in decision statements such as, if and while to decide the course of
action of a running program.
Logical operators:
In addition to the relational operators, C has the following three logical operators.
&& logical AND
|| logical OR
! logical NOT
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 43
The logical operators && and || are used when we want to test more than one condition
and make decisions.
Example: a>b && x == 10
An expression of this kind which combines two or more relational expression is termed
as a logical expression or a compound relational expression. Like the simple relational
expressions , a logical expression also yields a value of one or zero, according to the truth
table shown below. The logical expression given above is true only if a>b is true and
x==10 is true. If either (or both) of them are false, the expression is false.
Truth Table
Op-1 op-2 Value of the expression
Op-1 && op-2 op-1 || op-2
Non-zero Non-zero 1 1
Non-zero 0 0 1
0 Non-zero 0 1
0 0 0 0
Some examples of the usage of logical expressions are:
1. If(age>55 && salary <1000)
2. If (number<0 || number>100)
Relational and logical expressions:
We have seen that float or integer quantities may be connected by relational operators to
yield an answer which is true of false.
For example the expression,
Marks>=60
would have an answer true if marks is greater than or equal to 60 and false if marks is
less than 60. The result of the comparison (marks>=60) is called a logical quantity. C
provides a facility to combine such logical quantities by logical operators to logical
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 44
expressions. These logical expressions are useful in translating intricate problem
statements.
Example : A university has the following rules for a student to qualify for a degree with
Physics as the main subject and Mathematics as the subsidiary subject:
(i) He should get 50 percent or more in Physics and 40 percent or
more in Mathematics.
(ii) If he gets less than 50 percent in Physics he should get 50 percent
or more in Mathematics. He should get atleast 40 percent in
Physics.
(iii) If he gets less than 40 percent in Mathematics and 60 percent or
more in Physics he is allowed to reappear in an examination in
Mathematics to qualify.
(iv) In all the other cases he is declared to have failed.
/*This program implements above rules*/
include<stdio.h>
main()
{
int roll_no, physics_marks, chem_marks;
while(scanf(―%d %d %d‖, &roll_no, &physics_marks, &chem_marks)!=EOF)
{
If(((chem_marks>=50 && (physics_marks>=35)) || ((chem_marks>=40)) &&
(physics_marks>=50)))
printf(―%d %d %d Pass\n‖, roll_no, chem_marks, physics_marks);
else
if (( chem_marks>=60)) && physics_marks<35))
printf(―%d %d %d Repeat Physics\n‖, roll_no,physics_marks,chem_marks);
else
printf(―%d %d %d Failed \n‖, roll_no, physics _marks, chem_marks);
}
}/*End while*/
}/*End main*/
Precedence of relational operators and logical operators:
Example:
(a>b *5) &&(x<y+6)
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 45
In the above example, the expressions within the parentheses are evaluated first. The
arithmetic operations are carried out before the relational operations. Thus b*5 is
calculated and after that is compared with it. Similarly y+6 is evaluated first and then x is
compared with it .In general with in parentheses:
1. The unary operations, namely, -,++,--,! (logical not) are performed
first.
2. Arithmetic operations are performed next as per their precedence.
3. After that the relational operations in each sub expressions are
performed, each sub expression will be a zero or non _ zero. If it is
zero it is taken as false else it is taken as true.
4. These logical values are now operated on by the logical operators.
5. Next the logical operation && is performed next.
6. Lastly the evaluated expression is assigned to a variable name as per
the assignment operator.
The conditional operator:
An operator called ternary operator pair ―?:‖ is available in C to construct conditional
expressions of the form.
exp1? exp2: exp3;
Where exp1,exp2, and exp3 are expressions.
The operator?; works as follows: exp1 is evaluated first. If it is nonzero(true), then the
expression exp2 is evaluated and becomes the value of the expression. If exp1 is false,
exp3 is evaluated and its value becomes the value of the expression. Note that only one of
the expressions (either exp2 or exp3) is evaluated.
For example, consider the following statements
x=3;
y=15;
z=(x>y)?x:y;
In this example, z will be assigned the value of b. This can be achieved using the if..else
statements as follows:
If (x>y)
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 46
z=x;
else
z=b;
Bitwise operators:
All data items are stored in the computer‘s memory as sequence of bits (i.e. 0s and 1s)
and some applications need the manipulation of bits. C has a distinction of supporting
special operators known as bitwise operators for manipulation of data at bit level. These
operators are used for testing the bits, or shifting them right or left. Bitwise operators may
not be applied to float or double.
Operator Meaning
& bitwise AND
| bitwise OR
^ bitwise exclusive OR
<< shift left
>> shift right
~ One‘s Complement
The result of bitwise AND operator is 1 when both the bits are 1, otherwise it is 0.
Similarly the result of bitwise OR is one if any one of the bit is 1, otherwise it is 0. The
result of bitwise XOR is 1 when the bits are different. The bitwise complement operator
reverses the state of each bit. i.e. if the bit is zero, complement of it will 1 and vice versa.
Ex: int a =5, b=3;
Then equivalent binary representation of a = 5 = 0000 0101 and b=3= 0000 0011
Therefore
a = 0000 0101
b = 0000 0011
a & b = 0000 0001 = 1
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 47
a | b = 0000 0111 = 7
a ^ b = 0000 0110 = 6
~a = 1111 1010
a << 1 = 0000 1010 = 10 equivalent to multiplying a by 2
a >> 1 = 0000 0010 = 2 equivalent to dividing a by 2
Special Operators
1) Comma Operator
C has some special operators. The comma operator is one among them. This operator
can be used to link the related expressions together. A comma-linked list of expressions
are evaluated left to right and the value of right-most expression is the value of the
combined expression.
For example, the statement
Value=(a=2, b=6 ,a+b);
First assigns the value 2 to a, then assigns 6 to b, and finally assigns 8(i.e 2+6) to value.
The comma operator has the lowest precedence of all operators,hence the parentheses are
necessary.
Some examples are given below:
In for loops:
for(a=1, b=10;a<=b; a++, b++)
In while loops:
while(c=getchar(), C!=‘10‘)
Exchanging values:
t=x, x=y, y=t;
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 48
2) sizeof operator
The sizeof operator returns the memory size (in bytes) of the operand. The operand may
be a constant, variable or a data type. It is normally used to determine the size of arrays
and structures. Its syntax is as follows:
sizeof(operand);
Example : x = sizeof(int); will return 2
y = sizeof(10.2) will return 4 since a float point constant requires 4 bytes of
memory
z = sizeof(x) will return 2
Example program:
main()
{
int x;
double y;
char ch=‘y‘;
clrscr();
printf(―Size of x = %d\n‖, sizeof(x));
printf(―Size of y = %d\n‖, sizeof(double));
printf(―Size of char = %d\n‖, sizeofch));
getch();
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 49
Precedence and Associativity of operators:
Each operator in C has a precedence associated with it. This precedence is used to
determine how an expression involving more than one operator is evaluated. The operator
at the higher level of precedence are evaluated first.
The operators of the same precedence are evaluated either from left to right or from right
to left depending on the level. This is known as the associatively property of an operator.
Operator Description Level Associativity
( )
[ ]
Parenthesis
Array index
1 L – R
+
-
++
--
!
~
&
sizeof(type)
Unary plus
Unary minus
Increment
Decrement
Logical negation
One‘s Complement
Address of
type cast conversion
2 R – L
*
/
%
Multiplication
Division
Modulus
3 L- R
+
-
Addition
Subtraction 4 L – R
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 50
<<
>>
Left Shift
Right Shift 5 L – R
<
<=
>
>=
Less than
Less than or equal to
Greater than
Greater than or equal
to
6 L – R
= =
! =
is equal to
Not equal to 7 L – R
& Bitwise AND 8 L – R
^ Bitwise XOR 9 L – R
| Bitwise OR 10 L – R
&& Logical AND 11 L – R
| | Logical OR 12 L – R
? : Conditional Operator 13 R – L
=,
+=, -=, *=, /=, %=
Assignment operator
Short hand
assignement
14 R – L
, Comma operator 15 R – L
Evaluation of expressions involving all the above type of operators:
The following expression includes operators from six different precedence groups.
Consider variables x, y , z as integer variables.
Z+=(x0>0 && x<=10) ? ++x : x/y;
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 51
The statement begins by evaluating the complex expression
(x>0 && x<=10)
If this expression is true, the expression ++x is evaluated. Other wise, the a/b is
evaluated. Finally, the assignment operation(+=) is carried out, causing the value of c to
be increased by the value of the conditional expression.
If for example x, y, and z have the values 1,2,3 respectively, then the value of the
conditional expression will be 2(because the expression ++a will be evaluated), and the
value of z will increase to 5(z=3+2). On the other hand, if x,y and z have the values
50,10,20 respectively, then the value of the conditional expression will be 5(because the
expression x/y will be evaluated) and the value of z will increase to 25(z=20+5).
Mathematical Functions:
In c there are no built-in mathematical functions. The table below shows the
mathematical functions.
Function Meaning
Trigonometric
1. acos(x) Arc cosine of x
2. asin(x) Arc sine of x
3. atan(x) Arc tan of x
4. atan2(x,y) Arc tangent of x/y
5. cos(x) cosine of x
6. sin(x) sine of x
7. tan(x) tangent(x)
Hyperbolic
1. cosh(x) Hyperbolic cosine of x
2. sinh(x) Hyperbolic sine of x
3. tanh(x) Hyperbolic tangent of x
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 52
Other functions
ceil(x) x rounded up to the nearest integer
exp(x) e to the power x
fabs(x) Absolute value of x
floor(x) x rounded down to the nearest
integer
fmod(x,y) Remainder of x/y
log(x) Natural log of x, x>0
log 10 (x) Base 10 log of x, x>0
pow(x,y) x to the power y
sqrt(x) Square root of x, x>=0
Note:
1. x and y should be declared as double
2. In trigonometric and hyperbolic functions, x and y are in radians
3. All the functions return a double.
Preprocessor directives:
There are different preprocessor directives. The table below shows the preprocessor
directives.
Directive Function
#define defines a macro substitution
#undef Undefines a macro
#include Specifies the files to be included.
#ifdef Tests for a macro definition
#endif Specifies the end of #if
#ifndef Tests whether a macro is not defined
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 53
#if Tests a compile-time condition
#else Specifies alternatives when #if tests
fails
#define statement:
One of the uses of the #define statement is for assigning symbolic names to
program constants.
The general syntax is :
#define TRUE 1
defines the name TRUE and makes it equivalent to the value 1. The name TRUE can
subsequently be used anywhere in the program where the constant 1 could be used.
Whenever this name appears, its defined value of 1 will be automatically substituted into
the program by the preprocessor. For example, we might have the following C statement
that uses the defined name TRUE
count=TRUE;
This statement would assign the value of TRUE to count.
The preprocessor statement
#define FALSE 0
would define the name FALSE and would make its subsequent use in the program
equivalent to specifying the value 0. Therefore, the statement
count=FALSE;
would assign the value of FALSE to count and the statement
If (count = = FALSE)
……
would compare the value of count against the defined value of FALSE.
#define TRUE 1
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 54
#define FALSE 0
/*Function to determine if an integer is even*/
main()
{
int number,ans;
printf(―enter the number:‖);
scanf(―%d‖ , &number);
if (number%2==0)
{
ans=TRUE;
else
ans=FALSE;
}
}
Some more examples of definition constants:
#define COUNT 100
#define SUBJECTS 6
#define PI 3.1415
#define CAPITAL ―BANGALORE‖
#include statement:
C preprocessor enables you to collect all your definitions into a separate file and then
include them in your program using the #include statement.
The general statement for this preprocessor directive is:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 55
#include ―filename‖
The #include directive can take the form
#include<filename>
without double quotation marks. In this case, the file searched only in the standard
directories.
#include <stdio.h>
#include ―SYNTAX.C‖
#include ―STAT.C‖
#include ―TEST.C‖
Header files:
C language offers simpler way to simplify the use of library functions to the greatest
extent possible. This is done by placing the required library function declarations in
special source files, called header files. Most C compilers include several header files,
each of which contains declarations that are functionally related. stdio.h is a header file
containing declarations for input/ouput routines; math.h contains declarations for certain
mathematical functions and so on. The header files also contain other information related
to the use of the library functions, such as symbolic constant definitions.
The required header files must be merged with the source program during the
compilation process. This is accomplished by placing one or more #include statements at
the beginning of the source program.
The other header files are:
<ctype.h> character testing and conversion functions
<stdlib.h> utility functions such as string conversion routines , memory allocation
routines, random number generator, etc
<string.h> String manipulations functions
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 56
<time.h> time manipulation functions
Input and Output Functions
The C language consists of input-output statements to read the data to be processed as
well as output the computed results. C language provides a set of library functions or
built in functions, in order to carry out input and output operations. These library
functions are available in a header file called stdio.h. So for using these library functions
the following preprocessor directive is essential
# include <stdio.h>
The input and output functions in C language can be broadly categorized into two types:
1. Unformatted Input Output functions : which provides the facility to read or
output data as a characters or sequence of characters. Ex: getch(), getche(),
getchar(), gets(), putch(), purchar() and puts().
2. Formatted I/O functions : which allow the use format specifiers to specify the
type of data to be read or printed. Ex: scanf() and printf() functions.
scanf function:-
The function scanf() is used to read data into variables from the standard input, namely a
keyboard. The general format is:
scanf(format-string, var1,var2,………varn)
Where format-string gives information to the computer on the type of data to be stored in
the list of variables var1,var2……varn and in how many columns they will be found
For example, in the statement:
scanf(―%d %d‖, &p, &q);
The two variables in which numbers are used to be stored are p and q. The data to be
stored are integers. The integers will be separated by a blank in the data typed on the
keyboard.
A sample data line may thus be:
456 18578
Observe that the symbol &(called ampersand) should precede each variable name.
Ampersand is used to indicate that the address of the variable name should be found to
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 57
store a value in it. The manner in which data is read by a scanf statement may be
explained by assuming an arrow to be positioned above the first data value. The arrow
moves to the next data value after storing the first data value in the storage location
corresponding to the first variable name in the list. A blank character should separate the
data values.
The scanf statement causes data to be read from one or more lines till numbers are stored
in all the specified variable names. No that no blanks should be left between characters in
the format-string. The symbol & is very essential in front of the variable name. If some
of the variables in the list of variables in the list of variables in scanf are of type integer
and some are float, appropriate descriptions should be used in the format-string.
For example:
scanf(―%d %f %e‖, &a , &b, &c);
Specifies that an integer is to be stored into a, float is to be stored in b and a float written
using the exponent format in c. The appropriate sample data line is:
485 498.762 6.845e-12
printf function:
The general format of an output function is
printf(format-string, var1,var2…..varn);
Where format-string gives information on how many variables to expect, what type of
arguments they are, how many columns are to be reserved for displaying them and any
character string to be printed. The printf() function may sometimes display only a
message and not any variable value. In the following example:
printf(―Answers are given below‖);
The format-string is:
Answers are given below
And there are no variables. This statement displays the format-string on the video display
and there are no variables. After displaying, the cursor on the screen will remain at the
end of the string. If we want it to move to the next line to display information on the next
line, we should have the format-string:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 58
printf(―Answers are given below\n‖);
In this string the symbol \n commands that the cursor should advance to the beginning of
the next line.
In the following example:
printf(―Answer x= %d \n‖, x);
%d specifies how the value of x is to be displayed. It indicates the x is to be displayed as
a decimal integer. The variable x is of type int. %d is called the conversion specification
and d the conversion character .
In the example:
printf(―a= %d, b=%f\n‖, a, b);
the variable a is of type int and b of type float or double. % d specifies that a is to be
displayed as an integer and %f specifies that, b is to be displayed as a decimal fraction. In
this example %d and %f are conversion specifications and d, f are conversion characters.
Example to indicate how printf() displays answers.
/*Program illustrating printf()*/
# include<stdio.h>
main()
{
int a= 45, b= 67
float x=45.78 , y=34.90
printf(―Output:\n‖);
printf(―1,2,3,4,5,6,7,,8,0\n‖);
printf(―\n‖);
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 59
printf(―%d, %d,,%f ,%f \n‖ , a,b,x,y);
printf(―\n‖);
}
Output: 1,2,3,4,5,6,7,8,9,0 45,67,45.78,34.90
Example for illustrating scanf and printf statements:
/* Program for illustrating use of scanf and printf statements */
#include<stdio.h>
main()
{
int a,b,c,d;
float x,y,z,p;
scanf(―%d %o %x %u‖, &a, &b ,&c ,&d);
printf(―the first four data displayed\n‖);
printf((―%d %o %x %u \n‖, a,b,c,d);
scanf(―%f %e %e %f‖, &x, &y, &z, &p);
printf(―Display of the rest of the data read\n‖);
printf(―%f %e %e %f\n‖, x,y,z,p);
printf(―End of display‖);
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 60
Input:
-768 0362 abf6 3856 -26.68 2.8e-3 1.256e22 6.856
Output:
The first four data displayed
-768 362 abf6 3856
Display of the rest of the data read
-26.680000 2.800000 e-03 1.256000e+22 6.866000
End of display
Formatted input and output using format specifiers:
The function scanf is the input analog of printf, providing many of the same
conversion facilities in the opposite direction.
int scanf (char *format, …..)
scanf reads characters from the standard input, interprets them according to the
specification in format, and stores the results through the remaining arguments. The
format argument is described below; the other arguments, each of which must be a
pointer, indicate where the corresponding converted input to be stored.
scanf stops when it exhausts its format string, or when some input fails to match the
control specification. It returns as its value the number of successfully matched and
assigned input items. This can be used to decide how many items were found . On
end of file EOF is returned; note that this is different from 0, which means that the
next input character does not match the first specification in the format string. The
next call to scanf resumes searching immediately after the last character already
converted.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 61
A conversion specification directs the conversion of the next input field. Normally
the result is placed in the variable pointed to by the corresponding argument. If
assignment suppression is indicated by the * character, however, the input field is
skipped; no assignment is made. An input field is defined as a string of non-white
space characters; it extends either to the next white space character or until the field
width, if specified, is exhausted. This implies that scanf will read across line
boundaries to find its input, since new lines are white space. (White space characters
are blank, tab, new line, carriage return, vertical tab and form feed).
Conversion characters are shown in the table below:
CHARACTER INPUT DATA
d decimal integer
i integer. The integer may be in octal (leading 0)
or hexadecimal (leading 0x or 0x)
o octal integer(with or without leading zero);
u unsigned decimal integer;
x hexadecimal integer (with or without leading ox or ox)
c character
s character string (not quoted)
e,f,g floating-point number with optional sign, optional
decimal point and optional exponent;
% literal %; no assignment is made.
The output function printf translates internal values to characters.
The general syntax is
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 62
int printf (char *format, arg1,arg2…………..)
printf converts, formats, and prints its arguments on the standard output under control
of the format. It returns the number of characters printed.
The format string contains two types of objects: ordinary characters, which are copied
to the output stream, and conversion specifications each of which causes conversion
and printing of the next successive argument to printf. Each conversion specification
begins with a % and ends with a conversion character. Between the % and the
conversion character there may be in order:
A minus sign, which specifies left adjustment of the converted argument.
A number that specifies the minimum field width. The converted argument will
be printed in a field at least this wide. If necessary it will be padded on the left or
right, to make up the field width.
A period, which separates the field width from the precision.
A number, the precision, that specifies the maximum number of characters to
printed from a string, or the number of digits after the decimal point of a floating
point value, or the minimum number of digits for an integer.
An h if the integer is to be printed as a short, or l if as a long.
CHARACTER ARGUMENT TYPE
d,i int; decimal number
o int; unsigned octal number(without a leading zero)
x, x int; unsigned hexadecimal number(without a
leading ox or OX), using abcdef or ABCDEF for 10….15
u int; unsigned decimal number
c int; single character.
s char *; print characters from the string until a‗\o‘ or the number
characters given by the precision.
F double; [-] m.dddddd, where the number of d‘s is given by the
precision(default 6)
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 63
e,E double; [-] m.dddddd e+/-xx or [-] m.dddddd E+/- xx, where the
number of d‘s is given by the precision(default 6)
g,G double; use %e or %E if the exponent is less than or equal to the
precision; otherwise use %f. Trailing zeros and a trailing decimal
point are not printed.
P void *; pointer(implementation-dependent Representation).
% no argument is converted ; print a %
A width or precision may be specified as * , in which case the value is computed by
converting the next argument(which must be an int). For example, to print at most max
characters from a string s.
Printf (―%.*s‖, max, s);
Most of the format conversions have been illustrated in earlier . One exception is
precision as it relates to strings. The following example shows the effect of a variety of
specifications in printing ―hello world‖.
:%s: :hello, world:
:%10s: :hello, world:
:%.10s: :hello, wor:
:%-10s: :hello, world:
:%.15s: :hello, world:
:%-15s: :hello, world:
:%15.10s: : hello, wor:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 64
:%-15.10s: :hello, wor :
The getchar( ) function
Single characters can be entered into the computer using the C library function getchar.
The getchar function is a part of the standard C I/O library. It returns a single character
from a standard input device typically a keyboard. The function does not require any
arguments, though a pair of empty parentheses must follow the word getchar.
The general syntax
Character variable=getchar();
Where character variable refers to some previously declared character variable.
Example:
A C program contains the following statements
char c;
…………….
C=getchar();
The first statement declares that c is a character-type variable. The second statement
causes a single character to be entered from the standard input device and then assigned
to c.
If an end-of-file condition is encountered when reading a character with getchar
function, the value of the symbolic constant EOF will automatically be returned. (This
value will be assigned within the stdio.h file. Typically, EOF will be assigned the value -
1, though this may vary from one compiler to another).
The getchar function can also be used to read multi character strings, by reading
one character at a time within a multi pass loop.
The putchar( ) function:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 65
Single characters can be displayed using the C library function putchar. This function is
complementary to the character input function getchar. The putchar function, like
getchar, is a part of the standard C I/O library. It transmits a single character to a standard
output device. The character being transmitted will normally be represented as a
character type variable. It must be expressed as an argument to the function, enclosed in
parentheses, following the word putchar.
The general syntax is
putchar(character variable)
where character variable refers to some previously declared character variable.
A C program contains the following statements
Char c;
………
putchar(c);
C programs:
1) Program to demonstrate printf statement
#include<stdio.h>
main()
{
printf(―hello, world\y‖);
printf(―hello, world\7‖);
printf(―hello, world\?‖);
}
2) Program to convert farenheit to Celsius
#include<stdio.h>
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 66
main()
{
float fahr, Celsius;
printf(― enter the value for farenheit\n‖);
scanf(― %f‖, &fahr);
Celsius=(5.0/9.0)*fahr-32.0;
printf(―%f %f \n‖, fahr,Celsius);
}
3) Program to depict interactive computing using scanf function.
#include<stdio.h>
main()
{
int number;
printf(―enter an integer number\n‖);
scanf(―%d‖, &number);
if (number<100)
printf(―Your number is smaller than 100\n\n‖);
else
printf(―Your number contains more than two digits\n‖);
}
4) Program to convert days to months and days
#include<stdio.h>
main()
{
int months,days;
printf(―enter days \n‖);
scanf(―%d‖, &days);
months=days/30;
days=days%30;
printf(―Months = %d Days= %d‖, months,days);
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 67
BASIC C PROGRAMS
PROGRAM TO PRINT A SENTENCE.
#include <stdio.h>
void main()
{
printf("C Programming"); //displays the content inside quotation return;
}
Output:
C Programming
PROGRAM TO READ AND DISPLAY AN INTEGER.
#include <stdio.h>
void main()
{
int num;
printf("Enter a integer: ");
scanf("%d",&num); // Storing a integer entered by user in variable num printf("You
entered: %d", num);
return;
}
Output:
Enter a integer: 25
You entered: 25
PROGRAM TO ADD TWO INTEGERS
#include <stdio.h>
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 68
void main( )
{
int num1, num2, sum;
printf("Enter two integers: ");
ssca scanf("%d %d",&num1,&num2);// Stores the two integer entered by user in // variable
num1 and num2
sum=num1+num2; // Performs addition and stores it in variable sum printf("Sum:
%d",sum); // Displays sum
return;
}
Output:
Enter two integers: 12 11
Sum: 23
PROGRAM TO MULTIPLY TWO FLOATING POINT NUMBERS
#include <stdio.h>
void main( )
{
float num1, num2, product; printf("Enter two numbers: ");
scanf("%f %f",&num1,&num2); //Stores two floating point numbers entered
//by user in variable num1 and num2 respectively
product = num1*num2; // Performs multiplication and stores it
printf("Product: %f", product);
return;
}
Output:
Enter two numbers: 2.4 1.1
Product: 2.640000
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 69
MODULE II
BRANCHING AND LOOPING: Two way selection (if, if-else, nested if-
else, cascaded if-else), switch statement, ternary operator? Go to, Loops (For, do-
while, while) in C, break and continue, programming examples and exercises.
BRANCHING AND LOOPING
We all need to alter our actions in the face of changing circumstances. If the
weather is fine, then we will go for a stroll. If the highway is busy, we would take a
diversion. If the pitch takes spin, we would win the match. If she says no, we would look
elsewhere. You can notice that all these conditions depend on some condition being met.
C language too must be able to perform different sets of actions depending on the
circumstances. C has three major decision making instructions-the if statement, the if-else
statement, and the switch statement. A fourth, somewhat less important structure is the
one that uses conditional operators.
Decisions! Decisions!
As of now, we have used sequence control structure in which various steps are
executed sequentially, i.e., in the same order in which they appear in the program. In fact,
to execute the instructions sequentially, we don‘t have to do anything at all. However, in
serious programming situations, seldom do we want the instructions to be executed
sequentially. Many a time, we want a set of instructions to be executed in one situation
and an entirely different set of instructions to be executed in one situation. This kind of
situation is dealt with in C programs using a decision control instruction. As mentioned
earlier, a decision instruction can be implemented in C using:
(a) The if statement. Different forms of if :
Simple if statement.
If … else statement.
Nested if .. else statement.
Else if statement.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 70
(b) The Switch Statement.
(c) The conditional operators.
if Statement: Like most languages, C uses keyword if to implement the decision control
instruction. if statement is a powerful decision-making statement and is used to control
the flow of execution of statements. It is basically a two-way decision statement and is
used in conjunction with an expression. It takes the following form:
if (test expression)
statement-block;
The keyword if tells the compiler that what follows is a decision control
instruction. The condition following the keyword if is always enclosed within a pair of
parentheses. If the condition, whatever it is, is true, then the statement is executed. If the
condition is not true, then the statement is not executed; instead the program skips past it.
Generally, we express a condition using C‘s relational operators. The relational operators
allow us to compare two values to see whether they are equal to each other, unequal, or
whether one is greater than the other.
Here is a sample program, which demonstrates the use of if and the relational operators:
//Demonstration of if statement
#include<stdio.h>
main()
{
int num;
printf(―Enter a number less than 10‖);
scanf(―%d‖,&num);
if(num<10)
printf(―Given number is less than 10‖);
}
NOTE:
We mentioned earlier that the general form of the if statement is as follows-
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 71
if(condition)
Statement;
Truly speaking the general form is as follows:
if(expression)
Statement;
Multiple statements within if:
It may so happen that in a program, we want more than one statement to be
executed if the expression following if is satisfied. If such statements are to be executed,
then they must be places within a pair of braces, as illustrated in the following example,
if(a>3)
{
Bonus=2400;
Printf(―bonus=%d‖,bonus);
}
Observe that here the 2 statements to be executed on satisfaction of the condition have
been enclosed within a pair of braces. If a pair of braces is not used, then the C compiler
assumes that the programmer wants only the immediately next statement after the if to be
executed on satisfaction of the condition. In other words, we can say that the default
scope of the if statement is the immediately next statement after it.
The if … else statement: The general form is:
If(test expression)
{
True-block statements(s)
}
else
{
false-block statement(s)
}
Let us consider an example
#include<stdio.h>
Void main()
{
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 72
int a, b;
printf(―Enter a and b values‖);
scanf(―%d%d‖,&a,&b);
if(a>b)
printf(― a is larger than b‖);
else
printf(― a is larger than b‖);}
In the above example expression (a>b) evaluated for true or false. If expression true than
statements present in the if body will execute else statement present in the else body
executes.
Nesting of if … else statements: When a series of decisions are involved, we may have
to use more than one if … else statement in nested form as shown below:
if(test condition 1)
{
if(test condition 2)
{
Statement-1;
}
else
{
Statement-2;
}
else
{
Statement-3;
}
Statement-x;
Example:
if(a>b)
{
if(a>c)
printf(― a is big‖)
else
printf(― C is big‖);
}
if(b>a)
{
if(b>c)
printf(― b is big‖);
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 73
else
printf(―c is big‖);
}
Dangling ELSE Problem:
One of the classic problems encountered when we start using nested if … else
statements is the dangling else. This occurs when a matching else is not available for an
if. The answer to this problem is very simple. Always match an else to the most
unmatched if in the current block. In some cases, it is possible that the false condition is
not required. In such situations, else statement may be omitted.
“else is always paired with the most recent paired if”
The else if LADDER or cascaded if -else:
There is another way of putting ifs together when multipath decisions are
involved. A multipath decision is a chain of ifs in which the statement associated with
each else is an if. It takes the following general form:
if(condition-1)
Statement-1;
else if(condition-2)
Statement-2;
else if(condition-3)
Statement-3;
else if(condition-n)
Statement-n;
else
Default-statement;
Statement-x;
This construct is known as the else if ladder. The conditions are evaluated from the top,
downwards. As soon as the true condition is found, the statement associated with it is
executed and control is transferred to the statement-x (skipping the rest of the ladder).
When all the n conditions become false, then the else containing the default-statement
will be executed.
The Switch Statement: (keywords used: switch, break, default)
A switch statement is used when multiple branching is required in a program. Switch
is a multi way branching statement. The switch statement tests the value of a given
variable against a list of case values and when a match is found, a block of statements
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 74
associated with that case is executed. The general form of the switch statement is as
follows.
Syntax:
switch (expr)
{
case value1 :
block1;
break;
case value2:
block2;
break;
------
------
default:
default-block;
break;
}
Flow chart
The expr is an integer expression or character. value1, value2, …. are constant or
constant expressions and are known as case labels. Each of these values should be
unique within a switch statement. block1, block2, …. are statement lists and may
contain zero or more statements.
When the switch statement is executed, the value of the expression is successively
compared against the values value1, value2…. If a case is found whose matches with
the value of the expression, then the block of statements that follows the case are
executed.
Ex:
switch ( num)
{
case 1:
printf‖(One‖);
Entry
Switch(
expr)
Block2
Default -block
Statement X
Block1
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 75
break;
case 2:
printf‖(Two‖);
break;
case 3:
printf(―Three‖);
break;
…..
…..
}
The points to remember while using switch statement are as follows:
The expression value must be an integer or character constant.
case should always be followed by an integer constant, single character
constant or integer constant expression.
All cases should be distinct
The statements under default are executed if none of the cases match the value
of the expression. Default class is optional.
Cases and default can occur in any order
Evaluation starts at the case which matches the value of the expression.
Once the match is established, all subsequent cases are executed. So explicit
―break‖ statement is to be provided if subsequent cases are not be executed.
Break is an optional statement which causes explicit exit from the switch statement
The Loop Control Structure
The programs that we have done so far used either a sequential or a decision
control instruction. In the first one, the calculations were carried out in a fixed order,
while in the second, an appropriate set of instructions were executed depending upon the
outcome of the condition being tested.
Loops! Loops!
The versatility of the computer lies in its ability to perform a set of instructions
repeatedly. This involves repeating some portion of the program either a specified
number of times or until a particular condition is being satisfied. This repetitive operation
is done through a loop control instruction.
There are three methods by way of which we can repeat a part of a program. They
are:
Using a for statement.
Using a while statement.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 76
Using a do-while statement.
The loop in a program consists of two parts: 1) Body of the loop. 2) Condition.
Looping process includes the following steps:
Initialization of condition variable.
Test the condition.
Execute the body of the loop depending on the condition.
Updating the condition variable.
While loop:
The while loop is used to execute a block of code, as long as some condition is
true. If the condition is false from the start the block of code is not executed at al. The
while loop tests the condition before it‘s executed so sometimes the loop may never
be executed if initially the condition is not met. The while loop is called entry
controlled loop. Its syntax is as follows.
While (tested condition is satisfied)
{
block of code;
}
Here is a simple example of the use of the while loop. This program counts from
1 to 100.
Main ()
{ int count = 1;
while (count <= 100)
{
printf(―%d\n‖,count);
count += 1;
}
}
Do….while loop:
The do loop also executes a block of code as long as a condition is satisfied. The
difference between a "do ...while" loop and a "while " loop is that the while loop tests
its condition before execution of the contents of the loop begins; the "do" loop tests
its condition after it's been executed at least once. If the test condition is false as the
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 77
while loop is entered the block of code is never executed. Since the condition is tested
at the bottom of a do loop, its block of code is always executed at least once. It is
called as an exit controlled loop.
The "do ....while" loop syntax is as follows
do
{
block of code
} while (condition is satisfied);
Note that a semi-colon ( ; ) must be used at the end of the do ...while loop. This
semi-colon is needed because it instructs whether the while (condition) statement
is the beginning of a while loop or the end of a do ...while loop. Here is an
example of the use of a do loop.
main()
{
int value, r_digit;
printf(―Enter a number to be reversed.\n‖);
scanf(―%d‖, &value);
do
{
r_digit = value % 10;
printf(―%d‖, r_digit);
value = value / 10;
} while (value != 0);
printf(―\n‖);
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 78
for loop:
The third and last looping construct in C is the for loop. The for loop can execute
a block of code for a fixed or given number of times. Its syntax is as follows.
for (initializations; test conditions; increment value)
{
block of code;
}
Ex:
for (count = 1; count <= 10; count++)
{
printf("%d\n",count);
}
It is also possible to have multiple initializations and multiple actions. This loop
starts one counter at 0 and another at 100, and finds a midpoint between them.
(This is advanced material).
for (i = 0, j = 100; j != i; i++, j--)
{
printf("i = %d, j = %d\n", i, j);
}
All of the constituent parts of the statement are optional. The initialization,
condition, termination sections of the for loop can be blank. For instance, suppose
we need to count from a user specified number to 100. The first semicolon is still
required as a place keeper
printf("Enter a number to start the count: ");
scanf("%d",& count);
for ( ; count < 100 ; count++)
{
printf("%d\n", count);
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 79
The difference between while and do-while loop
While loop do – while loop
1. Entry controlled loop i.e. the condition
is checked first and statement in the loop
will get executed if the condition is true
1. Exit controlled loop i.e. condition is
checked at the end of the loop and
statement in the loop will get executed if
the condition is true.
2. Statements in the loop will not get
executed if initially the condition is false
2. Statements in the loop will get
executed at least once even if the
condition is false initially.
3. syntax:
while ( condition)
{
statements;
}
3. Syntax:
do
{
statements;
} while (condition);
4. Example:
int i=1;
do {
printf(―%d‖, i);
i++;
} while (i<10);
4 . Example:
int i=1;
do {
printf(―%d‖, i);
i++;
} while (i<10);
Use of break and continue statement in C.
Sometimes, due to an exceptional condition, you need to jump out of a loop early,
that is, before the main controlling expression of the loop causes it to terminate
normally. Other times, in an elaborate loop, you may want to jump back to the top of
the loop (to test the controlling expression again, and perhaps begin a new trip
through the loop) without playing out all the steps of the current loop. The break and
continue statements allow you to do these two things. (They are, in fact, essentially
restricted forms of goto.)
The break statement causes an immediate exit from the loop (innermost loop in the
case of nested structure).
{
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 80
printf(―%d ―, i);
if ( i = = 5)
break;
}
In the above program, when the value of i becomes 5 the loop terminates.
The presence of continue statement in a loop causes to go back to the condition at the
top, test for it, and do next iteration if the condition is true. The continue statement is
usually used for skipping one iteration of a loop.
Ex: while ( i < 10)
{ i++;
if ( i = = 5)
continue;
printf(―%d ―, i); }
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 81
MODULE III ARRAYS AND STRINGS: Using an array, Using arrays with Functions, Multi-Dimensional arrays. String: Declaring, Initializing, Printing and reading strings, strings manipulation functions, strings input and output functions, arrays of strings, programming examples and Exercises.
FUNCTIONS: Functions in C, Argument Passing – call by value, Functions and
program structure, location of functions, void and parameter less Functions, Recursion,
programming examples and exercises.
ARRAYS, STRINGS AND FUNCTIONS
An array may be defined as a group of similar data elements that share a common
name. The arrays can be profitably used if want to handle a large number related data
of similar type.
For instance, we can define an array name salary to represent a set of salaries of a
group of employers. A particular value is indicated by writing a number called index
or subscript in brackets after the array name. For example,
Salary[10] represents the salary of the 10th
employee. While the complete
set of values is referred to as an array, the individual values are called elements of the
array. Arrays can be of any variable type.
Arrays can be classified as one dimensional arrays and multidimensional arrays. A
list of items having only one variable name and can be accessed using only one
subscript is called a single dimensional array.
For ex: salary[50]; is a one dimensional array.
The array declared with more than one subscript is called a multi dimensional array.
Here more than one subscript is required to specify each array element. Consider a
case where we have to store the marks of 5 students in 4 subjects. For this purpose,
we can declare a two dimensional array which can store 20 values.
Ex: matrix[5][5]; is a two dimensional array.
Declaration of arrays:
An Array is declared as follows:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 82
Type variable[n];
Where n is an integer indicating the maximum number of elements in the array.
Type refers to the data type of the array and variable is any valid C identifier used
indicate the name of the array.
Example:
int marks[10];
float sales[50];
int purchase[10][20];
char name[20];
Rules to be followed while using arrays:
Array subscript always starts with zero. So the first element will have the
index as zero.
The data type of all the elements of the array must be same.
Array can be initialized at the time of declaration by specifying the value
of each element within braces. There must be an equal sign between the
array name and braces and each value in the braces must be separated by a
comma.
If all values are given in braces, the subscript in the array can be omitted.
If an array is declared with subscript and fewer the number of values are
given in the braces, the cells are initialized from the beginning and
remaining cells are left uninitialized.
There is no way to initialize middle elements of the array.
The compiler does not check for bounds of the array. While assigning
values to the array elements, the user has to see that the subscript value
will be less than the maximum size of the array.
C provides a facility called array that enables the user to combine similar data types into
a single entity. Ordinary variables are capable of holding only one value at a time. If there
is a large amount of similar data to be handled, then using a different variable for each
data item would make the job unwieldy, tedious and confusing. Instead, on combining all
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 83
this similar data into an array, the whole task of organizing and manipulating data would
become easier and more efficient.
Like ordinary variables, arrays too can be initialized during declaration. For
example,
int num[6]={2,4,12,14,7,3};
int n[]={2,4,5,6,7};
float p[]={12.3,2.3,5.2,3.6,-11.3};
In C, there is no check to see if the subscript used for an array exceeds the size of
the array. Data entered with a subscript exceeding the array size will simply be placed in
memory outside the array; probably on the top of other data, or on the program itself.
This will lead to unpredictable results, to say the least, and there will be no error
messages to warn us that we are going beyond the array size.
Array Declaration:
To begin with, like other variables, an array needs to be declared so that the
compiler will know what kind of an array and how large an array we want. Consider the
following example:
int marks[30];
Here, int specifies the type of the variable, just as it does with ordinary variable and the
work marks specifies the name of the variable. The [30] however is new. The number 30
tells how many elements of the type int will be in our array. This is often called the
'dimension' of the array. The bracket ( [] ) tells the compiler that we are dealing with an
array.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 84
Accessing elements of an array:
Once an array is declared, let us see how individual elements in the array can be
referred. This is done with subscript, the number in the brackets following the array
name. This number specifies the element's position in the array. All the array elements
are numbered, starting with 0. Thus, marks[2] is not the second element of the array, but
the third. The ability to use variables to represent subscript is what makes arrays so
useful.
Entering Data into an array:
Here is the section of code that places data into an array:
for(i=0;i<=29;i++)
{
printf(―\n Nter marks‖);
scanf(―%d‖,&marks[i]);
}
The for loop causes the process of asking for and receiving a student's marks
from the user to be repeated 30 times. The first time through the loop, I has a value of 0,
so the scanf() function will cause the value typed to be stored in the array element
marks[0], the first element of the array. This process will be repeated until i becomes 29.
This is last time through the loop, which is a good thing, because there is no array
elements like marks[30].
An array is collection of similar elements.
The first element in the array is numbered 0, so the last elements is 1 less than the size of the
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 85
array.
An array is also known as subscripted variable.
Before using an array, its type and dimension must be declared.
However big an array, its elements are always stored in contiguous memory locations.
Till the array elements are not given specific values, they are supposed to contain garbage
values.
If the array is initialized where it is declared mentioning the dimension of an array is optional.
The size should be either a numeric constant or a symbolic constant.
An array can be initialized at either of the following stages: 1) At Compile time. 2) At run
time.
Use multiple arrays for realizing a matrix in a program.
Compiler doesn't perform boundary checking on an array.
Two Dimensional Arrays:
It is possible for arrays to have two or more dimensions. The two-dimensional
array is also called a matrix. The following program shows a two-dimensional array at
work.
main(){
int s[4][2],i;
for(i=0;i<=3;i++)
{
printf(―nter roll no. and marks‖);
scanf(―%d%d‖,&s[i][0],&s[i][1]);
}
for(i=0;i<=3;i++)
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 86
printf(―%d%d\n‖,s[i][0],s[i][1]);
}
The program is fairly simple. Through the first for loop, we read the values of Roll no.
and marks into the two-dimensional array s[4][2] and through the 2nd
loop we print those
values.
The arrangement of array elements into rows and columns is only conceptually
true, since in memory there are no rows and columns. Hence even 2-D array elements are
arranged linearly in memory.
Multi Dimensional Arrays:
C allows arrays of three or more dimensions. The exact limit is determined by the
compiler. The general form of a multi-dimensional array is
Type array name[s1][s2][s3] . . . [sm];
Where si is the size of the ith element. Some examples are:
int survey[3][6][12];
survey is three-dimensional array declared to contain 180 integer type elements.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 87
STRINGS
A string is a sequence of characters that is treated as a single data item. Any group
of characters defined between double quotation marks is a string constant. Example:
―Man is obviously made to think‖.
The way a group of characters can be stored in a integer array, similarly a group
of characters can be stored in a character array.
A string constant is a one-dimensional array of characters terminated by a null
('\0'). For example:
char name[]={'H','A','E','S','L','\0'};
Each character in the array occupies one byte of memory and the last character is
always '\0'. Note that '\0' and 0 are not same. ASCII value of '\0' is 0, whereas ASCII
value of 0 is 48. Note that elements of the character array are stored in contiguous
memory locations. The terminating null ('\0') is important, because it is the only way the
functions that work with a string can know where the string ends. In fact, a string not
terminated by a '\0' is not really a string, but merely a collection of characters.
Char name[]=‖HAESLER‖, Note that in this declaration '\0' is not
necessary. C inserts the null character automatically.
Character strings are often used to build meaningful and readable programs. The
common operations performed character strings include:
Reading and writing strings.
Combining strings together.
Copying one string to another.
Comparing strings for equality.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 88
Extracting a portion of a string.
Declaring and Initializing String Variables
C does not support string as a data type. However, it allows us to represent strings
as character arrays. In C, therefore a string variable is any valid C variable name and is
always declared as an array of characters. The general form of declaration of a string
variable is:
char string_name[ size ];
The size determines the number of characters in the string_name.
When the compiler assigns a character string to a character array, it automatically
supplies a null character ('\0') at the end of the string. Therefore, the size should be equal
to the maximum number of characters in the string plus one.
Like numeric arrays, character arrays may be initialized when they are declared. C
permits character arrays to be initialized in wither of the following forms:
char name[]={'H','A','E','S','L','\0'};
Char name[]=‖HAESLER‖;
We can also declare the size much larger than the string size in the initializer.
That is, the statement
char str[10]=‖GOOD‖;
is permitted. The storage looks like:
G O O D \0 \0 \0 \0 \0 \0
However, the following declaration is illegal:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 89
char str2[3]=‖GOOD‖;
Readings Strings from Terminal:
Using scanf Function: The familiar input function scanf can be used with %s
format specification to read in a string of characters. Example:
char address[10];
scanf(%s‖,address);
The problem with scanf function is that it terminates its input on the first white
space it finds. A white space includes blanks, tabs, carriage returns, form feeds and new
lines. Therefore if the following line of text is typed in at the terminal,
NEW YORK
then only the string NEW will be read into the array of address, since the blank
space after the work NEW will terminate the reading of string.
The scanf function automatically terminates the string that is read with a null
character and therefore character array should be large enough to hold the input string
plus null character. Unlike previous scanf calls, in the character arrays, the ampersand
(&) is not required before the variable name.
The address array is created in the memory as shown below:
N E W \0 ? ? ? ? ? ?
0 1 2 3 4 5 6 7 8 9
Note that unused locations are filled with garbage.
So, If we want to read the entire line ―NEW YORK‖ then we may use two
character arrays of appropriate sizes. That is,
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 90
Char adr1[15],adr2[15];
Scanf(―%s %s‖,adr1,adr2);
Will assign the string ―NEW‖ to adr1 and ―YORK‖ to adr2.
We can also specify the field width using the form %ws in the scanf function for reading
a specified number of characters from the input string.
scanf(―%ws‖,name);
Here two things may happen,
1. The width w is equal to or greater than the number of characters typed in. the entire
string will be stored in the string variable.
2. The width w is less than the number of characters in the string. The excess characters
will be truncated and left unread.
Consider the following statements:
char name[10];
scanf(%5s‖,name);
The input string RAM will be stored as:
R A M \0 ? ? ? ? ? ?
The input string KRISHNA will be stored as:
K R I S H \0 ? ? ? ?
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 91
Using getchar and gets function:
We can use getchar function repeatedly to read successive single characters from
the input and place them into an character array. Thus, an entire line of text can be read
and stored in an array. The reading is terminated when the newline character (‗\n‘) is
entered and the null character is placed at the end of the string. The getchar function takes
the following form;
Char ch;
Ch=getchar();
Another more convenient method of reading a string of text containing white spaces is to
use the library function gets available in <stdio.h> header file. This is a simple function
with one string parameter and called as below:
gets(str);
str is a string variable declared properly. It reads characters into str from the
keyboard until a new line character is encountered and then appends a null character to
the string. Unlike scanf it does not skip white spaces.
For example the code segment:
char line[80];
gets(line);
printf(―%s‖,line);
reads a line of text from the keyboard and displays it on the screen.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 92
C does not provide operators that work directly on strings. For instance, we cannot
assign one string to another directly. The following statements set of statements
are not valid:
String=‖ABC‖;
String1 = string;
Writing strings to screen:
Using printf function: The format %s can be used to display an array of
characters that is terminated by the null character.
We can also specify the precision with which the array is displayed. For example:
%10.4
indicates that the first four characters are to be printed in a field width of 10
columns.
Using putchar and puts functions:
Like getchar C supports another character handling function putchar to output
the values of character variables. It takes the following form:
char ch=‘A‘;
putchar(ch);
the function putchar requires one parameter. This statement is equivalent to:
printf(%c‖,ch);
Another way of printing string values is to use the function puts declared in the header
file <stdio.h>. This is a one parameter function and invokes as under:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 93
Puts(str);
For example, the program segment:
Char line[40];
Gets(line);
Puts(line);
reads a line of text from the keyboard and displays it on the screen.
Arithmetic Operations on Characters:
C allows us to manipulate characters the same way we do with numbers.
Whenever a character constant or character variable is used in an expression, it is
automatically converted into an integer value by the system. The integer value depends
on the local character set of the system.
To write a character in its integer representation, we may write it as an integer.
For example, if the machine uses the ASCII representation, then,
X=‘a‘;
Printf(―%d‖,x);
will display the number 97 on the screen.
It is also possible to perform arithmetic operations on the character constants and
variables. For example,
x=‘z‘-1;
is a valid statement. In ASCII, the value of ‗z‘ is 122, the statement will assign the value
121 to the variable x.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 94
The C library supports a function that converts a string of digits into their integer
values. The function takes the form
x=atoi(string);
x is an integer variable and string is a character array containing a string of digits.
Consider the following segment of code:
number=‖1988‖;
year=atoi(number);
number is a string variable which is assigned the string constant ―1988‖. The
function atoi converts the string ―1988‖ to its numeric equivalent 1988 and assigns it to
the integer variable year. String conversion functions are stored in the header file
<std.lib.h>.
String Handling Functions:
strcat() Function
strcat() joins two or more strings together. It takes the following form
strcat(string1, string2);
String1 and string2 are character arrays. When the above function is executed, string2
is appended to string1. It does so by removing the null character at the end of string1
and placing string2 from there. The string at string2 remains unchanged.
strcat function may also append a string constant to a string variable. The following is
valid
strcat(part1,"SACY");
C also permits nesting of strcat functions. For example
strcat(strcat((string1,string2),string3);
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 95
is allowed and concatenates all the three strings together. The resultant string is stored
in string1.
strcmp() Function
The strcmp function compares two strings identified by the arguments and has a value
0 if they are equal. If they are not, it has the numeric difference between the first non-
matching characters in the strings. It takes the form:
strcmp(string1, string2);
string1 and string2 may be string variables or string constants. For
example
strcmp(name1,name2);
strcmp(name1,"JOHN");
strcpy() Function
The strcpy function works almost like a string-assignment operator. It takes the form
strcpy(string1,string2);
and assigns the contents of string2 to string1. string2 may be a character array
variable or a string constant. For example
strcpy(city,"DELHI");
will assign the string "DELHI" to the string variable city. Similarly the statement
strcpy(city1, city2);
will assign the contents of the string variable city2 to the string variable city1.The
size of the array city1 should be large enough to receive the contents of city2.
strlen() Function
This function counts and returns the number of characters in a string
n = strlen(string);
Where n is an integer variable, which receives the value of the length of the string.
The argument may be a string constant. The counting ends at the first null character.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 96
strncmp(str1, str2,n) function
Compares first n characters of the second string with first string and returns either 0, 1
or -1.
strncat(str1,str2,n) function
Concatenates first n characters of the second string to the first string.
strncpy(str1,str2,n) function
Copies first n characters of the second string to the first string.
strupr(str1) function
Converts the string to upper cas.e
strlwr(str1) function
Converts the string to lower case.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 97
FUNCTIONS
A Function is a self-contained block of statements that perform a coherent task of
some kind. Every C program can be thought of as a collection of these functions.
C functions can be classified into two categories, namely, library functions and
user-defined functions. main is an example of user-defined functions. printf and scanf
belong to the category of library functions. some of other library functions are sqrt, cos,
strcat etc. The main distinction between these two categories is that library functions are
not required to be written by us whereas a user-defined function has to be developed by
the user at the time of writing a program.
Example program:
#include<stdio.h>
void message(); //function prototype declaration
void main()
{
message(); //function call
printf(―C Program‖);
}
void message() //function definition
{
printf(―C++ Program‖);
}
Output:
C++ Program
C Program
We can write more than one function in a single program. Consider the foll.
Program
#include<stdio.h>
void Italy();
void brazil();
void argentina();
void main()
{
printf(―I am in main‖);
italy();
brazil();
argentina();
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 98
void italy()
{
printf(―I am in italy‖);
}
void brazil()
{
printf(―I am in brazil‖);
}
void argentina()
{
printf(―I am in argentina‖);
}
Output:
I am in main
I am in Italy
I am in brazil
I am in argentina
From above we can conclude that:
A C program is a collection of one or more functions.
If a C program contains only one function, it must be main().
If a C program contains more than one function, then one of these must be
main(). because program execution always begin with main().
There is no limit on the number of functions that might be present in a C program.
Each function in a program is called in the sequence specified by the function
calls in main().
After each function has done its thing, control returns to main(). When main()
runs out of statements and function calls, the program ends.
Summarization:
1. A function gets called when the function name is followed by a semicolon. For
example,
void main()
{
argentina();
}
2. A function is defined when function name is followed by a pair of braces in which one
or more statements may be present. For example,
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 99
Void argentina()
{
Statement1;
Statement2;
Statement3;
}
(d) Any function can be called from any other function. Even main( ) can be called from
other functions. For example,
main( )
{
message( ) ;
}
message( )
{
printf ( "\nCan't imagine life without C" ) ;
main( ) ;
}
(e) A function can be called any number of times. For example,
main( )
{
message( ) ;
message( ) ;
}
message( )
{
printf ( "\nJewel Thief!!" ) ;
}
(f) The order in which the functions are defined in a program and the order in which they
get called need not necessarily be same. For example,
main( )
{
message1( ) ;
message2( ) ;
}
message2( )
{
printf ( "\nBut the butter was bitter" ) ;
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 100
message1( )
{
printf ( "\nMary bought some butter" ) ;
}
Here, even though message1( ) is getting called before message2( ), still, message1(
) has been defined after message2( ). However, it is advisable to define the functions
in the same order in which they are called. This makes the program easier to
understand.
(g) A function can call itself. Such a process is called ‗recursion‘. We would discuss this
aspect of C functions later in this chapter.
(h) A function can be called from other function, but a function cannot be defined in
another function. Thus, the following program code would be wrong, since
argentina( ) is being defined inside another function, main( ).
main( )
{
printf ( "\nI am in main" ) ;
argentina( )
{
printf ( "\nI am in argentina" ) ;
}
}
(i) There are basically two types of functions:
Library functions Ex. printf( ), scanf( ) etc.
User-defined functions Ex. argentina( ), brazil( ) etc.
As the name suggests, library functions are nothing but commonly required
functions grouped together and stored in what is called a Library. This library of
functions is present on the disk and is written for us by people who write compilers
for us. Almost always a compiler comes with a library of standard functions. The
procedure of calling both types of functions is exactly same.
Why Use Functions
Why write separate functions at all? Why not squeeze the entire logic into one function,
main( )? Two reasons:
(a) Writing functions avoids rewriting the same code over and over. Suppose you have a
section of code in your program that calculates area of a triangle. If later in the
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 101
program you want to calculate the area of a different triangle, you won‘t like it if you
are required to write the same instructions all over again. Instead, you would prefer
to jump to a ‗section of code‘ that calculates area and then jump back to the place
from where you left off. This section of code is nothing but a function.
(b) Using functions it becomes easier to write programs and keep track of what they are
doing. If the operation of a program can be divided into separate activities, and each
activity placed in a different function, then each could be written and checked more
or less independently. Separating the code into modular functions also makes the
program easier to design and understand.
Return Statement:
The return statement has two important uses. It causes an immediate exit from the
function it is in. That is, it causes program execution to return to the calling function. It
can be used to return the values.
The syntax of the return statement is:
return;
return(var);
return(exp);
where var is a variable. Exp is any arithmetic expression.
When the return statement is encountered in the called function, control is passed
on to the calling function and a variable var or the value obtained by the arithmetic
expression is returned by the called function to the calling function.
Parameters:
Arguments are also known as Parameters. They are used to communicate between
the calling function and the called function.
The parameters are of two types.
1. Actual Parameters.
2. Formal Parameters (Dummy).
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 102
The variables that are used while calling a function are known as actual
parameters. The variables that are used in function definition are known as formal
parameters. The names of actual and formal parameters can be same or can be different.
Even though the names are same the ―C‖ compiler treats them as different variables.
For example let us consider the following statement
Max=maximum(a,b,c);
Here we are passing values of a,b,c to maximum(). a,b,c are known as actual parameters.
maximum(x,y,z);
In the function definition we are using x,y,z these variables are known as formal
parameters.
The values of actual parameters are copied into formal parameters.
Types of Functions:
The user defined functions are of three types:
1. Functions with no arguments and no return values.
2. Functions with arguments and no return values.
3. Functions with arguments and return values.
1. Functions with no arguments and no return values:
Functions which have no arguments and no return values are written as:
void func()
main()
{
func();
}
func()
{
statements;
}
In the above example, the function is called by the main() and the code of the
function is written after the main() function. As the function func() has no arguments,
main() cannot send any data to func() and since it has no return statement, hence the
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 103
function cannot return any value to main(). As function returns nothing it‘s return type is
specified as void.
#include<stdio.h>
#include<conio.h>
void fun();
main()
{
clrscr();
fun();
}
void fun()
{
int num;
printf("Nter the number:");
scanf("%d",&num);
printf("the number you entered is %d",num);
}
2. Functions with arguments and no return values:
Functions can have parameters, hence the calling function can send data to the
called function but it cannot return any value to the calling function as it has no return
statement. Following program illustrates this:
#include<stdio.h>
#include<conio.h>
void sum(int,int);
main()
{
int x,y;
printf(―Nter first number:‖);
scanf(‖%d‖,&x);
printf(―Nter second number:‖);
scanf(‖%d‖,&y);
sum(x,y);
}
void sum(int a,int b)
{
int sum=0;
sum=a+b;
printf(―Sum of two no.‘s:%d‖,sum)
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 104
In this program main() function calls sum() and this function takes two parameters
of type int and returns no value. So return data type void is used.
3. Functions with arguments and return values:
Since functions have parameters, the calling function can send data to the called
function, it can also return any value to the calling function with the use of return
statement. Following program illustrates this:
#include<stdio.h>
#include<conio.h>
int sum(int,int);
main()
{
int z,x,y;
printf(―Nter first number:‖);
scanf(‖%d‖,&x);
printf(―Nter second number:‖);
scanf(‖%d‖,&y);
z=sum(x,y);
printf(―Sum of two no.‘s:%d‖,z)
}
int sum(int a,int b)
{
int sum=0;
sum=a+b;
return sum;
}
Passing Values between Functions
The functions that we have used so far haven‘t been very flexible. We call them
and they do what they are designed to do. Like our mechanic who always services the
motorbike in exactly the same way, we haven‘t been able to influence the functions in the
way they carry out their tasks. It would be nice to have a little more control over what
functions do, in the same way it would be nice to be able to tell the mechanic, ―Also
change the engine oil, I am going for an outing‖. In short, now we want to communicate
between the ‗calling‘ and the ‗called‘ functions.
The mechanism used to convey information to the function is the ‗argument‘. You
have unknowingly used the arguments in the printf( ) and scanf( ) functions; the format
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 105
string and the list of variables used inside the parentheses in these functions are
arguments. The arguments are sometimes also called ‗parameters‘.
Consider the following program. In this program, in main( ) we receive the values
of a, b and c through the keyboard and then output the sum of a, b and c. However, the
calculation of sum is done in a different function called calsum( ). If sum is to be
calculated in calsum( ) and values of a, b and c are received in main( ), then we must
pass on these values to calsum( ), and once calsum( ) calculates the sum we must return
it from calsum( ) back to main( ).
/* Sending and receiving values between functions */
main( )
{
int a, b, c, sum ;
printf ( "\nEnter any three numbers " ) ;
scanf ( "%d %d %d", &a, &b, &c ) ; sum = calsum ( a, b, c ) ;
printf ( "\nSum = %d", sum ) ;
}
calsum ( x, y, z )
int x, y, z ;
{
int d ;
d = x + y + z ;
return ( d ) ;
}
And here is the output...
Enter any three numbers 10 20 30
Sum = 60
There are a number of things to note about this program:
(a) In this program, from the function main( ) the values of a, b and c are passed on to
the function calsum( ), by making a call to the function calsum( ) and mentioning a,
b and c in the parentheses:
sum = calsum ( a, b, c ) ;
In the calsum( ) function these values get collected in three variables x, y and z:
calsum ( x, y, z )
int x, y, z ;
(b) The variables a, b and c are called ‗actual arguments‘, whereas the variables x, y and
z are called ‗formal arguments‘. Any number of arguments can be passed to a
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 106
function being called. However, the type, order and number of the actual and formal
arguments must always be same.
Instead of using different variable names x, y and z, we could have used the same
variable names a, b and c. But the compiler would still treat them as different
variables since they are in different functions.
(c) There are two methods of declaring the formal arguments. The one that we have used
in our program is known as Kernighan and Ritchie (or just K & R) method.
calsum ( x, y, z )
int x, y, z ;
Another method is,
calsum ( int x, int y, int z )
This method is called ANSI method and is more commonly used these days.
(d) In the earlier programs the moment closing brace ( } ) of the called function was
encountered the control returned to the calling function. No separate return
statement was necessary to send back the control.
This approach is fine if the called function is not going to return any meaningful
value to the calling function. In the above program, however, we want to return the
sum of x, y and z. Therefore, it is necessary to use the return statement.
The return statement serves two purposes:
(1) On executing the return statement it immediately transfers the control back to
the calling program.
(2) It returns the value present in the parentheses after return, to th3e calling
program. In the above program the value of sum of three numbers is being
returned.
(e) There is no restriction on the number of return statements that may be present in a
function. Also, the return statement need not always be present at the end of the called
function. The following program illustrates these facts. fun( )
{
char ch ;
printf ( "\nEnter any alphabet " ) ;
scanf ( "%c", &ch ) ;
if ( ch >= 65 && ch <= 90 )
return ( ch ) ;
else
return ( ch + 32 ) ;
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 107
In this function different return statements will be executed depending on whether
ch is capital or not.
(f) Whenever the control returns from a function some value is definitely returned. If a
meaningful value is returned then it should be accepted in the calling program by
equating the called function to some variable. For example,
sum = calsum ( a, b, c ) ;
(g) All the following are valid return statements.
return ( a ) ;
return ( 23 ) ;
return ( 12.34 ) ;
return ;
In the last statement a garbage value is returned to the calling function since we are
not returning any specific value. Note that in this case the parentheses after return
are dropped.
(h) If we want that a called function should not return any value, in that case, we must
mention so by using the keyword void as shown below.
void display( )
{
printf ( "\nHeads I win..." ) ;
printf ( "\nTails you lose" ) ;
}
(i) A function can return only one value at a time. Thus, the following statements are
invalid.
return ( a, b ) ;
return ( x, 12 ) ;
There is a way to get around this limitation, which would be discussed later in this
chapter when we learn pointers.
(j) If the value of a formal argument is changed in the called function, the
corresponding change does not take place in the calling function. For example, main(
)
{
int a = 30 ;
fun ( a ) ;
printf ( "\n%d", a ) ;
}
fun ( int b )
{
b = 60 ;
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 108
printf ( "\n%d", b ) ;
}
The output of the above program would be:
60
30
Thus, even though the value of b is changed in fun( ), the value of a in main( )
remains unchanged. This means that when values are passed to a called function the
values present in actual arguments are not physically moved to the formal
arguments; just a photocopy of values in actual argument is made into formal
arguments.
Scope Rule of Functions
Look at the following program
main( )
{
int i = 20 ;
display ( i ) ;
}
display ( int j )
{
int k = 35 ;
printf ( "\n%d", j ) ;
printf ( "\n%d", k ) ;
}
In this program is it necessary to pass the value of the variable i to the function
display( )? Will it not become automatically available to the function display( )? No.
Because by default the scope of a variable is local to the function in which it is defined.
The presence of i is known only to the function main( ) and not to any other function.
Similarly, the variable k is local to the function display( ) and hence it is not available to
main( ). That is why to make the value of i available to display( ) we have to explicitly
pass it to display( ). Likewise, if we want k to be available to main( ) we will have to
return it to main( ) using the return statement. In general we can say that the scope of a
variable is local to the function in which it is defined.
Calling Convention
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 109
Calling convention indicates the order in which arguments are passed to a function
when a function call is encountered. There are two possibilities here:
Arguments might be passed from left to right.
Arguments might be passed from right to left.
C language follows the second order.
Consider the following function call:
fun (a, b, c, d ) ;
In this call it doesn‘t matter whether the arguments are passed from left to right or from
right to left. However, in some function call the order of passing arguments becomes an
important consideration. For example:
int a = 1 ;
printf ( "%d %d %d", a, ++a, a++ ) ;
It appears that this printf( ) would output 1 2 3.
This however is not the case. Surprisingly, it outputs 3 3 1. This is because C‘s
calling convention is from right to left. That is, firstly (a) (b) 1 is passed through the
expression a++ and then a is incremented to 2. Then result of ++a is passed. That is, a is
incremented to 3 and then passed. Finally, latest value of a, i.e. 3, is passed. Thus in right
to left order 1, 3, 3 get passed. Once printf( ) collects them it prints them in the order in
which we have asked it to get them printed (and not the order in which they were passed).
Thus 3 3 1 gets printed.
Advanced Features of Functions
With a sound basis of the preliminaries of C functions, let us now get into their
intricacies. Following advanced topics would be considered here.
(a) Function Declaration and Prototypes
(b) Calling functions by value or by reference
(c) Recursion
Let us understand these features one by one.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 110
(a) Function Declaration and Prototypes:
Before any function is to be called, it must be declared. The declaration statement for a
function is referred as function prototype. A function prototype tells the compiler the type
of data returned by the function, the number of arguments the function expects to receive,
the types of arguments, and the order in which these arguments are expected.
Function prototype is always declared at the beginning of main() function. The
function prototype is written as follows:
data_type function_name(argument_1,argument_2 …… argument_n);
If function return data type is not specified the function is assumed to return int
value. If function returns nothing then void type is to be used as return type.
Note:
#include<stdio.h>
int maximum(int,int,int); //function prototype
main()
{
Int a,b,c;
Printf(―Nter 3 numbers:‖);
Scanf(―%d%d%d‖,&a,&b,&c);
Printf(―Maximum is: %d‖,maximum(a,b,c));
}
// function maximum definition
int maximum(int x,int y,int z)
{
int max=x;
if(y>max)
max=y;
if(z>max)
max=z;
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 111
return max;
}
The function prototype for maximum is
Int maximum(int,int,int);
This function prototype states that maximum takes three arguments of type int and
returns a result of int type.
Void Type:
Sometimes a function may not return any value, in such a case its data type
becomes void. The following program shows how to use void:
#include<stdio.h>
void message();
void display();
main()
{
message();
printf(―Iam back in main()‖);
}
void message()
{
printf(―Iam in message function‖);
display();
}
void display()
{
printf(―Iam in display function‖);
return;
}
(b) Call by Value and Call by Reference
Functions can be called by using parameters. Parameters can generally passed to a
function in the following two ways.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 112
1. Call by value:
According to this mechanism the value of each of the actual parameters are
copied into the corresponding formal arguments. Any changes done to the formal
parameters have no effect on the actual parameters, because the actual parameters and
formal parameters have different memory locations.
2. Call by reference:
According to this mechanism the address of the actual parameters are passed
while calling a function. The formal parameters are pointer variables and they point to the
same memory locations of the corresponding actual parameters. Hence any changes that
are done to the formal parameters effect the values of actual parameters.
A function can at most return back only one value as a result. In general, we make use of
call by value mechanism, if a single value has to be returned. On the other hand when
more than one value desired, we use call by reference mechanism to indirectly transfer
the resulting values back to the calling function.
S.No Call by value Call by reference
1. This is the usual method to
call a function in which only
the value of variable is
passed as an argument.
In this method, the address
of the variable is passed as
an argument.
2. Any change in the value of
argument passed is local to
the function and is not
accepted in the calling
program.
Any change in the value of
the argument passed is
accepted in the calling
program.
3. Memory location occupied
by formal and actual
parameters are different.
Memory location occupied
by formal and actual
parameters are same.
4. Since new location is
created, this method is slow.
Since the existing memory
location is used through its
address, this method is fast.
Local and Global (External) Variables:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 113
The variables which are defined within the body of the function or block is local
to that function or block only and called local variables.
Example:
var(i,j)
int i,j;
{
int a,b;
. . . . . ;
}
Here a,b are the local variables which are defined within the body of the function var().
Local variable can be used for only that function, in which they are defined. The same
variable name can be used in different functions and hence these variables are local to
that function only.
The variables which are defined outside the main() is called global variable. The
global variable has the same data type and same name throughout the program. It is
useful to declare the variable global when the variable has constant value throughout the
program.
Following program illustrates the use of global variable:
#include<stdio.h>
int a,b=6;
void func();
main()
{
a=8;
func();
}
void func()
{
int area;
area=a*b;
printf(―area=%d‖,area);
}
Output:
area=48
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 114
Scope and Lifetime of a Variable
The scope of a variable is the portion of the program where the variable is valid or
"known‖. A variable's lifetime is the period of time during which that variable exists
during execution. Some variables exist briefly. Some are repeatedly created and
destroyed. Others exist for the entire execution of a program. In this section we will
discuss two storage classes of variables: automatic variables and static variables.
An automatic variable's memory location is created when the block in which it is
declared is entered. An automatic variable exists while the block is active, and then it is
destroyed when the block is exited. Since a local variable is created when the block in
which it is declared is entered and is destroyed when the block is left, one can see that a
local variable is an automatic variable.
A static variable is a variable that exists from the point at which the program begins
execution and continues to exist during the duration of the program. Storage for a static
variable is allocated and initialized once when the program begins execution. A global
variable is similar to a static variable since a global variable exists during the duration of
the program. Storage for the global variable is allocated and is initialized once when the
declaration for the global variable is encountered during execution. Thus both the global
variable and the static variable have a history preserving feature -- they continue to exist
and their contents are preserved throughout the lifetime of the program.
(c) Recursion
In C, functions can call themselves. A function is recursive if a statement in the
body of the function calls itself. Sometimes called circular definition, Recursion is the
process of defining something in terms of itself.
The main advantage of recursive function is clear, short and simple programs.
A commonly used example of a recursive procedure is determining the factorial of a
number. The factorial of a umber n is define as:
N!=n*(n-1)*(n-2)* ….a
This is an example of a recursive definition wherein the factorial of a number is defined
in terms of itself, i.e, the factorial n! is defined in terms of the factorial (n-1)!.
Obviously this recursive definition should have a stopping condition otherwise an infinite
loop will result. In this case, it is
0!=1.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 115
Thus, the complete definition of factorial function is
N!=n*(n-1) with 0!=1.
It is simple matter to convert this factorial function to a C function –
int fact(int x)
{
int f=1;
if(x>1)
f=x*fact(x-1);
return(f);
}
The following points should be noted about this function:
The fact() function calls itself, but with a parameter one less than the current
parameter i.e., fact(6) calls fact(5) while fact(5) calls fact(4) and so on.
This recursive calling function ends when fact(1) calls fact(0) – fact(0) returning
1.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 116
MODULE IV STRUCTURES AND FILE MANAGEMENT: Basic of structures, structures and Functions, Arrays of structures, structure Data types, type definition, Defining, opening and closing of files, Input and output operations, programming examples and exercises.
STRUCTURES, UNIONS, TYPE DEFINITION, BIT FIELDS
C Data Types:
Primary data types
Derived data types
User-defined data types
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 117
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 118
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 119
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 120
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 121
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 122
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 123
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 124
File Handling in C
Why files are needed?
When the program is terminated, the entire data is lost in C programming. If you
want to keep large volume of data, it is time consuming to enter the entire data.
But, if file is created, this information can be accessed using few commands.
There are large numbers of functions to handle file I/O in C language. In this
study material, you will learn to handle standard I/O (High level file I/O
functions) in C.
High level file I/O functions can be categorized as:
1. Text file
2. Binary file
File Operations
1. Creating a new file
2. Opening an existing file
3. Reading from and writing information to a file
4. Closing a file
Working with file
While working with file, you need to declare a pointer of type file. This
declaration is needed for communication between file and program.
FILE *ptr;
fopen() and fclose() functions
Opening a file
Opening a file is performed using library function fopen(). The syntax for
opening a file in standard I/O is:
ptr=fopen("fileopen","mode")
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 125
For Example:
SYNTAX:-
fopen("E:\\cprogram\program.txt","w");
/* --------------------------------------------------------- */
E:\\cprogram\program.txt is the location to create file.
"w" represents the mode for writing.
/* --------------------------------------------------------- */
Here, the program.txt file is opened for writing mode.
Opening Modes in Standard I/O
File Mode Meaning of Mode During Inexistence of file
r Open for reading. If the file does not exist,
fopen() returns NULL.
w Open for writing.
If the file exists, its contents
are overwritten. If the file does
not exist, it will be created.
a
Open for append.
i.e, Data is added to
end of file.
If the file does not exists, it
will be created.
r+ Open for both
reading and writing.
If the file does not exist,
fopen() returns NULL.
w+ Open for both
reading and writing.
If the file exists, its contents
are overwritten. If the file does
not exist, it will be created.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 126
Opening Modes in Standard I/O
File Mode Meaning of Mode During Inexistence of file
a+
Open for both
reading and
appending.
If the file does not exists, it
will be created.
Closing a File
The file should be closed after reading/writing of a file. Closing a file is
performed using library function fclose().
SYNTAX:-
fclose(ptr); //ptr is the file pointer associated with file to be closed.
The Functions fprintf() and fscanf() functions.
Important is that the functions fprintf() and fscanf() are the file version of printf()
and fscanf(). The only difference while using fprintf() and fscanf() is that, the
first argument is a pointer to the structure FILE
Character input /output functions ,String input and output functions
Examples:-
Writing to a file
#include <stdio.h>
int main()
{
int n;
FILE *fptr;
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 127
fptr=fopen("C:\\program.txt","w");
if(fptr==NULL){
printf("Error!");
exit(1);
}
printf("Enter n: ");
scanf("%d",&n);
fprintf(fptr,"%d",n);
fclose(fptr);
return 0;
}
This program takes the number from user and stores in file. After you compile
and run this program, you can see a text file program.txt created in C drive of
your computer. When you open that file, you can see the integer you entered.
Similarly, fscanf() can be used to read data from file.
Reading from file
#include <stdio.h>
int main()
{
int n;
FILE *fptr;
if ((fptr=fopen("C:\\program.txt","r"))==NULL){
printf("Error! opening file");
exit(1); /* Program exits if file pointer returns NULL. */
}
fscanf(fptr,"%d",&n);
printf("Value of n=%d",n);
fclose(fptr);
return 0;
}
If you have run program above to write in file successfully, you can get the
integer back entered in that program using this program.
Other functions like fgetchar(), fputc() etc. can be used in similar way.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 128
Description
The C library function int fputc(int char, FILE *stream) writes a character (an
unsigned char) specified by the argument char to the specified stream and advances the
position indicator for the stream.
Declaration
Following is the declaration for fputc() function.
SYNTAX:-
int fputc(int char, FILE *stream)
Parameters
char -- This is character to be written. This is passed as its int promotion.
stream -- This is the pointer to a FILE object that identifies the stream where the
character is to be written.
Return Value
If there are no errors, the same character that has been written is returned. If an error
occurs, EOF is returned and the error indicator is set.
Example
The following example shows the usage of fputc() function.
#include <stdio.h>
int main ()
{
FILE *fp;
int ch;
fp = fopen("file.txt", "w+");
for( ch = 33 ; ch <= 100; ch++ )
{
fputc(ch, fp);
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 129
fclose(fp);
return(0);
}
Let us compile and run the above program, this will create a file file.txt in the current
directory which will have following content:
!"#$%&'()*+,-
./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcd
Now let's the content of the above file using the following program:
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("file.txt","r");
while(1)
{
c = fgetc(fp);
if( feof(fp) )
{
break ;
}
printf("%c", c);
}
fclose(fp);
return(0);
}
Binary Files
Depending upon the way file is opened for processing, a file is classified into text
file and binary file.
If a large amount of numerical data it to be stored, text mode will be insufficient.
In such case binary file is used.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 130
Working of binary files is similar to text files with few differences in opening
modes, reading from file and writing to file.
Opening modes of binary files
Opening modes of binary files are rb, rb+, wb, wb+,ab and ab+. The only
difference between opening modes of text and binary files is that, b is
appended to indicate that, it is binary file.
Reading and writing of a binary file.
Functions fread() and fwrite() are used for reading from and writing to a file on the
disk respectively in case of binary files.
Function fwrite() takes four arguments, address of data to be written in disk, size
of data to be written in disk, number of such type of data and pointer to the file
where you want
to write.
Syntax:-
fwrite(address_data,size_data,numbers_data,pointer_to_file);
Function fread() also take 4 arguments similar to fwrite() function as above.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 131
Sequential and Random Access File Handling in C
In computer programming, the two main types of file handling are: Sequential;
Random access.
Sequential files are generally used in cases where the program processes the data in a
sequential fashion – i.e. counting words in a text file – although in some cases, random
access can be feigned by moving backwards and forwards over a sequential file.
True random access file handling, however, only accesses the file at the point at which
the data should be read or written, rather than having to process it sequentially. A hybrid
approach is also possible whereby a part of the file is used for sequential access to locate
something in the random access portion of the file, in much the same way that a File
Allocation Table (FAT) works.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 132
The three main functions are:
rewind() – return the file pointer to the beginning;
fseek() – position the file pointer;
ftell() – return the current offset of the file pointer.
Each of these functions operates on the C file pointer, which is just the offset from the
start of the file, and can be positioned at will. All read/write operations take place at the
current position of the file pointer.
The rewind() Function
The rewind() function can be used in sequential or random access C file programming,
and simply tells the file system to position the file pointer at the start of the file. Any
error flags will also be cleared, and no value is returned.
While useful, the companion function, fseek(), can also be used to reposition the file
pointer at will, including the same behavior as rewind().
Using fseek() and ftell() to Process Files-Positioning the file pointers
The fseek() function is most useful in random access files where either the record (or
block) size is known, or there is an allocation system that denotes the start and end
positions of records in an index portion of the file. The fseek() function takes three
parameters:
FILE * f – the file pointer;
long offset – the position offset;
int origin – the point from which the offset is applied.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 133
The origin parameter can be one of three values:
SEEK_SET – from the start;
SEEK_CUR – from the current position;
SEEK_END – from the end of the file.
So, the equivalent of rewind() would be:
fseek( f, 0, SEEK_SET);
By a similar token, if the programmer wanted to append a record to the end of the file, the
pointer could be repositioned thus:
fseek( f, 0, SEEK_END);
Since fseek() returns an error code (0 for no error) the stdio library also provides a
function that can be called to find out the current offset within the file:
long offset = ftell( FILE * f )
This enables the programmer to create a simple file marker (before updating a record for
example), by storing the file position in a variable, and then supplying it to a call to fseek:
long file_marker = ftell(f);
// … file processing functions
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 134
fseek( f, file_marker, SEEK_SET);
Of course, if the programmer knows the size of each record or block, arithmetic can be
used. For example, to rewind to the start of the current record, a function call such as the
following would suffice:
fseek( f, 0 – record_size, SEEK_CURR);
With these three functions, the C programmer can manipulate both sequential and
random access files, but should always remember that positioning the file pointer is
absolute. In other words, if fseek is used to position the pointer in a read/write file, then
writing will overwrite existing data, permanently.
ERROR HANDLING IN FILES:-
In this C language study material I am going to look at error handling. Although C
programming does not provide direct support for error handling (also called exception
handling), there are ways to do error handling.
Of course the programmer needs to prevent errors during coding and should always test
the return values of functions called by the program. A lot of C function calls return a -1
or NULL in case of an error, so quick test on these return values are easily done with for
instance an ‗if statement‘.
For instance if a program successful ends the return value of the program is zero. If the
program ends with an error usually a number larger than zero is returned (for example
1).
So, the one thing you need to remember is that you (the programmer) are responsible for
error handling. You‘re the person that needs to make sure that a program will gracefully
terminate and not just CRASH unexpectedly! It is you that need to take appropriate
action depending on the return values of function calls.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 135
Global Variable errno
The global variable errno is used by C functions and this integer is set if there is an error
during the function call. To make use of errno you need to include errno.h and you need
to call ‗extern int errno;‘
Let us take a look at an example:
#include <stdio.h>
#include <errno.h>
extern int errno;
int main () {
FILE * fp;
fp = fopen ("filedoesnotexist.txt", "rb");
if (fp == NULL) {
fprintf(stderr, "Value of errno: %d\n", errno);
} else {
fclose (fp);
}
return 0;
}
The output of the program will be something like:
Value of errno is: 2
As you can see we include the stdio.h and errno.h header files. Then ‗extern int errno‘ is
called, so we now have access to the integer errno. To generate an error we open a file
that doesn‘t exist. If the file pointer (fp) equals NULL then we print the value of errno
(in this case errno will be 2). If we get a file pointer (in case the file exists) we close the
file.
The functions strerror() and perror()
In the previous example the errno had a value of 2. But what is the meaning of the value
of 2? How does the user know what this error is? Of course a good practice is to make
some documentation where you describe each error number and what the user should
do. But it is also a good practice to give a good descriptive error message when an error
occurs in the program. The C programming language has two functions that can be used
to display a text message that is associated with errno. The functions are strerror() and
perror().
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 136
The function strerror() returns a pointer to the textual message of the current errno
value. The function perror() displays a string you pass to it, followed by a colon and the
textual message of the current errno value.
Basic C- Files Examples:-
1. Write a C program to read name and marks of n number of
students from user and store them in a file.
#include <stdio.h>
#include<conio.h>
int main(){
char name[50];
int marks,i,n;
clrscr();
printf("Enter number of students: ");
scanf("%d",&n);
FILE *fptr;
fptr=(fopen("C:\\student.txt","w"));
if(fptr==NULL){
printf("Error!");
exit(1);
}
for(i=0;i<n;++i)
{
printf("For student%d\nEnter name: ",i+1);
scanf("%s",name);
printf("Enter marks: ");
scanf("%d",&marks);
fprintf(fptr,"\nName: %s \nMarks=%d \n",name,marks);
}
fclose(fptr);
getch();
return 0;
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 137
2. Write a C program to read name and marks of n number of
students from user and store them in a file. If the file previously
exits, add the information of n students.
#include <stdio.h>
#include<conio.h>
int main(){
char name[50];
int marks,i,n;
clrscr();
printf("Enter number of students: ");
scanf("%d",&n);
FILE *fptr;
fptr=(fopen("C:\\student.txt","a"));
if(fptr==NULL){
printf("Error!");
exit(1);
}
for(i=0;i<n;++i)
{
printf("For student%d\nEnter name: ",i+1);
scanf("%s",name);
printf("Enter marks: ");
scanf("%d",&marks);
fprintf(fptr,"\nName: %s \nMarks=%d \n",name,marks);
}
fclose(fptr);
getch();
return 0;
}
3. Write a C program to write all the members of an array of
strcures to a file using fwrite(). Read the array from the file and
display on the screen.
#include<stdio.h>
#include<conio.h>
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 138
struct s
{
char name[50];
int height;
};
int main(){
struct s a[5],b[5];
FILE *fptr;
int i;
clrscr();
fptr=fopen("file.txt","wb");
for(i=0;i<5;++i)
{
fflush(stdin);
printf("Enter name: ");
gets(a[i].name);
printf("Enter height: ");
scanf("%d",&a[i].height);
}
fwrite(a,sizeof(a),1,fptr);
fclose(fptr);
fptr=fopen("file.txt","rb");
fread(b,sizeof(b),1,fptr);
for(i=0;i<5;++i)
{ printf("Name: %s\nHeight: %d",b[i].name,b[i].height);
}
fclose(fptr);
getch();
}
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 139
MODULE V POINTERS AND PREPROCESSORS: Pointers and address, pointers and functions arguments, pointers and arrays, address arithmetic, character pointer and functions, pointers to pointer ,Initialization of pointers arrays, Dynamic allocations methods, Introduction to Preprocessors, Complier control Directives, programming examples and exercises.
Structures: Primitive and non primitive data types, Definition and applications of Stacks,
Queues, Linked Lists and Trees
DATA STRUCTURE:
An implementation of abstract data type is data structure i.e. a mathematical or
logical model of a particular organization of data is called data structure.
Thus, a data structure is the portion of memory allotted for a model, in which the
required data can be arranged in a proper fashion.
Types:-
A data structure can be broadly classified into (i) Primitive data structure
(ii) Non-primitive data structure
(i) Primitive data structure
The data structures, typically those data structure that are directly operated upon
by machine level instructions i.e. the fundamental data types such as int, float, double in
case of ‗c‘ are known as primitive data structures.
(ii) Non-primitive data structure
The data structures, which are not primitive are called non-primitive data
structures.
There are two types of-primitive data structures.
(a) Linear Data Structures:-
A list, which shows the relationship of adjacency between elements, is said to be
linear data structure. The most, simplest linear data structure is a 1-D array, but
because of its deficiency, list is frequently used for different kinds of data.
(b) Non-linear data structure:-
A list, which doesn‘t show the relationship of adjacency between elements, is said to
be non-linear data structure.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 140
Linear Data Structure:
A list is an ordered list, which consists of different data items connected by means
of a link or pointer. This type of list is also called a linked list. A linked list may be a
single list or double linked list.
Single linked list: - A single linked list is used to traverse among the nodes in
one direction.
Double linked list: - A double linked list is used to traverse among the nodes
in both the directions.
A linked list is normally used to represent any data used in word-processing
applications, also applied in different DBMS packages.
A list has two subsets. They are: -
Stack: - It is also called as last-in-first-out (LIFO) system. It is a linear list in
which insertion and deletion take place only at one end. It is used to evaluate
different expressions.
Queue: - It is also called as first-in-first-out (FIFO) system. It is a linear list in
which insertion takes place at once end and deletion takes place at other end.
It is generally used to schedule a job in operating systems and networks.
Non-linear data structure:-
The frequently used non-linear data structures are
(a) Trees : - It maintains hierarchical relationship between various elements
(b) Graphs : - It maintains random relationship or point-to-point relationship
between various elements.
OPERATION ON DATA STRUCTURES: -
The four major operations performed on data structures are:
(i) Insertion : - Insertion means adding new details or new node into the data
structure.
(ii) Deletion : - Deletion means removing a node from the data structure.
(iii) Traversal : - Traversing means accessing each node exactly once so that the
nodes of a data structure can be processed. Traversing is also
called as visiting.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 141
(iv) Searching : - Searching means finding the location of node for a given key
value.
Apart from the four operations mentioned above, there are two more operations
occasionally performed on data structures. They are:
(a) Sorting : - Sorting means arranging the data in a particular order.
(b) Merging : - Merging means joining two lists.
REPRESENATION OF DATA STRUCTURES:-
Any data structure can be represented in two ways. They are: -
(i) Sequential representation
(ii) Linked representation
(i) Sequential representation: - A sequential representation maintains the data in
continuous memory locations which takes less time to retrieve the data but
leads to time complexity during insertion and deletion operations. Because of
sequential nature, the elements of the list must be freed, when we want to
insert a new element or new data at a particular position of the list. To acquire
free space in the list, one must shift the data of the list towards the right side
from the position where the data has to be inserted. Thus, the time taken by
CPU to shift the data will be much higher than the insertion operation and will
lead to complexity in the algorithm. Similarly, while deleting an item from the
list, one must shift the data items towards the left side of the list, which may
waste CPU time.
Drawback of Sequential representation: -
The major drawback of sequential representation is taking much time for
insertion and deletion operations unnecessarily and increasing the complexity
of algorithm.
(ii) Linked Representation: - Linked representation maintains the list by means
of a link between the adjacent elements which need not be stored in
continuous memory locations. During insertion and deletion operations, links
will be created or removed between which takes less time when compared to
the corresponding operations of sequential representation.
Because of the advantages mentioned above, generally, linked representation is preferred
for any data structure.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 142
STACKS
A stack is a linear data structure in which an element may be inserted or deleted
only at one end called the top end of the stack i.e. the elements are removed from a stack
in the reverse order of that in which they were inserted into the stack.
A stack follows the principle of last-in-first-out (LIFO) system. According to the
stack terminology, PUSH and POP are two terms used for insert and delete operations.
Representation of Stacks
A stack may be represented by means of a one way list or a linear array. Unless,
otherwise stated, each of the stacks will be maintained by a linear array STACK, A
variable TOP contains the location of the top element of the stack. A variable N gives the
maximum number elements that can be held by the stack. The condition where TOP is
NULL, indicate that the stack is empty. The condition where TOP is N, will indicate that
the stack is full.
Application of Stacks
There are two important applications of stacks.
a) Recursion
b) Arithmetic Expression
Recursion
Recursion is and important facility in many programming languages. There are
many problems whose algorithmic description is best described in a recursive manner.
A function is called recursive if the function definition refers to itself or does
refers to another function which in turn refers back to the same function. In-order for the
definition not to be circular, it must have the following properties:
(i) There must be certain arguments called base values, for which the function
does not refer to itself.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 143
(ii) Each time the function does refer to itself, the argument of the function
must be closer to a base value.
A recursive function with those two properties is said to be well defined.
Let us consider the factorial of a number and its algorithm described recursively:
We know that N! = N * (N-1)!
(N-1)! = N-1 * (N-2)! and so on up to 1.
FACT(N)
1. if N=1
return 1
2. else return N * FACT(N-1)
3. end Let N be 5.
Then according to the definition FACT(5) will call FACT(4), FACT(4) will call
FACT(3), FACT(3) will call FACT(2), FACT(2) will call FACT(1). Then the execution
will return back by finishing the execution of FACT(1), then FACT(2) and so on up to
FACT(5) as described below.
1) 5! = 5 * 4!
2) 4! = 4 * 3!
3) 3! = 3 * 2!
4) 2! = 2 * 1!
5) 1! = 1
6) 2! = 2 * 1 = 2
7) 3! = 3 * 2 = 6
8) 4! = 4 * 6 = 24
9) 5! = 5 * 24 = 120
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 144
From above example it is clear that every sub function contain parameters and local
variables. The parameters are the arguments which receive values from objects in the
calling program and which transmit values back to the calling program. The sub-function
must also keep track of the return address in the calling program. This return address is
essential since control must be transferred back to its proper place in the calling program.
After completion of the sub-function when the control is transferred back to its calling
program, the local values and returning address is no longer needed. Suppose our sub-
program is a recursive one, when it call itself, then current values must be saved, since
they will be used again when the program is reactivated.
Thus, in recursive process a data structure is required to handle the data of ongoing
called function and the function which is called at last must be processed first. i.e the data
accessed last must be processed fist i.e Last in first out principle. So, a stack may be
suitable data structure that follows LIFO to implement recursion.
Queue
Queue is a linear data structure in which insertion can take place at only one end
called rear end and deletion can take place at other end called top end. The front and rear
are two terms used to represent the two ends of the list when it is implemented as queue.
Queue is also called First In First Out (FIFO) system since the first element in queue will
be the first element out of the queue.
Like stacks, queues may be represented in various ways, usually by means of one
way list or linear arrays. Generally, they are maintained in linear array QUEUE. Two
pointers FRONT and REAR are used to represent front and last element respectively. N
may be the size of the linear array. The condition when FRONT is NULL indicate that
the queue is empty. The condition when REAR is N indicated overflow.
Circular Queue
The linear arrangement of the queue always considers the elements in forward
direction. In the above two algorithms, we had seen that, the pointers front and rear are
always incremented as and when we delete or insert element respectively. Suppose in a
queue of 10 elements front points to 4th
element and rear points to 8th element as follows.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 145
1 2 3 4 5 6 7 8 9 10
QUEUE XX XX XX XX XX
FRONT REAR
When we insert two more elements then the array will become
1 2 3 4 5 6 7 8 9 10
QUEUE XX XX XX XX XX XX XX
FRONT REAR
Later, when we try to insert some elements, then according to the logic when REAR is N
then it encounters an overflow situation. But there are some elements are left blank at the
beginning part of the array. To utilize those left over spaces more efficiently, a circular
fashion is implemented in queue representation. The circular fashion of queue reassigns
the rear pointer with 1 if it reaches N and beginning elements are free and the process is
continued for deletion also. Such queues are called Circular Queue.
Types of QUEUE
There are two types of Queue
Priority Queue
Double Ended Queue
Priority Queue
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 146
A priority queue is a collection of elements such that each element has been
assigned a priority value such that the order in which elements are deleted and processed
comes from the following rules
1. An element of higher priority is processed before any element of lower priority.
2. Two elements with the same priority are processed according to the order in
which they were added to the queue.
There are various ways of maintaining a priority queue in memory. One is using one
way list. The sequential representation is never preferred for priority queue. We use
linked Queue for priority Queue.
Double Ended Queue
A Double Ended Queue is in short called as Deque (pronounced as Deck or dequeue). A
deque is a linear queue in which insertion and deletion can take place at either ends but
not in the middle.
There are two types of Deque.
1. Input restricted Deque
2. Output restricted Deque
A Deque which allows insertion at only at one end of the list but allows deletion
at both the ends of the list is called Input restricted Deque.
A Deque which allows deletion at only at one end of the list but allows insertion
at both the ends of the list is called Output restricted Deque.
A linked list is a linked representation of the ordered list. It is a linear collection of data
elements termed as nodes whose linear order is given by means of link or pointer. Every
node consist of two parts. The first part is called INFO, contains information of the data
and second part is called LINK, contains the address of the next node in the list. A
variable called START, always points to the first node of the list and the link part of the
last node always contains null value. A null value in the START variable denotes that the
list is empty.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 147
INFO LINK
C 1 6
2 3
4 3 5
START A 4 9
5 7
D 6 Null
2 7 8
AVAIL 8 10
B 9 1
10 Null
START
A B C D NULL
Along with the linked list in the memory, a special list is maintained which consists of
list of unused memory cells or unused nodes. This list is called list of available space or
availability list or list of free storage or free storage list or free pool. A variable AVAIL is
used to store the starting address of the availability list.
Sometimes, during insertion, there may not be available space for inserting a data into a
data structure, then the situation is called OVERFLOW. Programmers generally handle
the situation by checking whether AVAIL is NULL or not.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 148
The situation where one wants to delete data from a data structure that is empty is called
UNDERFLOW. The situation is encountered when START is NULL.
Header Linked List :
A header linked list is a linked list, which always contains a special node called the
header node at the beginning of the list. The header node contains the overall information
of the list, which is frequently required for many operations and useful while looking for
such information. There are two kinds of header lists.
a) A grounded header list is a header list where the last node contains the null
pointer.
b) A circular header list is a header list where the last node points back to the
header node.
Circular Linked List :
A linked list is called circular if the last node contains the address of first node or header
list. The advantage of circular linked list is it requires minimum time to traverse the
nodes which are already traversed, with out moving to starting node.
Linked Stack :
The problem with array-based stacks are that the size must be determined at compile
time. Instead, let's use a linked list, with the stack pointer pointing to the top element, let
fresh be the new node. To push a new element on the stack, we must do:
fresh->next = top;
top = fresh;
To pop an item from a linked stack, we just have to reverse the operation.
p = top;
top = top->next;
Linked Queues
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 149
Queues in arrays were ugly because we need wrap around for circular queues. Linked
lists make it easier. We need two pointers to represent our queue - one to the rear for
enqueue operations, and one to the front for dequeue operations.
Note that because both operations move forward through the list, no back pointers are
necessary!
Application of Linked List:
1) Polynomial Manipulation:
A polynomial has multiple terms with same information such as coefficient and powers.
Each term of a polynomial is treated as a node of a list and normally a linked list used to
represent a polynomial. The implementation of polynomial addition is the only operation
that is discussed many place. Multiplication of polynomials can be obtained by
performing repeated additions.
Each polynomial is stored in decreasing order of by term according to the criteria of that
polynomial. i.e. The term whose powers are more are stored at first node and the least
power term is stored at last. This ordering of polynomials makes the addition of
polynomials easy. In fact two polynomials can be added or multiplied by scanning each
of their terms only once.
2) Linked Dictionary:
An important part of any compiler is the construction and maintenance of a dictionary
containing names and their associated values. Such dictionary is also called Symbol
Table. There may be several symbols corresponding to variable names, labels, literals,
etc.
The constraints, which must be considered in the design of the symbol tables, are
processing time and memory space. There are many phases associated with the
construction of symbol tables. The main phases are building and referencing.
It is very easy to construct a very fast symbol table system, provided that a large section
of memory is available. In such case a unique address is assigned to each name. The most
straightforward method of accessing a symbol table is linear search technique. This
method involves arranging the symbols sequentially in memory via an array or by using a
simple linked list. An insertion can be easily handled by adding new element to the end
of the list. When it is desired to access a particular symbol, the table is searched
sequentially from its beginning until it is found. It will take n/2 comparisons to find a
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 150
particular symbol. The insertion mechanism is fast but the referencing is extremely slow.
The referencing will be fast if we use binary search technique. To implement a binary
search on symbol table a tree representation is used.
Double Linked List (Two way List)
Since the single linked list contains only one single pointer that points to the next
of the linked list, there is only one way traversal. So, the reverse direction is not possible,
in the single linked list.
For bi-directional movement, a two-way list or double liked list is considered. IT
is a linear collection of data elements, called nodes. Where each node is divided into
three parts: INFO, PRIOR, and NEXT. The INFO part contains the information of the
node and PRIOR and NEXT are the pointers refers to predecessor node and successor
node address respectively. The list also has two pointers: START and LAST. START
points to the first node of the list where as LAST points to last node of the list. The
PRIOR part of the first node and NEXT part of the last node contains always null value.
PRIOR INFO NEXT
4 9 C 1 6
START 2 3
3 5
Null A 4 9
6 5 7
LAST 1 D 6 Null
7 8
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 151
8 10
START 2 4 B 9 1
LAST
AVAIL 10 Null
A B C D
NULL NULL
Difference between single linked list and double linked list :
The Single linked list has only one advantage, that it can traverse a list in one direction.
That means one cannot get the address of its predecessor node. i.e. When we look for any
previous information of the list during operations then one has to traverse again from the
start node of the one way list. Which uses an extra pointer and additional searching time.
But in case double linked list we can have the address of the next as well as previous
node. So, while we look for previous node address, we can obtain through prior part of
the two-way list which need not require extra pointer or takes less time than that of the
single linked list. So apart from the bi-directional movement facility, the two-way list
also saves the time and space during traversal operation.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 152
Trees
A tree is a nonlinear data structure and is generally defined as a nonempty finite set of
elements, called nodes such that:
1. T contains a distinguished node called root of the tree.
2. The remaining elements of tree form an ordered collection of zero or more
disjoint subsets called sub tree.
Binary Tree :
A binary tree is defined as a finite set of elements, called nodes, such that:
1) Tree is empty (called the null tree or empty tree) or
2) Tree contains a distinguished node called root node, and the remaining nodes
form an ordered pair of disjoint binary trees
R
T1 T2
In the above tree R is the root node and T1 and T2 are called subtrees. T1 and T2
are left and right successor of R. The node R is called parent node and T1 and T2 are
called children. All lower level nodes are called descendants and upper level nodes are
called ancestors of their descendants. The line drawn between parent and child is called
an edge or arc where as the line(s) between and ancestor and descendant is called path. A
node without any children is called a terminal or leaf node and all others are called non-
terminal or non-leaf node. A path ending with a leaf is called a branch.
Each node in a binary tree is assigned a level number, as follows. The root node is
assigned the level number 0, and every other node is assigned a level number, which are
1 more than the level number of its parent. The nodes of same level number are said to
belong to same generation. Nodes of same parent are called siblings.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 153
The depth or height of a tree is the maximum level number of the tree or
maximum number of nodes in a branch of a tree.
Two trees are said to be similar if they have the same structure and are said to be
copies if they are similar and if they have same contents at corresponding nodes.
Complete Binary Tree:
A binary tree is said to be complete if all its level except
possibly the last, have maximum number of possible nodes,
and if all the nodes at the last level appear as far left as
possible.
Full binary tree:
A binary tree said to be full if all its level have maximum
number of possible node.
Extended Binary Tree (Strictly Binary Tree or 2-tree):
A binary tree is said to be Extended binary tree if each node
has either 0 or 2 children. In this case the leaf nodes are
called external nodes and the node with two children are
called internal nodes.
Skewed Tree:
A tree is called Skew if all the nodes of a tree are attached
to one side only. i.e A left skew will not have any right
children in its each node and right skew will not have any
left child in its each node.
Left Skew Right Skew
Binary Search Trees:
A tree is called binary search tree if each node of the tree has following properties.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 154
The value at a node is greater than every value in the left subtree and is less than
every value in the right subtree.
Heap:
A binary tree is also called a heap and there are two types of heap. The are Max Heap and
Min Heap. A heap is called maximum heap if value of a node is greater than or equal to
each of its descendant node. A heap is called minimum heap if value of a node is less
than or equal to each of its descendant node.
Representation of Binary Search Tree :
Sequential Representation :
The sequential representation of tree stores data in an array as per the following rules:
1. The root node is stored in 1st position.
2. Every left and right child of a parent node at location k will be stored in
(2*K)th position and (2*K+1)
th position respectively.
The following example shows the representation of binary tree in an array.
F B H A D G I C E
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Suppose an array is representing a tree then its tree representation will be drawn using the
same rule and an example is shown bellow.
A B C D E F G H I J
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 155
Linked Representation of Tree:
The Linked representations of tree, maintains three parallel arrays. An INFO array
contains the data of each node, LEFT array contains the location of left child and RIGHT
array contains location of right child. A ROOT pointer points to the root node of the tree.
LEFT INFO RIGHT
null C 1 null
2 4
3 5 D 3 9
ROOT 4 6
7 B 5 1
6 8
2 null A 7 null
AVAIL 8 10
null E 9 null
10 null
Header Nodes:
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 156
When a binary tree is maintained in memory by means of a linked representation.
Sometimes an extra, special node, called a header node, is added to the beginning of the
tree. When this extra node is used, the tree pointer variable, which is called HEAD, will
point to the header node, and the left pointer of the header node will point to the root.
Generally, the header node of any tree contains the general or overall information of the
tree, which is required frequently in the operation of the tree. For example, number of
employees present in employee tree, number nodes present in a tree, cumulative values of
all the nodes etc. so that while accessing such information the nodes of the tree need not
be traversed.
Threads and Threaded Binary Tree:
Approximately half of the entries in the pointer fields Left and right of any binary
tree contains null elements. Replacing the null entries by some other type of information
may more efficiently use this space. Specifically, we will replace certain null entries by
special pointers, which point to nodes higher in the tree. These special pointers are called
threads and the tree is called threaded binary tree.
There are many ways to thread a binary tree, but each threading will correspond
to a particular traversal of tree. Unless otherwise stated, threading will correspond to in-
order traversal.
There are two types of threading:
One way threading
Two way threading
In one way threading, either left pointer or right pointer will be used for threading.
When left pointer used to point the predecessor node of the tree according to in-order
traversal, then the threading is called left-in threading. When a right pointer is used to
point the successor node according to in-order traversal, then the threading is called right-
in threading.
In two way threading both left and right pointers are used to point predecessor and
successor nodes of the tree according to in-order traversal.
Height Balanced Tree(AVL Tree):
Adelson-Velskii and Landis in 1962 introduced a binary tree structure that is
balanced with respect to heights of the subtrees. As a result of the balanced nature of this
type of tree, dynamic retrievals can be performed in less time. At the same time an
identifier may be inserted and deleted in that tree in less time.
Definition: A empty tree is called height balanced. If the tree is nonempty binary tree
T with TL and TR as its left and right subtrees, then tree is called height balanced iff
a) hL – hR is –1, or 0 , or1 where hL and hR are heights of left subtree TL and right
subtrees TR respectively.
b) TL and TR are height balanced.
PROGRAMMING IN C AND DATA STRUCTURES
DEPARTMENT OF CSE Page 157
Generally, while inserting or deleting an identifier in tree we balance the tree.
Balancing of a tree is carried out using essentially two kind of rotation left rotation and
right rotation. When a tree at a node has Balance Factor less –1 then the tree at that node
is considered to be right heavy. To balance the right heavy tree the tree at that node
rotated towards left. Similarly, if the tree is at a node is heaving Balance Factor more than
1 will be considered as left heavy. To balance the left heavy tree, the tree is rotated
towards right at that node.
Application of Binary Tree:
1. Symbol Table Construction:
The notion of symbol table arises frequently in computer science while building
compilers, loaders, linkers, assemblers etc. A symbol table is a set of name-value pairs.
Associated with each name in the table is an attribute, a collection of attributes, or some
directions about what further processing is needed. One of the criteria that a symbol table
routine must meet is that the table searching must be performed efficiently. This
requirement originates in the compilation phase while handling many lexemes and tokens
of the program. The three required operation of the symbol table are:
a) Insertion of new entry
b) Deletion of existing entry
c) Looking up information of an existing entry.
Each of above operation requires searching.
Generally, a tree is used to construct a symbol table because
a) If the symbol table entries as encountered are uniformly distributed according
to lexicographic order, then table searching becomes approximately
equivalent to a binary search, as long as the tree is maintained in lexicographic
order.
b) A binary tree is easily maintained in lexicographic order.
2) Manipulation of the Arithmetic Expressions:
We observed that the formulas in Reverse polish notation are very useful in the
compilation process. There is a close relationship between binary trees and formulas in
prefix or suffix notations. Let us write the infix formula as a binary tree where a node has
an operator as a value and where the left and right sub trees are the left and right operands
of that operator. The leaves of the tree are the variables and constants of the expression.
We represent the expression in binary tree due to similarities of infix to in order and
postfix to post order traversal of tree. The tree used for expression is called parse tree.