75% found this document useful (4 votes)
2K views270 pages

C Language by Example (23-2-2021)

This document provides an introduction and overview of the C programming language. It discusses the brief history of C, including its origins from predecessors like CPL and B and its development at Bell Labs in the early 1970s. It then provides a high-level index of the chapters and topics that will be covered in the book, including introductions to programming concepts, control structures, arrays, functions, pointers, file handling and more. The document concludes by providing background on the publisher C-Family Computers and contact information.

Uploaded by

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

C Language by Example (23-2-2021)

This document provides an introduction and overview of the C programming language. It discusses the brief history of C, including its origins from predecessors like CPL and B and its development at Bell Labs in the early 1970s. It then provides a high-level index of the chapters and topics that will be covered in the book, including introductions to programming concepts, control structures, arrays, functions, pointers, file handling and more. The document concludes by providing background on the publisher C-Family Computers and contact information.

Uploaded by

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

C-Family 1 Preface & Index

A Complete Material on C-Language Programming

This book softcopy is available in pdfhost.io website, to download the file, search through keyword
‘cfamily1999’, along with this book, you get 500 exercise programs list on C,C++, Java programming.
This pdf file(s) designed for 2-sided print-copy (Xerox copy).
C-Family 2 Preface & Index

Chapter Index Page No


Introduction to C 5
history of C, evolution of languages 5
features of C language 7
assembler, compiler, interpreter 8
keywords, tokens, data types, expressions 9
operators 11
garbage values, comment lines 18
Introduction to Programming 19
library-functions, user-functions, proto-type of function 19,20,21
about main() 22
first C program 23
compiling and running a program 24
escape sequence characters 27
type casting 32
representation of constants in C 33
flow chart, algorithm, pseudo code 34-38

Decision Control Structures 39


if, if-else 39-43
nested-if 48
If-else-if ladder 54
If-else linking, about Boolean value, null instruction 60, 61, 63
switch statement, conditional operator, goto statement 65, 68,71

Looping Control Structures 72


while loop 105
for loop 107
do-while loop 109
break, continue 111
nested loop 112

One Dimensional Arrays 121


accessing & initialization of arrays 122,123
about array size , array boundaries 124
C-Family 3 Preface & Index

Functions 132

types of functions, library functions, user functions 132,133


function body & its call syntax 137
more about functions 146

Pointers 151
operators in pointers 152
arrays & pointers, passing array to function 161,164
call-by-value vs call-by-reference 169

Sorting & Searching 172

Storage Classes 180

Preprocessor Directives 186

2D Arrays 191

Characters & Strings 200-203


initialization of strings 203
pointer to string, passing array to function 207, 208
array of strings 219

Recursion 224

Dynamic Memory Allocation 237

Command Line Arguments 241

User Defined Data types 242


structures, array of structures 243, 244
different declaration structures, typedef, advantages of structures 246, 247
union, enumeration 248, 250

File Handling 258


text files, binary files 259
IO operations on files 260
C-Family 4 Preface & Index

C by Examples
A complete reference material on C-language programming

About C
C-language is an ideal programming language and a perfect combination of power and flexibility. Though
it is a high-level language, it has low level features as well as easy interaction with hardware and OS. Even
assembly language code can be mixed in it. It is accepted as a good system programming language.
Powerful OS like UNIX was developed using C.

‘C’ is widely used in the software industry for both system and application side development. C is the
primary subject in computer science. It lays good foundation in programming and eases the learning of
any advanced courses that are to follow. So, it has been added in every branch of arts, science, and
engineering as part of curriculum. Every graduate student is going to face C, C++, DS, Java, Python and
Oracle in the first & second academic years.

About C-Family Computers


C-Family is a premier institute in Vijayawada training the students in C, C++, DS, Java, Python, Oracle,
WebDesign courses since 1999. C-family was not setup by any business men instead it was setup and
run by a group of eminent programmers. We provide hands on training to ambitious students in right
proportions to their passion for knowledge. Needless to say, taking individual care of each student is
the hallmark of our institution. Our courses are designed in such a way that student get best
foundation in logic and programming skills. [The languages C, C++, VC, VC++, JAVA are called C-Family
Languages, as we teach all these courses, we named this institute C-Family Computer Education]

I am grateful to all the students, friends, staff who helped me making this material. This book is
advisable to learn the logic and programming skills for beginners. For any suggestions contact me on
[email protected]

by Srihari Bezawada

since 1999
C-Family Computer Education,
#40-9/1-26, Vasayva Complex,
Dr. Samaram Hospital Lane,
Benz Circle, Vijayawada-10,
9440-030405, 8500-117118.
C-Family 5 Introduction to C

Introduction to C
Brief History of C
In 1960’s, there was a need for general purpose programming language and the available ones were of
specific-purpose only. For example, COBOL was meant for business applications; similarly FORTRAN was
extremely small and suitable only for scientific applications. Instead of being small, simple and specific, the
CPL was intended to support wide range of applications in all sectors; thus, the demand for a general-
purpose language led to the invention of CPL (Combined Programming Language). However, its heavy
specific features made it difficult to program. Its drawbacks were eliminated, simplified and further
developed by Martin Richards and named as BCPL (Basic CPL). Still it had some complex & difficult features
of CPL and these difficulties were simplified by ken Thompson and named it as ‘B’.

Later while developing UNIX operating system in 1969, ken Thomson faced several problems with the B
language; here B was used for programming while making UNIX software. Dennis Ritchie modified the B
language to overcome its limitations to suit all needs and renamed it as C. Of course, the development of
UNIX using C language made it uniquely portable and improvable; Finally, C was released in 1972. Dennis
Ritchie is a research scientist at Bell Telephone Laboratories in U.S.A. Brian Kernighan also participated while
making the definitive description of the language. Therefore, the C is also referred as ‘K&R-C’.

Evolution of languages
We have three types of languages 1.machine language, 2.Assembly language, 3.high level language.
Programs are written using these languages.
A) Machine Language (binary/low level language)
It is treated as first generation language, used during development of computer in 19th century. In this
language, the data and instruction of programs were written in terms of binary symbols (1&0’s), even input
and output were given in binary codes, as the computer understands the instructions only in ones and zeros.
For example, the instruction 9+13 is in binary form like 0010 1001 1101. Here, the first 4 bits represents
addition(+) code and remaining 8 bits are 9 & 13. This language is also called binary or low level language.
Actually, this language is difficult to understand, remember and writing programs in binary codes, it leads to
a lot of typing mistakes, because everything is 1&0s. This problem led to the invention of assembly language.

B) Assembly Language
this is somewhat better than binary language. Here, symbolic names were provided for every binary codes
of machine language. The names such as add, sub, mul, div, cmp, etc. So programmers can easily understand
and write instructions using these names instead of binary 1&0’s. For example adding 4 & 6 in 8088
assembly language as
mov ax,4;
mov bx,6;
add ax,bx
However, the main drawback of assembly language is, a large set of instructions are needed to be written
for simple tasks like addition of two numbers. It supports only small programs if the code is <1000 lines,
otherwise difficult to manage the code. Moreover, assembly differs from one to another machine. Some
people consider Assembly language also a machine language since the assembly codes resembles the
machine codes.
C-Family 6 Introduction to C

C) High Level Language


this is English and mathematical oriented language. Here data and instructions composed in terms of English
words and mathematical expressions. For example c=a+b, c=a-b , if(a<b), …etc. So one can easily learn and
apply high level language code. One can write the programs without the knowledge of computer hardware
and operating system, i.e, it hides(abstract) the underlying details about the instructions how they are being
processed in the machine. So programmers can easily code the programs without bothering about hardware
and O.S. The 8085, 8086 are known as Assembly languages whereas C , C++, JAVA are high level languages.

Assembler & Compiler


Neither assembly nor high-level language programs can be understood by the computer directly. Before
executing them, they have to be converted into binary codes, because, the computer is electronic device, it
can understand and process only binary codes in voltages. The assembler is a translation-software, which
translates assembly language program into equivalent machine code. Similarly compiler translates high-level
language code into equivalent machine understandable code. We have several operating systems and
several C compilers. All most all compilers follow the same rules except for a few modifications.

Operating System
The term O.S refers to a set of programs that manages the resources of a computer. The resources of
computer includes processor, main-memory, disks, and other devices such as keyboard, monitor, printer
that are connected to it. It also provides a good interface to the user. The interface provided by the O.S
enables the user to use the computer without knowing the details of the hardware. So interface hides the
underlying working of a computer. The main jobs of O.S are memory management, process management,
disk management, I/O management, security, and providing interface to the user …etc.

Currently, the widely used operating systems are MS-DOS, UNIX, and WINDOWS. DOS is a simple operating
system largely used in PCs. Unix, Linux, Mac, Windows on the other hand used variety of computers such as
mainframes, servers, graphics workstations, supercomputers, and also in PCs.

When a user runs a particular program (application) in the computer, the operating system loads the
program into main memory (RAM) from the hard-disk, and then executes the instruction by instruction with
the help of processor. The processor can take & execute only one instruction at a time. So this loading and
executing instructions is done under the control of OS. Thus OS executes our programs with the help of
hardware. OS is the main responsible for all these things and also makes the computer in working for other
tasks.

The relation between hardware, operating system, user-program, and user can simulate with a banking-
system such as bank, employee, transaction and customer. The hardware as a bank and O.S as a bank
employee, who works dedicatedly to organize all transactions of a bank, whereas the user as a customer and
user-program as a transaction, the user submit his program just by giving a command to the computer; the
responder, the O.S, takes up the program into main memory and process the instructions on the hardware
under its control. The following picture shows the layers of interaction between user and the computer.

User Customer
User program Transaction
Operating system Bank employee
Computer hardware Bank
C-Family 7 Introduction to C

What is Programming Language?


Language means communication between two people; likewise, programming language is a communication
between user and the computer. The user communicates with the computer by giving instructions to it, the
instructions are written based on the language’s syntax structure provided by the language manufactures.
We have several languages such as Fortran, Pascal, COBOL, C, etc; out of all, C is a rich, simple, elegant,
powerful, and structured language. Now a day’s C became primer language for advanced languages like C++,
Java, C#, VC, VC++, as they all adopted C syntax. All these languages are also called C-Family languages.

Features of C-Language
A) C is a small & compact language: It has small number of keywords and symbols. Therefore, it
provides easy & compact programming. The size of software is also less compared to other language and it
has good library functions.

B) C is a high-level language with low-level features: Although C is technically a high-level


language, it has good syntax, features (pointer) and library functions to interact directly with hardware of
the computer. C linked closely with the machine, so one can directly access the components like hard disk
drive, optical drives, printers, operating system…etc; besides, it supports assembly language instructions
within the C program. That is, one can mix up assembly language instructions within the C program; hence it
is well suited for writing both system software and business packages.

C) C is a structured programming language: Previously, the languages were influenced by


‘if’, ‘goto’, ‘repeat’, etc; writing code using such statements makes the program unreadable and complex.
If there are no ideal structural tools to force the programmer to write the code in uniform style then
everybody writes one’s own style and makes the program complex and un-readable to others. For example,
if there are no predefined traffic rules in city roads, everyone travels as per one’s convenience and makes
traffic disordered and cause inconvenience to others; so the traffic structures such as signals, dividers, zebra
lines and indicators force the traveler to follow rules in order not to cause confusion. Now, the word
structured means a predefined logical model (uniform syntax) and structured programming means, writing
instructions in a predefined structured manner, thereby every programmer writes instruction in uniform
style and made easy to understand by others.
Structured programming was first suggested by Corrado Bohm and Guiseppe Jacopini. The two
mathematicians demonstrated that any computer program can be written with just three structures:
sequence, decision, and looping. ie, the logic of any program can be expressed in terms of these structures.
A program of any complexity can be solved by the appropriate combinations (mixture) of these three basic
constructs. These structures are constructed with one entry and one exit style, so that one can easily
understand the execution flow of a program. Thus structured programming greatly reduces the complexity
of programs. So every structured language supports the following constructs
 Conditional execution of statements (i.e., "if" statements).
 Case selection.
 Looping.
 Subroutine (functions/sub programs)
Subroutine: The features of function provide the facility to divide the big program into several reusable
segments called sub-programs, each with the all necessary data and related instructions to perform a certain
task and hide (independent) from the rest of the program. Thus, this collection of sub-programs made up
the entire program.
C-Family 8 Introduction to C

D) C is a portable language: The word portable means easy to carry or transfer, here the portability
refers to the ability of a program to run on different environments (hardware or operating systems).
As ‘C’ became powerful, it had provided different version of C-compilers for different operating systems.
A C-program written in one platform can be portable to any other platform with few/negligible
modifications. For example, a program written in UNIX operating system can be easily converted to run in
WINDOWS or DOS and vice versa.

E) C has flexible coding style: Unlike other languages (COBOL, FORTRAN), C provides freedom to the
programmer while coding the program. We can write the code without bothering about the alignment of
the program. The C compiler can recognize the code even when the program is not aligned or typed
properly. In other words, we can use more spaces, empty lines in between instructions (tokens), or we can
type several instructions in one line.

F) Widely Acceptable: It is suitable for both system and application side programming. It frees the
programmer from traditional programming limitations. It empowers the programmer to develop any kind of
applications. Thus, accepted by almost all users and became the most popular language in the world. In fact,
many of the software available in the market are written in C.

G) C is a case sensitive language: In C, an upper case alphabet is never treated equal to the lower
case alphabet and vice versa. All most all keywords and predefined routines of C languages use only lower
case alphabets. Therefore, it is very simple to type in only one case. Of course, some user defined symbols
(identifiers) can be typed in upper case to identify them uniquely.

Character set of C
It is a set of symbols called characters, which are supported by the C-language. C supports all most all
symbols which are provided in the keyboard
 Lower case alphabets (a-z)
 Upper case alphabets (A-Z)
 Digits (0-9)
 White space (‘ ‘)
 Math symbols ( + , - , * , / , % < > = …etc )
 Special symbols like {} [] () ! & , “ \ …etc )

Keywords
Like English language vocabulary, C has its own vocabulary called keywords; thus Keyword is a reserved
word, which has specific meaning in C, and it cannot be used for other purpose, using these keywords the
programs are constructed. C has the following standard set of 32 keywords.
if, else, switch, for, while, break, continue, goto, auto, register, extern, static, volatile, return, enum, void,
char, int, long, short, float, double, signed, unsigned, case, const, default, do, union, sizeof, typedef, struct;
Note: All keywords should be written in lower case. Depending on the compiler/vendor, few additional
keywords may also exist.

Tokens
Let the expression ‘x+y’. It has three tokens ‘x’, ’y’ and ‘+’. Here x, y are called operands, and ‘+’ is called an
operator. The compiler splits all the instructions into individual tokens for checking syntax errors. Splitting
expression into tokens and checking is known as parsing.
C-Family 9 Introduction to C

Now token can be defined as an elementary item in the program, which is parsed by the compiler.
Token can be a keyword, operator, identifier, constant, or any other symbol;
For example, consider the following statements.
 a+b // ‘a’, ’b’ and ‘+’ are 3 individual tokens.
 a<=b // ‘a’, ‘b’, and ‘<=’ are 3 tokens (not 4)
 c++ // ‘c’ and ‘++’ are 2 tokens
 if(a<b) // it has 6 token
Note: Here tokens ‘<=’ or ‘++’ misunderstand as two tokens, but they are single tokens.

Instructions & program


Instruction is a command that is given to the computer processor to perform a certain elementary task.
For example, consider a simple addition instruction 10+20, when this instruction executes, we get 30.
Statement is a meaningful combination of one or more instructions that solves a complex task.
For example, consider calculating area of a circle “area=22/7*radius*radius“
Program is an organized collection of such related instructions/statements to solve a specified problem.
Software can be defined as collection of one or more programs.
The programs look like the following example; this calculates the sum of two numbers
step1. input(a,b)
step2. c=a+b
step3. print(c)

Classification of Data (Data types)


Data means a value or a set of values that represent attributes like age, experience, address, salary, …etc;
for example, the “employee record” contains data like idno, name, age, experience, address, salary…etc;
The computer hardware (processor) designed to process only two types of data
1.integral (also called integer values)
2.floating point (also called real numbers or precisions)
The integral data are rounded values like 10, 20, -343, etc, whereas floating points are 15.44, -45.56, etc;
so, in the real world, any kind of data comes under these two types, for example, the employee number,
name, address are integral types; [the name & address are stored as array of ASCII values of integral types];
the basic salary, net salary and other values are stored in floating point format;

In C, these data are classified into nine types based on the application’s requirement and hardware support;
these are known as built-in or primitive or basic types.

data

Integral Floating point

1 byte 2 byte 4 byte 4 byte 8 byte 10 byte


(char) (int) (long int) (float) (double) (long double)

signed unsigned signed unsigned signed unsigned


char char int int long int long int
C-Family 10 Introduction to C

Type Bytes occupied Range

singed char 1 -128 to 127


unsigned char 1 0 to 255

signed int 2 -32768 to 32767

unsigned int 2 0 to 65,535

signed short int 2 -32768 to 32767

unsigned short int 2 0 to 65,535


signed long int 4 -2147483648 to 2147483647
unsigned long int 4 0 to 4294967295

float 4 3.4 e-38 to 3.4 e+38

double 8 1.7e-308 to 1.7e+308

long double 10 3.4 e-4932 to 3.4 e+4932

signed int or unsigned int are system dependents, for example, in 16-bit DOS, it occupies 16 bits of memory,
whereas in 32-bit Unix/Windows, it occupies 32 bits of memory. So they occupy 2/4 bytes based on system.

The keyword signed is an optional word for signed types. That means, even if we do not mention the
keyword ‘signed’, the compiler by default takes as signed types.
For example, the ‘int’ is equal to ‘signed int’ in the C-language.
int a, b, c;  is equal to  signed int a, b , c;

Representing –ve values


For signed types, the leftmost bit is used to represent sign (+ve/-ve). This bit is called sign bit, If this bit
contained 0 then it is said to be +ve value, or else –ve value, For example,
the value +13(1101) is stored in one byte as follows
+ve sign
0 0 0 0 1 1 0 1
th th th th th rd nd st
8 bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit

The value -13 is stored as follows


-ve sign
1 0 0 0 1 1 0 1
th th th th th rd nd st
8 bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit

Note: This kind of value representation is called “signed magnitude representation”. Actually, 2’s
compliment representation is used for negative values. In the same way floating point numbers float,
double, long double are also represented in a special IEEE format, for further details Google it.
C-Family 11 Introduction to C

Operators
Operator is a symbol or keyword used to compute mathematical or logical calculations in a program.
C provides rich set of operators for making flexible and simple expressions. Operators are classified primarily
into four categories: arithmetic, relational, logical, and bitwise. Assignment, referencing, de-referencing are
called special operators. Each operator comes under one of the following types.
Unary Operators: These operators are associated with only one operand.
Binary Operators: These operators are associated with two operands.
Ternary Operators: These take three operands to perform an operation.
Note: just go through these operators briefly, we can learn in detailed in rest of the chapters.

Unary Binary Ternary


Sign + ve sign , -ve sign
+ Addition
++ (increment) - Subtraction
Arithmetic * Multiplication
-- (decrement) / Division
% Modulo division
< Less than ?:
> Greater than Conditional
>= greater than equal to operator
Relational
<= less than or equal to
== equal to
!= not equal to
! (NOT) && AND
Logical
|| OR
& Bitwise AND
| Bitwise OR
Bitwise ~ (1’s compliment) ^ Bitwise exclusive OR
>> Right shifting
<< Left shifting
= Simple Assignment
+= Addition Assignment
Assignment -= Subtraction Assignment
/= Division Assignment
*= %= …etc
sizeof . direct selection
miscellaneous * (dereferencing) -> Indirect selection
& (Referencing) , expression separator

A) Arithmetic operators
These operators are used to calculate arithmetical sums such as addition(+), subtraction(-), multiplication
(*), division(/) for quotient and modulus division(%) for remainder.
Let us see some of arithmetic expressions. Here a & b are operands
a + b, a - b, a * b, a / b, a%b
Integer division gives only the integer part of the result, that is, the fraction part is truncated (ignored).
For example, the result of 15/2 is 7 (not 7.5). The floating point division gives fractions also (15.0/27.5)
The modulus-division gives the remainder of a division, for example 17%32. Notice that, we cannot apply
modulus-division on floating point values as the division goes on and on, till the remainder becomes zero, so
it is meaningless applying ‘%’ on float values. For example the instruction 15.0%2.0 is an error statement.
(In some cases like 10.0%3.0 divisions goes endlessly)
C-Family 12 Introduction to C

Observe the result of following expressions

15/2  7 // decimal part is truncated, because 15 & 7 are integers


15.0/2  7.5 // because 15.0 is floating point
15.0/2.0  7.5
4/5  0
15%4  3 // remainder of division
4%6  4 // it goes zero times and remainder is 4
-15%6  -3
10%-3  1 // in modulo division, sign of result is, sign of numerator
2.5%5  error

B) Relational operators
These operators are used to find the relation between two values. If relation is found to be true then the
result is 1, otherwise it is 0. (The result of this 1 or 0 value is also said to be BOOLEAN values).
The operators such as: < > <= >= == !=

a>b // greater than comparison


a<b // less than comparison
a <= b // less than or equal comparison
a >= b // greater than or equal comparison
a == b // equality comparison
a != b // non equality comparison
Observe the result of relational operators
2 == 5  0
2 != 5  1
5 < 10  1
10 < 5  0

C) Logical Operators
These operators are used to combine two or more relations to form a single compound relation.
These operators also give the result either 1 or 0 (Boolean value)
&&  Logical AND operator
||  Logical OR operator
!  Logical NOT operator
The operator ‘&&’ works just like the word ‘AND’ in English language.
The operator ‘||’ works just like the word ‘OR’ in English language.
syntax1: relation1 && relation2 eg: if marks1>50 && marks2>50 then student passed
syntax2: relation1 || relation2 eg: if marks1<50 || marks2<50) then student failed
syntax3: ! relation  ! true  false
1) When we want two or more relations to be true for one action then we use AND operator(&&),
for example if A>B and A>C are true, then ‘A’ is said to be bigger than B,C.
In C-lang, it is written as: if(A>B && A>C)
here if both conditions A>B and A>C are satisfied, then the operator && gives the result 1 (true).
If anyone of them is false, the result is 0 (false).
C-Family 13 Introduction to C

2) When we want either of relations to be true for one action, then we use OR operator(||),
for example, If any marks1<35 or marks2<35 or marks3<35 are true, then student is “failed”.
in C program, it is written as  if( marks1<35 || marks2<35 || marks3<35)
if anyone relation is satisfied, the operator || gives the result true. If all are false, then result is false

The following truth table gives result of logical operators

A B A &&B A||B !A
1 1 1 1 0
1 0 0 1 0
0 1 0 1 1
0 0 0 0 1

D) Assignment operator (=)


If you are new to the programming, you definitely misunderstand it as an “equal” comparison operator
which we use in mathematics. But in C, it is used differently to copy one location value to another location.
It is used to assign(copy) right hand side expression’s value to left hand side variable; i.e, it copies RHS
expression’s value to LHS variable;
Syntax1: variable=expression;
Syntax 2: variable1 = variable2 = variable3 =... variableN = expression;

a
a = 10; //assigns 10 to ‘a’ (puts 10 in a’s memory)
10

b = a; //assigns ‘a’ value to ’b’, after this instruction both b a


a , b contains 10
10 10

e f g h
e=f=g=h=100; // assigns 100 to all e, f, g, h
100 100 100 100

c=a+b; // the addition value of a,b assigned to c

a+b=c; // error, not following syntax rules

10=a; // error, not following syntax rules

E) Arithmetic assignment operators (shortcut operators)


These shortcut operators are used when left hand side operand is repeated in right hand side at assignment
operation. For example ‘salary = salary + 1000’, this can be taken in short form as ‘salary += 1000’
The operators are : +=, -=, *=, /=, %= ……etc.
a = a + 10;  a += 10
a = a - 10;  a -= 10
a = a * 200;  a=a* 100;
note: these short operators somewhat confusion as a result discouraged in modern programming.
C-Family 14 Introduction to C

F) Increment or decrement operators (++ , --)


in programming, it is often needed to increment/decrement variable values by 1.
for this, C provides a very important and versatile operators called ‘++’ and ‘- -‘.
these are very famous operators and almost all languages following in computer science..
++ is an increment by one operator
-- is a decrement by one operator
Let us take one example
k=5; // sets 5 to k
k++; // this instruction increments ‘k’ value by 1, so it becomes 6
so this ‘k++’ is a short form of k=k+1
These two operators are again classified into pre & post increment/decrements
1) ++variable; // pre increment
2) --variable; // pre decrement
3) variable ++; // post increment
4) variable --; // post decrement
Pre increment/decrement has highest priority than any other operator. Hence, this operator is evaluated
before any other operator, whereas post increment/decrement has lowest priority than any other operator.
Hence, this is evaluated after all other operators are evaluated; (for clarity sees the operator priority table)
Note: the parenthesis ( ) has no effect on these operators. For example: 2*(a++) is equal to 2*a++;
Let us take some examples, Let a=5, b=10;
1) a++; // this is equal to a=a+1; here ‘a’ becomes 6
b--; // this is equal to b=b-1; here ‘b’ becomes 9

2) b = ++a;  this is equal to given below, first pre-increment and then assignment
++a;
b=a;
result is: a gains 6, b is gains 6

3) b = a++;  this is equal to given below, first assignment and then post-increment
b=a;
a++;
result is: b gains 5, a gains 6

4) b = ++a + ++a + a++;  this is equal to given below, we have two pre-increments, and one post-increment)
++a; // pre increment, so do first ( here ‘a’ becomes 6)
++a; // pre increment, so do first (here ‘a’ becomes 7)
b=a + a + a; // add all values (b=7+7+7)
a++; // post increment, so do last (here ‘a’ becomes 8)
Result of a, b are: a is 8, b is 21
note: So first do all pre increments, next process normal expressions, at last do all post increments.
5) b = a++*3 + ++a + 5*++a;  this is equal to given below
++a;
++a;
b=a*3+a+5*a;
a++;
C-Family 15 Introduction to C

G) sizeof():operator gives the size of memory which is occupied by the variable or constant or data type
sizeof(int)  2
sizeof(long int)  4
sizeof(k)  2 // let k is int type variable
sizeof(10)  2 // 10 is int type value

H) Comma operator(,) : It is used to separate two or more instructions in the program. It is used in
several contexts in the programming. The actual behavior of comma operator is that, it returns the right
hand side operand value as the result of the expression.
a=2, b=3, c=10; // Here comma works as separator
c=a , b; // it is combination of two instructions “c=a and b”, but ‘b’ does nothing
a = (b, c); // it is also a combination of two instructions, “b and a=c”

Operator precedence
In general, complex expressions are formed with the combination of mathematical or logical operators.
While evaluating such expressions, initially the sub expressions are evaluated according to the precedence.
For example, the expression 5+2*4 evaluated as 5+813. Observe the following table showing the relative
precedence of operators in c. Just look once about this precedence, we can learn in detailed in next
chapters.

Priority 1 () [] -> .
Priority 2 ! ~ +(sign) -(sign) ++ -- (pre incr/decr)
Priority 3 sizeof &(reference) *(de-reference)
Priority 4 * / %
Priority 5 + -
Priority 6 << >>
Priority 7 < <= > >=
Priority 8 == !=
Priority 9 ^ | & ( ORing, ANDing)
Priority 10 && ||
Priority 11 ?: (conditional operator)
Priority 12 = *= /= %= += -= &=
Priority 13 ^= |= <<= >>=
Priority 14 Comma operator (,)
Priority 15 ++ -- (post increment/ decrement)

In the above table, Operators in the same row have the same precedence. Among same precedence
operators, the evaluation takes place from left-to-right side in the expression. Only the assignment & unary
operators are performed from right-to-left. For example a=b=c=d, here first c=d is performed later b=c ….
Consider the expression:
1+ 2*3-4+5*6 //left to right performed
1+6-4+5*6
1+6-4+30
7-4+30
3+30
33
C-Family 16 Introduction to C

How to write expressions in C


An expression is a systematic combination of operands and operators to specify the relation among the
values. However, any single constant, variable is also called an expression. For example
1+2 4*5 22/7 10%3 10>5 a a+b
1==0 4<<1 55<=100 -10 10 b a<c
C language allows us to use complex expressions, wherein such expressions should be cautiously handled;
otherwise it leads to logical errors. Let us see, how an expression should be typed in correct syntax.
For example:
1. ax3 + bx2 + c x + d : Answer  a*x*x*x + b*x*x + c*x + d

2. -b+ √b2- 4ac : Answer  (-b+sqrt(b*b-4*a*c))/(2*a)


2*a

3. ax45 + 6x5 : Answer ( a*pow(x,45)+6*pow(x,5)/(c*x+7))


cx+7
Here pow() and sqrt () are functions, finds power and square root of a given value.

Variable and its Naming rules


Program means collection of data and instructions, the data is represented in terms of names such as age,
experience, salary …etc; these names are called variables, which denote a value of a particular instance in
the program; Thus, variable is said to be a name given to the memory location in computer main memory,
wherein constants are stored; these constants may vary during execution of program.
Rules for naming variables, While naming a variable, we should follow rules as explained below
 First letter must be an alphabet
 Only alphabets, digits and underscore are allowed in variable names
 We cannot use any other symbols like comma, hyphen, period…etc.
 Spaces are strictly not allowed.
 Should not be a keyword like ‘if’, ‘else’, ‘while’ …etc.
 The variable name can contain a maximum length of 32 characters.

some valid names Some invalid names


basic_salary 123pq // digits not allowed as first
net_ salary ab,cd // comma not allowed
age first-person // hyphen not allowed
weight double // keyword
name i and j // spaces
marks1 int // keyword
basicSalary units/month // other symbols not allowed
for1 basic salary // space
C-Family 17 Introduction to C

Declaration of variables
The declaration specifies name, size, type and other characteristics of a variable. Before using any variable,
it must be introduced to the compiler about the name, size and type of data it is going to hold.
This introduction is called variable declaration; it involves creation of memory in the RAM and substitution
of logical address (binding) where ever it is used in the program.

Syntax: <data type> <variable1>, [<variable2>, <variable3> … <variable n>];

Here in the syntax, the symbols “< >” represent user-defined and are compulsory, whereas square brackets
[] represent optional. [This is old style syntax, now a days nobody following this syntax]

The above syntax can be written as: dataType variable1, variable2, variable3…;
For example: int k1, k2=10; K1 k2
Garbage value 10
2 bytes 2 bytes
This declaration creates 2 bytes of memory space for k1, k2 in RAM; Here k1 has not been assigned with any
value, so by default, it contains garbage value (un-known value), whereas K2 has been initialized with 10;
Let us see more examples:
int age, experience; // holds person age and experience
char day, month; // holds day, month of a date
int year; // year of date
float salary; // salary of employee

Initialization of variables
We can set a value to the variables at the time of declaration ie, at the time of creation of memory.
This is called initialization of variable.
eg1: int k1=10; // this is called initialization, not an assignment, here k1 initialized with 10;
eg2: int k2;
----
K2=20; // this is not initialization, it is called assignment.
Note: here above 2 examples initialization & assignment affects the same result, we can follow either.

Garbage value
At the time of declaration, when a variable is not initialized with any value, then by default it holds an
unknown value called garbage value. This value may be +ve, or -ve or sometimes zero.
After completion of execution of one program, the program’s binary code or data will not be cleaned
automatically from the memory by the O.S, it exists until the next program is loaded into the same memory;
when a new program is loaded into this same memory, the old program’s code & data gets overwritten
(replaced). But when just space is allocated for new program variables, in this space, the previous program’s
binary values found or collected to these variables, which are anyway garbage to the new program.
This garbage exists until any new values scanned or assigned to this variables. For example,
int X=100, Y; // here X contains 100, but Y contains garbage value.

Note: Some times, this garbage may belong to our current running program itself. When a function is
terminated, its variable’s space is freed and reallocated for another function’s variable. So in this way the
garbage values come into picture.
C-Family 18 Introduction to C

‘C’ comment line


Comment lines are simply a passage of meaningful text, to give a brief idea about author of program,
purpose of program, and other details. It is a good programming practice giving comments to increase the
readability of a program. Programmers always add comments at instructions wherever complexity is seen.
Thus, the logic of program can be understood by studying comments. We can write our comments anywhere
in the program by enclosing the comment text within a pair of /* … */ This is as
/* ……….. comment line 1 ……………
………… comment line 2 ……………
………… comment line 3 …………… */

for eg: /* this program is written by Srihari, dated on 16-9-2020


this takes two input values and finds sum of them */
This comment lines are ignored (skipped) while compiling a program, and hence they are not executed.
Comments are not a part of the program, they are for documentation purpose. This is ‘C’ comment line and
can be used as single line or multi-line in the program.

C++ comment line: C++ supports single line comment, the syntax is
// ……………………………..comment line…………………………………….
The C++ is a superset of C, hence, we can compile C programs on C++ compiler, hence, we can use C++
comment lines in C programs (of course I myself used this comments during explanation of things).
C-Family 19 Introduction to Programming

Introduction to programming
Functions
In general speaking, in our real life, several people are required to accomplish one task with each one of
them doing one’s specialized sub task. Similar to this, a programmer cannot develop the entire code of one
application; instead many programmers contribute the code in terms of sub programs called functions.
Function is a sub-program that performs a given sub task in a program. Here each function is designed and
written for specific purpose such as calculating power, square root, logarithms …etc; thus collection of such
functions makes a C-program. For example, sqrt() is a function, it gives square root value. eg: sqrt(16)4
The functions are classified into ① library functions, ② user–defined functions

1) Library functions
These are ready-made functions, designed and written by the C manufactures to provide solutions for basic
and routine tasks in the programming. For example, the mathematical functions pow() & sqrt(), and I/O
functions scanf() & printf (),etc. The vendor of C, supply these predefined functions in compiled form with C
software.
There is huge collection of such compiled functions available in C, hence, these collections are called
functions Library. The library functions-body placed in separate files with name “xxxx.lib” in compiled
format and they are automatically linked to our program at the time of compilation, and these are hidden to
the programmer. Following library functions show how they are called from another part of program.

1) Math library functions


The familiar math functions are pow(), sqrt(), sin(), cos(), tan(), log(), log10(),etc.
1) pow(x,y) is a function calculates xy, where x is base and y is exponent.
3
k=pow(2,3); // k=8; here 2 is calculated and assigned to ‘k’

2) sqrt(x) is a function calculates square root of x.


K=sqrt(16); // k=4;

3) log() is a function, finds the log2 value


The syntax of these functions are defined in ‘math.h’ file and any function is used in the program, it should
be included at the beginning of program as: #include<math.h>

eg2) Terminal I/O library functions


Generally, all programs are needed to interact with keyboard or monitor devices to accept and print values.
Input is taken from the keyboard and the output is displayed on the screen.
The printf() and scanf() are familiar I/O functions defined in ‘stdio.h’ file

printf(): displays message or output values on the screen, the programs are stored permanently in
secondary storage devices like hard disk and when they get executed, loaded from hard disk to RAM and
then instruction by instruction is executed by the processor. Here nothing is displayed on the screen while
executing a program in the memory, if something need to be shown on the screen, we must add an
instruction called “printf()”, which displays data/message on the screen. For example

inside program On the screen


printf(“hello”); hello

Syntax: printf(“format string”, list of values); here the “Format string” represents, what format we want to
display on the screen for the list of values; the format strings are
C-Family 20 Introduction to Programming

%d  for printing integer value . (In this context ‘%’ is not a modulus operator)
%05d  for printing integer in 5-digit format by padding with zeros.
%f  for printing float value
%.2f  for printing with fraction values like 123.45
%5.2f for printing float in 5.2 decimal formats
Let us have some examples, how printf() shows output on the screen
1. printf(“%d”,123);  123
2. printf(“%5d”,123);  BB123 // B means blank space
3. printf(“%05d”, 123);  00123
4. printf(“%02d”, 123);  123
5. printf(“%5.2f”, 323.4);  BB323.40
6. printf(“%.2f”, 1323.4256);  1323.42
7. printf(“%8s”, “Hai”);  HaiBBBBB // B means blank space
8. printf(“%-8s”, “Hai”);  BBBBBHai // right justification

9. let w=10, c=29.50;


printf(“weight = %d, cost = %f”, w, c);  weight = 10, cost = 20.50

10. let x=500;


printf(“ hello %d world”, x);  hello 500 world

11. printf(“hello world”);  hello world // notice that, the values are not specified.

12. prinf(“10+20=30”);  10+20=30 // here + , = doesn’t work like operator, they are just to print on screen

so the printf() showoff as it is whatever message defined inside quotes(““) except %d, %f, …

List of all format strings


The following list specifies valid format characters
%c  It denotes single character (signed/unsigned char)
%d or %i  It denotes signed decimal integer (signed int)
%f  single precision floating point number (float)
%u  unsigned decimal integer (unsigned int)
%ld  signed long decimal integer
%lu  unsigned long decimal integer
%If  double precision floating point number (double)
%Lf  high precision floating point number (long double)
%%  single % symbol
%x  unsigned hexadecimal integer
%o  unsigned octal integer
scanf(): used to read input values from the keyboard, here user has to feed/enter values in the keyboard
while running a program, based on input values, the output is displayed. The scanf() waits for user
response until he/she enters some values from the keyboard. ie, pauses the program execution until he
enters input values in the keyboard with the end of input “enter-key”. For example,
C-Family 21 Introduction to Programming

program keyboard

scanf(“%d%d”, &a, &b);


10 20 ⤶

syntax: scanf(“format string”, list of variable addresses);


eg. scanf(“%d %f”, &age, &salary);
Here ‘&’ is called address operator, it must be prefixed before every variable at scanf().
[We will see in pointer topic why this address operator is required in the scanf(), until then just follow it]

1. scanf(“%d%d”, &x, &y); // accepts two values from keyboard and assigns into x , y;
2. scanf(“%d,%d”, &x, &y); // the input values must be separated by coma(,)  10,20⤶
3. scanf(“%d-%d-%d”, &day,&month,&year); //the date input must be separated by hypen(-)  10-2-3002⤶

4. scanf(“%d/%d/%d”, &day,&month,&year); //the date input must be separated by slash(/)  10/2/3002⤶


5. scanf(“%d%d”, &x, &y); //the default is space between two values  10 12⤶

2) User-defined functions
The library functions do not satisfy all the requirements of programming-needs instead they assist basic and
common programming tasks. So, one has to write one’s own functions to satisfy the needs of programming.

Thus, user defined functions are our-functions, created by ourselves to meet our requirements in the
programming. Besides our functions can be added to library files and we can use them like a library function
in our programs.

The following example explains how the function’s body are designed and written. This function body finds
big of two numbers. (Here just to create an idea about functions I have given this example. Don’t try to
understand in depth about these functions. This explained clearly in function’s chapter)
This function takes two integer values to x, y and returns biggest of it; if this function is called with
“K=big(23,4)” from another function say main() then returns 23 and assigned to k; this is as given figure
void main() int big( int x, int y)
{ int k; { int temp;
K=big(4,23); if( x>y) temp=x;
printf(“%d”,k); else temp=y;
} return(temp);
}

Adding library function’s signature (proto-type/declaration)


Compiling and generating machine code has 2 stages(compiling+linking), compiler generates machine code
of each function separately in object code format(semi executable code), later linker links all such semi
executable functions into single executable file(machine code format).
If any library function is used in the program, then how the compiler finds whether it is used (called)
properly or not? Because they were already in compiled form and linked directly at linking time. So the
compiler does not show if any errors exist; if we do so, then the linker may show linker-error or sometimes it
may leads to run-time error. For example, by mistake if pow() function is called with ‘k=pow(3,4,5) to find
34 then the linker may show error, because the actual function takes only two values like K=pow(3,4);
C-Family 22 Introduction to Programming

To solve this problem, the original proto-type of function should be added to our program to check out
syntax errors and to raise them; the functions original proto-type is provided by C-manufacturers in separate
files with name “xxxx.h”. So if any library function is used in the program, then related header file should be
included. So that, it compares our function-call statements with the original proto-type and if both are not
matched then compiler raises an error. (The word proto-type is also called function declaration/signature.)
Syntax to include file is  #incldue<file name .h>
#inclue<math.h> // to check syntax errors at math functions calls
#include<stdio.h> // for all I/O function signatures
#include<graphics.h> // for graphics functions
#incldue<string.h> // for string functions
At beginning, these files name were stdio, math, string.. etc, the extension “.h” was not given then, but
overtime, when they appears as program header, gradually start calling them as header files, so added “.h”

About main() function


The main() works like a start & end point of the program, the execution starts at “void main()” and ends at
last closing braces; Actually, the main() is also a function; among all the functions, main() is an important
and reserved function, it tells to the compiler the starting & ending point of program. The main() can be
written in any of the following ways, and all of them have the same meaning & works in similar way;
(of course different vendors of C, suggested in different ways to this)

void main () int main () main()


{ -------- { -------- { ----
-------- -------- -----
-------- return(0); -----
} } }

Now, in C program, at least one function must be there, that is main(); its execution starts by operating
system when user runs the program. The other functions are executed by shifting the control temporarily
from main(); the following figure explain how the other functions are called from main() and how they are
executed by the control jumping to it.
This example explains how the control jumps over to functions for calculating 23 and √28
void main() pow(int x, int y)
{ int k; {
// body of pow()
k=pow(2,3);
-----
printf(“%d”,k); }

k=sqrt(28);
printf(“%d”,k); sqrt(int x)
{
}
// body of sqrt()
}

“K=pow(2,3)” is known as function-call instruction, when it gets executed, the control transfers to its body,
calculates xy value, later returns ‘8’ and assigned to k; similarly sqrt() is also executed;

Thus, each function is a sub program, stored separately in the memory and executed whenever it is called,
Here main () is treated as boss function and other functions are sub ordinates to main(). The main function is
called by the operating system, that is indirectly by the user [ by pressing command control+f9 in turbo C++
editor or typing .exe file name at DOS prompt, or double click on icon of .exe file in windows];
C-Family 23 Introduction to Programming

First C Program

Line 1: // A sample program to print welcome messages on the screen, written by Srihari
Line 2: #include <stdio.h>
Line 3: void main()
Line 4: {
Line 5: int a, b, c;
Line 6: a=100;
Line 7: b=200;
Line 8: c=a+b;
Line 9: printf(“output = %d”, c);
Line 10: }}
line1: generally, at first line of program, the comments are added about purpose & author of program. It is
good programming practice to add such comments (we know, these lines ignored by compiler).
line2: #include it includes library function’s header files and other code files to our program, here the
printf() syntax provided in stdio.h, hence, it included here.
line 3: void main()  is the starting point of the program.
line 4: the open and close braces { } define a block. As per syntax, the executable instruction must be given
inside braces. (As C is block structured programming language)
line5: int a, b, c; here space is created to each variable with 2-bytes. (at this moment, it contains garbage)
Line6: a=100;  here 100 filled to ‘a’
Line7: b=200;  here 200 filled to ‘b’
Line8: c=a+b;  here 300 filled to ‘c’
Line8: printf(“output = %d”,c)  when this statement executes, we can see “output = 30” on the screen
Line9: ‘}’  closing braces tells the end of program execution.

Second C Program
#include<stdio.h>
void main()
{ printf(“\n welcome to C-Language programming”);
printf(“\n welcome to Vijayawada”); // ‘\n’ means print in next-line
printf(“\n welcome to C-Family Computers”);
}
we know, instructions are executed one by one from top-to-bottom in a program, so here output shown as:
welcome to C-Language programming
welcome to Vijayawada
welcome to C-Family Computers

General Structure of C program


The C program looks like following way

Line1 // Comment line about program


Line2 file inclusion statements
Line3 void main()
{
Line4 variable declaration
Line 5 input statements
Line 6 process statements
Line 7 output statements
}
C-Family 24 Introduction to Programming

line1: we already discussed above, now I am repeating same with more clarity.
In this line, the comments are added about program, ie, the purpose of program, input/output of
program, who & when has written, etc, are specified. Writing comments is a good programming
practice. However, this is optional.
line2: Here header files of library functions and other files are included. For example “#include<math.h> for
math functions, #include<stdio.h> for I/O functions ….etc;
line3: “void main ()” represents starting point of program, the execution starts at this point.
line4: variables are declared at the beginning of program block, and when this line is executed, space
is allocated for variables in the RAM.
line5: the input statements are used to accept values from the keyboard and other terminals.
line6: Here process statements specify the processing of input data
line7: here the output statements are used to show output on the screen or other terminals;
Note: the opening and subsequent closing braces {} defines a block; as per C syntax rules, the instruction
must be given inside block; all instructions must be terminated by “;”

Coding style of C program


Unlike some other programming languages (COBOL, FORTRAN, etc), C grants a freedom to every programmer to
follow his own style of coding. However, ensure that, the program should be readable and easy to debug by
others. For example, see the following instructions
a=10;
b=20;
c=a+b;
k=100;
the above sequence of instructions can be written in single line as: a=10; b=20; c=a+b; k=100;
to increase readability, we can give more spaces or empty lines between expressions, that is, we can add
spaces before and after of every token such as punctuation symbols, operators, variables and other places.
For example:
1. a+b  can be written as: a + b // spaces added before & after ‘+’ symbol
2. a+b<d*e  can be written as: a + b < d * e // observe space added here
3. printf(“hello”);  can be written as: printf ( “hello” ) ;

Developing, compiling, running, and debugging a program


A) Developing: Once a program has been designed and written, it must be entered before executing on
the system. If one wants to feed the program into computer, he needs a software tool to type the
instructions, and also allow modifying, deleting, copying, and other editing facilities. This is provided by the
special software called Editor. We have several editors to feed (type) the program into computer. The
editors like notepad, word pad, ms-word … etc, but today, every language supplier providing a special Editor
along with compiling, debugging, running facilities. All these features are available in one editor therefore it
is called “integrated development environment (IDE)”. Generally, the C++ editor is used instead of C,
because C++ is a superset of C. the C++ editor is more convenient than C since as it is a newer version.

note: we can use notepad editor to type the program code, but it does not provide to compile/run the
programs. It is just editor to type and save the code. So IDE is the ultimate tool for programming.
The following figure shows the turbo C++ IDE editor on DOS.
C-Family 25 Introduction to Programming

File menu: this menu-driven facility used to handle file operations such as opening a new file, or opening an
existing file, saving a file, etc.
Edit menu: this is used to copy, cut, and paste a group of selected lines.
Compile menu: to create object files, making executable files, linking a program….

B) Compiling & Running: Irrespective of number of languages in the market, the computer
processor understands only one language called machine language, this language designed with basic set of
operations like addition, subtraction, multiplication, comparison, etc. These operations are designed in
circuitry level in the form of 1’ and 0’s to execute directly by the processor, therefore this language is also
called low level or binary language.

The compiler is translation software, which translates high level program into machine code; the compiler
generates machine code of each line and stores into another file called “exe” (executable) file; this file can
be executed directly on the machine; once the exe file is generated then compiler and source file are not
required. These are required when modification are needed in the source code;

Thus, every high level language program must be translated to machine code; for this reason, every
language must have its own compiler to translate it into machine code; for example, the C compiler for C
programs, C++ compiler for C++ programs. if two same programs are written, one in C, and another in C++
then two compilers generates equivalent machine code;

compilation process has two stages called  compiling + linking


In compilation stage, it checks the typing and syntax errors, after rectifying them, it creates object file, which
is semi executable file. Here each function compiled independently and code is generated separately as they
are in source file. Later linker links all library and user-defined functions together to form a single executable
file. For example, main() function with printf() as shown in the above examples. The following figure shows
how they are compiled and linked to the program.
C-Family 26 Introduction to Programming

C program file.
let file name is “sample.c”

Compiler software

Produce semi executable file


Object file “sample.obj”

Library functions
Linker Software
are attached here

Executable file
“sample.exe”

Procedure to execute C-program in turbo C++ IDE on DOS environment

Open the Editor (tc)

Open a new file (alt+fnew)

Type the C program

Save the program into disk (f2)

Compile the program (f9)

Run the program (ctrl+f9)

Type the input values

Watch the output values (alt+f5)


To close lab(alt+x)
(al(Alt+x)
Close the program (alt+f3) To do one more program

D) Compiler vs Interpreter
Interpreter is a translator, which translates our ‘C’ program into machine code, here it translates one line
at a time and then executes immediately on the machine. That is, it translates line by line and then executes
instantly on the machine. So it also called instant compiler. Whenever we run the program, the interpreter
translate and executes, if we run more times, more translations it takes. It seems to be unnecessary
translating same program again & again in every use. This redundant translation leads to wastage of CPU
time and other resources.

Actually, interpreter is used for single-use applications like queries, commands, to check spellings in word
processing, language translators, internet browsing, etc. The web-sites are coded in the form of html, css,
etc and these files are downloaded and interpreted by the browsers, web browsers are nothing but
interpreters. So for single use applications interpreter is the choice.
C-Family 27 Introduction to Programming

Compiler translates line by line and stores into “.exe” file to execute later time, thus instead of executing
each line instantly on the processor, it stores into .exe file. Now this file contains all machine code
instructions of our C-program’s source file. This file can be executed directly on the machine whenever we
want, while running this .exe file, the compiler is not required. So here, no translation takes place again &
again in every use. The interpreter doesn’t create “.exe” file, so in every use translation is required.
Some kind of applications needed to execute regularly like calculator, business accounting, games, etc.
Here compiler is used to generate machine code file, so that, such file can be executed at any time without
translating again and again.
Conclusion: compiler is the choice for regular use applications, whereas interpreter is the choice for single
use application. For single use applications, it is un-necessary creating machine code file.

C program file Interpreter Processor


say ‘Sample.c’ (translates one line at a time and executes given instruction
sends to processor to exeucute) one at a time

C program file Compiler : translates line by line File: ‘Sample.exe’


say ‘Sample.c’ sends to exe file all machine code instructions
are collected here

Escape sequence characters


The symbol back slash (\) is called escape character, used to represent some special keys or symbols like
New Line, Carriage Return, Tab Spaces, etc. Escape sequence characters are
1. \n  new line (new line)
2. \t  horizontal tab space (4 gaps)
3. \\  single back slash (\), inserts slash in output.
4. \”  double quotes character (differently with the string enclosure).
5. \’  single quote character (differently with the character enclosure).
Let us see the following examples.
1. printf(“Hello\nHari”);  shows “Hello” in one line and “Hari” in next line
2. printf(“Hello\tHai”);  Hello Hai (4-gaps)
3. printf(“\”hello\””);  “hello”
4. printf(“\\ hello\\”)  \hello\

Finding sum and product of given two input values


This program scans two values from keyboard and prints the sum and product of two values.
ip: 10 20
op: sum is 30, product is 200
void main()
{ int a, b, sum, product;
printf(“Enter two values:”);
scanf(“%d%d”, &a, &b);
sum=a+b;
product=a*b;
printf(“sum is %d , product is %d”, sum , product);
}
C-Family 28 Introduction to Programming

Finding Fahrenheit from given Celsius. (formula is: F=9/5*C+32)


This program scans Celsius from keyboard and prints Fahrenheit as output.
ip: enter Celsius: 10
op: Fahrenheit is: 50
void main()
{ int C,F;
printf(“\n Enter Celsius:”);
scanf(“%d”, &C);
F=9/5*C+32;
printf(“Fahrenheit is: %d”, F);
}

Finding area and circumference of circle


The following program accepts radius from keyboard and prints area and circumference.
Logic: based on input value radius, the output (area and circumference) is calculated;

Process Program
input: radius(r) void main()
output: area ( ) { float radius, area, circum;
circumference (2 printf(“\n Enter radius of circle :”);
scanf(“%f”, &radius);
Input & output area=22/7.0 * radius * radius;
ip: Enter radius of a circle: 5 circum= 2*22/7.0*radius;
op: Area = 78.57143 printf(“the Area is %f\n”, area);
Circumference = 31.40 printf(“\nthe Circumference is %f”, circum);
}

Demo program for swapping two variable values


The following program explains how 2 variable values are exchanged one with the other. This is common
task in the programming and also known as swapping of data.
Logic: Let the input values are 23 & 45 and assigned to X,Y. See what happens, if one has written as
X=Y;
Y=X;
When ‘X=Y’ executes, the value of Y(45) is assigned to X and we lost the current value 23 of X. Now the X & Y
contains same value 45. When the second instruction Y=X executes, the same value 45 copied back to Y.
Now both the variables hold same value and our purpose can’t be survived. Therefore, to exchange two
values a third variable is required. This is explained in the following program.

void main() Output


{ int x, y, temp; ip: enter 2 values: 23, 45
printf(“enter 2 values :”); op: before swapping, the x , y are 23, 45
scanf(“%d%d”, &x, &y); after swapping, the x , y are 45, 23
printf(“\n before swapping the x, y are %d,%d”, x, y);
temp=x; // saving ‘x’ value in temporary variable.
x=y; // copying ‘y’ value to ‘x’
y=temp; // copying ‘x’ value to ‘y’
printf(“\n after swapping the x, y are %d %d”, x, y);
}
C-Family 29 Introduction to Programming

Accepting basic salary of employee and calculating net salary


This program scans basic salary from keyboard and prints net-salary. The net is sum of BASIC+HRA+TA
Process: HRA is 24% on basic ( HRA  House Rent Allowance)
TA is 7% on basic ( TA  Travelling Allowance)
net salary = basic + hra + ta;

void main()
{ float basic, hra, da, ta, netSalary;
printf(“enter basic salary :”);
scanf(“%f”, &basic);
hra=24*basic/100; // calculating 24% for house rent allowance
ta=7*basic/100; // calculating 7% for travelling allowance
netSalary=basic+ta+hra;
printf(“Net salary = %f”, netSalary);
}

Prints sum of arithmetic, relational, and logical operations of two values

void main() output


{ int a,b;
printf(“enter 2 values :”); ip: 11 4
scanf(“%d%d”, &a, &b); op: a+b=15
printf(“\n a+b=%d”, a+b); a-b=9
printf(“\n a-b=%d”, a-b); a%b=3 (remainder)
printf(“\n a%%b=%d”, a%b); a>b=1 (true)
printf(“\n a>b=%d”, a>b); a<b=0 (false)
printf(“\n a<b=%d”, a<b);
}
Note: In condition place, the value non-zero is taken as true, whereas, zero is taken as false

Finding reverse of 2-digit number


This program accepts a two-digit number like 47 and prints the reverse of it (74).
Logic: For example, the value 735 composed as  7*100 + 3*10+ 5*1.
Similarly, the reverse of it is  5*100+3*10+7*1
In this way, we can find the reverse of two digit number
void main()
10 ) 47 ( 4  n/10
{ int n, reverse;
40
printf(“\n enter two digit single number :”); ----------
scanf(“%d”, &n); 7  n%10
reverse=n%10*10+n/10;
printf(“\n reverse = %d”, reverse);
}
Let us substitute the value 47 in the expression “reverse = n%10*10+n/10”
reverse = n%10*10 + n/10;
= 47%10*10 + 47/10
= 7*10+4;
= 74
C-Family 30 Introduction to Programming

Printing size of different data types


The following program shows memory occupied by each data type in C.
The sizeof() is an operator, it gives the size of variable or data-type.
main() Output
{ long int k;
printf(“\n size of int is %d byte”, sizeof(int) ); size of int is 2 byte
printf(“\n size of long int is %d byte”, sizeof(long int) ); size of long int is 4 byte
printf(“\n size of float is %d\n byte”, sizeof(float) ); size of float is 4 byte
printf(“\n size of double is %d byte”, sizeof(double) ); size of double is 8 byte
printf(“\n size of k is %d bytes”, sizeof(k)); size of k is 4 bytes
printf(“\n size of 10 is %d bytes”, sizeof(10)); size of 10 is 2 bytes (10 is int-type)
printf(“\n size of 10.15 is %d bytes”, sizeof(10.15)); size of 10.15 is 4 bytes(10.15 is float-type)
}

Converting time(H:M:S) into seconds format


This program accepts a time in H:M:S format as input and prints output in seconds format.
ip: 2 40 50 (2-hr , 40-min , 50-sec) ip: 0 2 50 (0-hr , 2-min, 50-sec)
op: 9650 seconds op: 170 seconds
logic: total seconds is N=H*3600 + M*60 + S // each hour has 3600 seconds, each minutes has 60 seconds.
void main()
{ int H,M,S,N;
printf(“Enter time as hours minutes seconds format:”);
scanf(“%d%d%d”, &H, &M, &S);
N=H*3600+M*60+S;
printf(“output time in seconds is: %d“, N);
}

Converting seconds time into H:M:S format


Code to accept a time(N) in seconds format and prints output in H:M:S format
ip: 7270
op: 02:01:10 ( 2-hours, 1-minutes, 10-seconds )
logic: divide N with 3600 and take the quotient as hours, (1hour=3600seconds)
divide N with 3600 and take the remainder(R=N%3600). This R is the remaining seconds left after
taking hours from N. Again divide R with 60 and collect quotient and remainder.
The quotient would be minutes and remainder would be seconds.
void main()
{ int H,M,S,N,R;
printf(“Enter time in seconds format:”);
scanf(“%d”, &N);
H=N/3600;
R=N%3600;
M=R/60;
S=R%60;
printf(“output time is %d : %d : %d“, H, M, S);
}
C-Family 31 Type Casting

Type casting
Process of converting a value from one type to another type is called type casting. In C, the type casting is
done in two ways. ①Implicit type casting (automatic casting) ②Explicit type casting (manual casting)

①Implicit Typecasting
For example, the expression 10+20.54(int+float), here the operand 10 automatically converts into float-type
as 10.00, because, we must hand over same size and type of data to the CPU before computing. So compiler
automatically is done this conversion. So implicit type casting automatically is done by the complier when
two operands are not same type with in the expression. Let us see some examples,

eg1: void main()


{ int x=5;
float y=12.33, z;
z=x*y; // here ‘x‘ behaves like a float-type at this expression
printf(“ z value = %f”, z); // z value = 61.65
}

eg2: void main()


{ float k;
int a=10, b=3;
k=a/b+5;
printf(“\n Result of K = %.2f”,k); // Result of K=8.00
}
Here, the expression a/b gives the int type result(3 not 3.33) as both a&b are integer operands.
Later, this result is added to 5, which is again int type; finally this result gets converted implicitly to float and
assigned to k. Therefore the output  ‘Result of K=8.00’
eg3: int x=10; float y;
y=x; // Here ‘x’ value 10 is promoted to float-type, so 10.00 stored into ‘y’

eg4: int x; float y=29.34;


x=y; //Here the integer part of ‘y’ value 29 is assigned to ‘x’

eg5: long int x=9023455L;


int y;
y=x; //here, as ‘x’ is int-type, the right most 2 bytes of ‘y’ is stored into ‘x’ and results loss of some bits.
Let us see some expressions and its automatic type casting
Expression  After conversion  Result
int/int no conversion int
float/int float/float float
int * int no conversion int
int * long int long int * long int long int
int * float float * float float
float * double double * double double
C-Family 32 Type Casting

②Explicit typecasting
Sometimes, we need to convert explicitly to get desired result from the expression.
syntax: (conversion-type) expression
eg: (float) 15  15.00
(int) 2.6  2
In the above expression, 15 is int. But, upon prefixing (float)15, its type will be changed to float (as 15.00).
eg: void main()
{ int a=10, b=3;
float k;
k=a/b;
printf(“\n Before type casting K=%f”,k);
k=(float) a/b; // here ‘a’ converted by me, ‘b’ is converted by compiler.
printf(“\n After type casting K= %f”,k);
}
Before type casting K=3.000000
after type casting K= 3.333333

eg: void main()


{ int a=30, b=20000;
long int k;
k = 10 + a*b;
printf(“\n Before type casting K=%ld”,k);
k = 10 + (long int) a*b;
printf(“\n After type casting k=%ld”,k);
}
Before type casting K=10186 (un-expected value)
after type casting K= 600010
K=10 + a*b  here first, the result of ‘a*b’ is calculated and stored into temporarily variable (say it is T),
later 10 is added to T. Finally T value is assigned to K. The nameless variable T is automatically created by
compiler and it is of type int; because a & b are int types, so T will be the int type.
But the result of a*b is bigger than the integer range and it cannot hold by T, so some bits are truncated
while storing into T.
K=10+(long int) a*b  here ‘a’ is long int, which we converted , and ‘b’ is converted by the compiler.
so T will be the long int and it can hold the result of a*b;

Representation of Constants in C
In programming, Data is represented in two ways in terms of constants and variable data. Constants are
represented in special manner by adding format string or other symbols to the value. For example, ‘10L’ is
long int type.
Automatically, compiler understands some types of constants in the program. For example, the constant ‘10’
is considered as int-type, 34.55 as double-type, ‘A’ as char-type. These are default types and automatically
understand by the compiler. But some constant types are needed to specify explicitly along with format
string. The following list explains about all constant types. Do not use other symbols like comma, spaces,
quote, etc while specifying constants.
C-Family 33 Type Casting

integer Constants
A collection of one or more digits with or without a sign referred to as singed int constants. This is the
default type for integral values.
eg. 5, 256, 9113, 6284, +25, -62, etc are valid signed integers.
Similarly to represent unsigned int, the format string ‘u’ or ‘U’ is suffixed to the value.
eg. 67U, 43U, 4399u, 45u are valid unsigned integers.
Note that, -3428u is also a valid number. Here this -3428 is converted into equivalent unsigned integer
62108. Because, here the sign bit is also considered as data bit. (But this style is not recommended)
Some invalid declaration of integer constants are:
15,467 $25,566 4546Rs
long integer constants
for the long integer constants, the format string ‘l’ or ‘L’ is suffixed to the value.
eg: 2486384L –123456L 5434545l –34545l are valid long int constants
893434lu -3Lu … etc are valid unsigned long integers.
Octal int/long integer constants
for the octal integers, zero is prefixed before the value. (0 is like octal).
eg: 0123, 0574, 01, 046342L etc are valid octal integers.
0181, 09, 12, etc are in-valid octal integers. (In octal system 0-7 digits are used)
Hexadecimal int/long integer constants
in the hexadecimal number system, the symbols 0, 1, 2, 3 … 9, A, B, C, D, E, F are used.
(Total 16 symbols are used; because, the number system’s base is 16)
The symbol “0x or 0X” is prefixed before the hexadecimal number.
For example: 0x1, 0x123, 0xa5, 0xfldb, 0x0, 0xABC, 0xflc etc are valid hexadecimals.
character constants
To specify a character constant, we must enclose the character within the pair of single quotes.
eg. ‘A’ ‘z’ ‘s’ ‘8’ ‘+’ ‘;’ etc
string constants
It is a collection of characters enclosed within double quotes, used to represent names, codes, abels, etc.
eg: “Hello! Good morning!” “Magic mania” “A” “123” “A1” “#40-5-8A” “C-Family”
float constants (Real numbers)
We can specify the real numbers in two different notations, namely general and scientific notation.
Here the format string ‘f’ is attached at the end of value.
In normal representation: 3.1412f -25.62f 98.12f -045632.0f 1.f 9.13f
In scientific exponential representation: the syntax is [-]d.dddde[+/-]ddd where d is any digit.
2.32e5f (means 2.32 x 10^5 i.e. 232000.0)
12.102e-3f (means 12.102 x 10^-3 i.e., 0.012102)
-2. 165e6f (means -2.165 x 10^6 i.e., -2165000.0)
3.68e3f (means 3.68 x 10^3 i.e., 3680.0)
double constants: This is the default type for real numbers (floating point values).
eg: 1.2 45.3 4.39393 349.34899034
45.4e15 44.54e4 (‘l’ or ‘L’ is option for double)
long double: for the long double, the format string ‘l’ or ‘L’ is used.
eg: 3.14L
314.41 (Equivalent to 314. 0L)
3.68e3L (Means 3.68 x 103 i.e., 3680.0L)
C-Family 34 flow charts

Flow chart
It is a pictorial representation of flow of a program, which illustrates the sequence of operations to be
performed to get the solution of a problem. It is often used as a visual planning tool, how the control to be
moved from one point to another point to get a solution. It is like drawing a building plan before
constructing a building.

Flowcharts are generally drawn in the early stages of formulating computer solutions. It facilitates
communication between programmers and business people. It plays a vital role to understand the logic of
complicated and lengthy problems. Once the flowchart is drawn, it becomes easy to write the program in
any high level language. The following mathematical symbols are used to represent specifications with
directions to indicate the flow of control.

Start/stop a program

Rectangle for processing general instructions

Circle for connection

Arrows for directions

Rhombus for decision making

Parallelogram for Input/output from terminal

Cylinder for secondary Memory (external storage)

RAM (internal storage)

Predefined actions

File

Looping
C-Family 35 flow charts

Algorithm
In mathematics and computer science, an algorithm is a finite set of computational instructions that carry
out a particular task, which takes input and produces desired output. In simple words, it is step-by-step oral
explanation of logic how to construct instructions in a program; here English & math symbols are used to
explain logic in words

Flowchart depicts how the control to be moved in the program from one point to another point to get a
solution, whereas algorithm tells step-by-step explanation how to construct instructions in a program.

This is an independent method to explain the logic regardless of programming language used by the
programmer. Here English and math symbols are used to explain the logic. People write algorithm for
complex and complicated tasks to explain the logic in words, for example, sorting algorithms, searching
algorithms, shortest path in network …etc. Any algorithm follows,
1. Describes the input and output
2. Describes the data entities with purpose (variables)
3. Explains process in step by step using English and math symbols
4. Add comments at every step what it does, use square brackets [ ] for comments
5. Each instruction is clear and unambiguous (definiteness)
6. The algorithm terminates after finite number of steps

Note: there are no standard rules and regulation to implement algorithm/flowchart, so one can implement
one’s convenience but ensure that other must be understood it.

The flowchart and algorithm to find big of two numbers

Flow chart to find big of two numbers Algorithm to find big of two numbers
Start
step1: let us take a,b as type integer variables
step2: let us take ‘big’ to store big value
read(a,b) step3: [ scanning input from keyboard ]
read(a,b)
step4: [ finding big of 2 numbers ]
if a>b if(a>b) big=a
else big=b;
true false
step5: [ printing output ]
big=a big=b
print(big)
step6: [ closing the program]
stop
Print(big)

stop
C-Family 36 flow charts

Flowchart for finding big of three numbers

Start

read(a,b,c)

true false
if(a>c) if(a>b) if(b>c)

true false true false


print(a) print((c) print((b) print((c)

stop

Flowchart to Find sum of 1 to n numbers(1+2+3+4…+n)

start

print(“enter n:”);
read(n)

sum=0;
i=1;

false
if(i<=n)

true

sum=sum+’i’;
i++;

print(sum)

stop
C-Family 37 flow charts

Pseudo code
Pseudo code is a short hand way of describing a program or algorithm in general language syntax rather
than in specific language syntax. Algorithm uses English and math symbols to explain logic in stepwise,
whereas pseudo code uses programming language syntax to explain logic in term of instructions. So pseudo
code resembles the program with general language syntax. Most of the people adopt C or Pascal language’s
syntax and their control structures to describe the pseudo code.

Algorithm is understandable by any nonprogrammer but pseudo code understandable by a person who
knows at least one programming language. So it is a method used to explain the logic between two
programmers. It is easier for programmers to understand the general workings of one program which is
written by other programmer.

Flow chart shows only execution flow (directions), algorithm explains, what are the steps be taken to get a
solution, but it does not give clear explanation of how to write instructions, for example, to swap 2 values in
the algorithm, we write as: swap(a,b). In pseudo code we write as: t=a, a=b, b=t. So in pseudo code every
step is written in detailed, which is near to programming. So, one can say loosely, pseudo code is nothing
but a program without accurate syntax (syntax is ignored).
[FlowchartAlgorithm Pseudo codeProgram]
Example for Pseudo code: Calculating sum of 1 to n numbers (1+2+3+4…+n)

Algorithm ( finding sum of 1 to n ) Pseudo code ( finding sum of 1 to n )


1. [ variable declaration] 1. Start
n, i, sum : integers 2. int sum,i;
2. [ scanning input] 3. read(n);
read(n); 4. set i=1, sum=0;
3. [ initializing variables] 5. while(i<=n)
i=1; sum=0; { sum=sum+i;
4. * adding values 1,2,3,… n to sum+ i=i+1;
Repeat until<=n }
sum=sum+i; 6. print(sum);
i++; 7. stop;
5. [ printing ouput]
print(sum);
6. [ exiting the program ]
stop;
C-Family 38 flow charts
C-Family 39 if-else

Control Statements
Generally, instructions in a program are executed sequentially one after the other, in an order in which they
appear in the program. However, in practice, we need to bypass the control over some set of instructions, or
repeatedly process some instructions or to alter some other sequence depending upon the requirement.
For this purpose, special statements are necessary in programming to handle the control accordingly.
C possesses such a handy control statements like if, if-else, switch, while, etc. These statements alter the
normal execution sequence of a program according to our requirement. Therefore these statements are
called as control statements. These control-handling statements are of two types.
① Conditional control statements ② Unconditional control statements

Control statements

Conditional Un-conditional

Decision Looping

1) if 1) while 1) goto
2) if-else 2) for 2) break
3) conditional operator 3) do-while 3) continue
4) switch case selection 4) return

Decision control statements: These statements change the flow of execution depending on given logical
condition. Used to execute or skip some set of instructions based on given condition.
Loop statements: These are also called iterative statements, used to execute some set of instructions re-
peatedly until a given condition is failed.
Unconditional control statements: These statements unconditionally transfer the control from one location
to another specified location within a program.

if – statement
It is a decision control statement, executes or skips a given set of instructions depending upon the given test
condition. The syntax is
if(test-condition) false
test condition
{ instruction 1;
true
instruction 2;
Instruction 1;
------- Instruction 2
instruction N; …
Instruction n
}
instruction N+1; // after “if” statement
Instruction N+1
instruction N+2; Instruction N+2
------
------
C-Family 40 if-else

In the above if-statement, if the test-condition is success (true) then instruction-1, instruction-2, … instruc-
tion-N will be executed, later, the control comes out of if-body and proceeds with instruction N+1, instruc-
tion N+2 …etc. This is shown in the flow chart.
If the result of test-condition is false then control jumps out of if-body and proceeds with instruction N+1,
instruction N+2 …etc. In this case, the instruction-1 to instruction-N will not be executed.

Demo1 program, explains how an if-statement executes


#include<stdio.h>
void main()
{
if( 10 > 5 )
{ printf(“hello ”);
}

if( 10 < 5 )
{ printf(“hai ”)
}
printf(“bye”);
}
op: hello bye
In the above, the first condition (10>5) is true, so printf(“hello”) will be executed, but the second condition
(10<5) is false, so printf(“hai”) will not be executed. The final printf(“bye”) executes irrespective of
if-statements.

Demo2 program, explains how an if-statement executes


void main()
{ if( 1 < 2 )
{ printf(“ Red ”);
}
printf(“ A ”);
if( 1 > 2 )
{ printf(“ Blue ”);
}
printf(“ B ”);
if( 1 == 1 )
{ printf(“ Green ”);
}
printf(“ C ”);
if( 1 != 1 )
{ printf(“ Yeloow ”);
}
printf(“ D ”);
}
op: Red A B Green C D
C-Family 41 if-else

Finding absolute value of a given number ‘n’ modulus of |n|

This program accepts +ve or –ve integer from keyboard and displays result in +ve.
If user entered –ve value, converts it into +ve by multiplying it with -1.
start
ip: -14 ip: 15
op: 14 op: 15
read(n)
void main()
{ int n;
false
printf(“Enter a +ve/-ve value ”); if n>0
scanf(“%d”,&n); true
true
if(n<0) // if n<0 means, it is -ve
n=n*-1
{ n=n*-1; // if –ve, then converting to +VE
}
printf(“\n Result = %d”, n); print(n)
}
In this program, the instruction n=n*-1 executes when the input is -ve. stop

About Pair of Braces{ }


The pair of braces is optional when if-body or any control statement body contains only single instruction.
That is, the pair of braces is not required when if-body or else-body contained only single instruction.
The following code shows how to removes braces when single instruction exist in if-body.
// code after removing braces
if( A>B )
{ printf(“Red”); if( A>B )
} printf(“Red”);
printf(“Blue”); printf(“Blue”);
printf(“Green”); printf(“Green”);
------- -------

As per C-Syntax, the above two constructions are same, so it is better to avoid braces when we have single
instruction in if-body, but this single instruction must be followed indentation otherwise leads to confusion.
Indentation means writing instruction inside with tab-space, following code shows indentation

if( A>B ) if( A>B )


printf(“Red”);  with indentation printf(“Red”);  without indentation ( makes confusion)
printf(“Blue”); printf(“Blue”);
printf(“Green”); printf(“Green”);
------ -------
C-Family 42 if-else

if-body with and without braces


if(A>0) // without braces
{ printf(“ A is +VE”); if(A>0)
} printf(“ A is +VE”);
if(A<0) if(A<0)
{ printf(“ A is -VE”); printf(“ A is -VE”);
} if(A==0)
if(A==0) { printf(“ A is Zero”);
{ printf(“ A is Zero”); printf(“ A is +VE”);
printf(“ A is +VE”); }
}
Above two segment codes seems to be almost same, but in case of nested-if statements,
the 2nd construction without braces makes more clarity( we will see later).

Displaying biggest of two numbers


The following demo program accepts two integers from keyboard and prints the biggest value
void main() Same code without braces { }
{ int a, b, x; void main()
printf(“Enter two integers:”); { int a, b, x;
scanf(“%d %d”, &a, &b); printf(“Enter two integers:”);
if( a>b) scanf(“%d %d”, &a, &b);
{ x=a; if( a>b )
} x=a;
if( a<=b ) if( a<=b )
{ x=b; x=b;
} printf(“biggest is %d”, x);
printf(“biggest is %d”, x); }
}
Here, if a>b is true then ‘a’ is said to be big, then ‘a’ is assigned to ‘x’, or else ‘b’ is assigned at 2 nd if.

Calculating tax on salary of employee


This code accepts salary from keyboard and finds the tax, tax is 5% on salary but minimum tax is rs:200/-
Logic: first calculate tax as 5% on salary, if calculated tax is <200 then replace tax=200 as minimum
ip: salary: 20000 ip: salary: 1000
op: tax=1000/- op: tax=200/-
void main()
{ int salary, tax;
printf(“Enter salary :”);
scanf(“%f”, &salary);
tax=salary*5/100; // calculating 5% tax on salary
if( tax<200 ) // if tax is < 200 then replacing 200 as minimum
tax=200;
printf(“ tax amount is %f”, tax);
}
C-Family 43 if-else

if-else statement
This is two-way decision control statement, executes either if-block or else-block based on given condition.
If the condition is true then if-block executes, otherwise else-block executes. Let us see the syntax,
if (test-condition )
{
instruction 1; false
Test
instruction 2; // if-block
condition
true

----
instruction K; true
} Instruction 1; Instruction k+1;
else Instruction 2; Instruction k+2;
… …
{ Instruction k; Instruction n;
instructionK+1;
instructionK+2; // else-block
----
instruction N;
}
instruction N+1:
instruction N+2:
----
In the above if-else statement, always only one block will be executed, either if-block or else-block.
The test-condition is true, if-block is executed, and otherwise, the else-block is executed.
If the test-condition is true, the instruction-1, instruction-2, … instruction-k will be executed, later control
jumps out of ‘if’ construct and proceeds with instruction N+1, instruction N+2 …

If the condition is false, the else-block is executed i.e., instruction K+1, instruction K+2, … instruction N are
executed and then control proceeds with instruction N+1, instruction N+2 … statements.

Demo program for how an if-else executes

void main() After simplifying the program by removing braces


{ if (1<2) void main()
{ printf(“sky is blue”); { if (1<2)
} printf(“sky is blue”);
else else
{ printf(“sea is blue”); printf(“sea is blue”);
}
if (1>2)
if (1>2) printf(“C is simple”);
{ printf(“C is simple”); else
} printf(“C++ is also simple”);
else }
{ printf(“C++ is also simple”);
} If-body and else-body contained only single instruction,
} therefore braces are not required
op: sky is blue C++ is also simple
C-Family 44 if-else

Finding a person is minor or major


This program finds whether a person is minor/major depending upon his age.
If age<=18 then it displays “minor”, otherwise “major”
ip: 15 ip: 25
op: minor op: major
void main()
{ int age;
printf(“Enter the age:”);
scanf(“%d”, &age);
if(age<=18)
printf(“minor”);
else
printf(“major”);
}
Let age is 12
if( age <= 28 ) if( 12 <= 28 ) if(true)
printf(“minor”); printf(“minor”); printf(“minor”); printf(“minor”);
else else else
printf(“major”); printf(“major”); printf(“major”);

Finding given number is odd/even


This program accepts a number from keyboard and finds whether it is odd or even?
ip: 25 ip: 24
op: odd op: even
Logic: divide the input number with 2, and check the remainder; if the remainder is zero then it is said to be
even, otherwise odd.
void main()
{ int n;
printf(“Enter a number :”);
scanf(“%d”, &n);
if(n%2==0) // n%2 gives remainder of division
printf(“even number”);
else
printf(“odd number”);
}
The evaluation of if-statement is as follows

Let input is n=13. Then f(1==0) if(false)


if(n%2==0) printf(“even”); printf(“even”);
printf(“even”); else else printf(“odd“)
else printf(“odd”); printf(“odd”);
printf(“odd”);
C-Family 45 if-else

Finding a year is a leap year or not?


This program accepts year in a date and finds whether it is leap year or not?
ip: 2000 ip: 2005
op: 2000 is a leap year op: 2005 is not a leap year
Logic: if an year is divisible with 4, then it is said to be leap year otherwise non-leap year.
void main()
{ int year;
printf(“Enter year of date:”);
scanf(“%d”,&year);
if(year%4==0) // the operator % gives remainder of a division
printf(“\n year is a leap year”);
else
printf(“\n year is not a leap year”);
}
If the remainder of division “year%4” is zero, the year is said to be leap year, otherwise, not a leap year.
The evaluation of if-statement is as follows
Input: 2000 if(0==0) if(true)
if(year%4==0) printf(“leap year”); printf(“leap year”);
printf(“leap year”); else else
else printf(“not a leap year”); printf(“not a leap year”);
printf(“not a leap year”);

Finding biggest of two numbers


This demo program accepts two numbers from keyboard and displays small and big.
ip: 12 5 ip: 7 15
op: 12 is bigger than 5 op: 7 is smaller than 15
void main()
{ int a,b;
st
printf(“Enter any two numbers:”); // 1 printf()
scanf(“%d%d”, &a, &b);
if(a>b)
printf(“%d is bigger than %d”, a,b); // 2nd printf()
else
printf(“%d is smaller than %d”,a,b); // 3rd printf()
}
Here, if the condition a>b is true, then 2nd printf() is executed, or else, the 3rd printf() is executed.
So, always either if-block or else-block will be executed.

Writing if-else statement in simple style (finding big of two numbers)


if-body & else-body contains only single instruction then better to write in single line as shown below
(many professionals coders follow this style of coding)
If( a>b) // writing in same line
big=a; if( a>b) big=a;
else else big=b;
big=b;
C-Family 46 if-else

Finding difference of two numbers


This program accepts two values from keyboard and prints the difference in +ve ( like |x| )
(absolute value of a difference of given two numbers)+
ip: 12 18 ip: 19 11
op: 6 op: 8
Logic: User may enter numbers in any order, for example (12, 18) or (18, 12).
After subtracting, if the difference is –ve, then convert by multiplying with -1.
void main()
{ int a, b, diff;
printf(“Enter any two numbers:”);
scanf(“%d %d”, &a, &b);
diff=a-b;
if( diff < 0 ) // if difference is -ve
diff = -1*diff; // converting to +ve by multiplying with -1
printf(“\n difference = %d”, diff);
}
We can write the logic in other way as (subtracting small from big)
if(a>b) diff=a-b;
else diff=b-a;

Finding biggest digit for a given 2-digit number


This program accepts two-digit single number(N) and prints the biggest digit.
ip: 39 ip: 53
op: 9 op: 5
Logic: divide the ‘N’ with 10, the quotient will be the first-digit and remainder will be the second-digit.
Compare these two digits and print the big digit. Let N is 39, then N/10 gives 3, whereas n%10 gives 9.
void main() 10) 39 (3  first digit of 39
{ int n; 30
printf(“Enter a two digit number:”); ------
scanf(“%d”,&n); 9  second digit of 39
st nd
if(n/10 > n%10) // if 1 digit is bigger than 2 digit
st
printf(“%d”, n/10); // displaying 1 digit
else
nd
printf(“%d”, n%10); // displaying 2 digit
}

Finding reverse of 2/3 digit number


This program accepts a single number contained 2/3 digits and prints in reverse.
ip: 723 ip: 26
op: 327 op: 62
Logic: to get reverse of 29, compose the number as 9*10+2  92
to get reverse of 723, compose the number as 3*100+2*10+7*1
void main()
{ int n, rev;
printf(“Enter 2/3 digit single number :”);
scanf(“%d”, &n);
C-Family 47 if-else

if(n<100) // if n<100 then it is a two digit number


rev=n%10*10 + n/10; // reversing 2 digit number
else
rev=(n%10)*100 + n%100-n%10 + n/100; //reversing 3-digit number
printf(“reverse = %d”, rev);
}

Printing opposite case of an alphabet


ip: A ip: b
op: a op: B
This program accepts an alphabet character from keyboard and prints it in toggle case (opposite case).
If user entered in lower case, then prints in upper case and vice versa.
void main()
{ char ch:
printf(“Enter any alphabet:”);
scanf(“%c”,&ch);
printf(“\n ASCII value of given character is=%d”,ch);
if(ch>=’A’ && ch<=’Z’) // converting to opposite case
ch=ch+32;
else
ch=h-32;
printf(“\n Given character’s opposite case is =%c”,ch);
}
ip: enter any alphabet: A
op: ASCII value of given character is = 65
Given character opposite case is = a
The ASCII values of upper case alphabets is 65 to 90 (‘A’ to ‘Z’)
The ASCII values of lower case alphabets is 97 to 122 (‘a’ to ‘z’)
ASCII difference32.
Format string “%d” is used to print ASCII value of character
Format string “%c” is used to print ASCII symbol of character
C-Family 48 if-else

Nested-If Construct
Construction of one if-statement within another if-statement is called as nested-if. The inner and outer ‘if’
may have ‘else’ part of it. Look at the following different syntaxes of nested-if construct.
The simple form of nested-if statement is
if(condition) // outer if
{
if(condition) // inner if
{
instruction 1;
instruction 2;
---------
instruction n:
}
}
Let us see some more examples of nested-if with different styles
Example 1 Example 2 Example 3

if(condition) if(condition) if(condition)


{ { {
if(condition) if(condition) if(condition)
instruction1; instruction1; instruction1;
else } }
instruction2; else else
} { {
else if(condition) if(condition)
{ instruction2; instruction2;
if(condition) else }
instruction3; instruction3;
else }
instruction4;
}
In this way, we can nested as many ‘if’ statements as we need in the program

Checking given number is in between 10 & 20 or not?


void main()
{ int k;
printf(“enter a number”);
scanf(“%d”, &k);
if(k>=10)
{ if(k<=20) // nested if construction starts here
printf(“ yes, it is in between 10 & 20”);
else
printf(“no, it is above 20”);
}
else
printf(“no, it is below 10”);
}
C-Family 49 if-else

 Above code can be simplified using logical operators as


if( k>=10 && k<=20 )
printf(“yes, it is in limits of 10-20”);
else
printf(“no, it is not in limits of 10-20”);

Calculating the tax from given salary


 salary<=5000 then tax is zero
 salary>5000 and <=8000 then tax is 3%
 salary>8000 then tax is 5%
void main() Instead of writing three if-statements,
{ float salary, tax; it can be simplified using nested-if
printf(“enter the salary”);
scanf(“%f”, &salary); if(salary <= 5000)
if(sal<=5000) tax=0;
tax=0; else
{
if( salary>5000 && salary<=8000)
if(salary < 8000)
tax=salary*3/100;
tax=salary * 3/100.0;
if( salary>8000 ) else
tax=salary*5/100; tax=salary * 5/100.0;
printf(“ Tax is %.2f”, tax ); }
}

Finding roots of a quadratic equation


This program to display the root values of a quadratic equation given by its coefficients say a, b and c.
Here a, b and c are input numbers.
Logic: First find the value of (b2-4ac), let it is x
 if x<0 then print "roots are imaginary"
 If x == 0 print "roots are equal", the root1 and root2 are is -b/(2*a)
 If x > 0 then print root1, root2 values root1 = (-b+sqrt(x))/(2*a), root2 = (-b-b+sqrt(x))/(2*a)
void main()
{ float a, b, c, x, root1, root2;
printf(“enter a, b, c :”);
scanf(“%d %d %d”, &a, &b, &c);
x=b*b-4*a*c;
if(x<0)
printf(“roots are imaginary”);
else
{ if(x==0)
printf(“roots are equal, root1 & root2 = %f”, -b/(2*a));
else
{ printf(“Root1 = %f”, (-b+sqrt(x))/(2*a));
printf(“Root2 = %f”, (-b-sqrt(x))/(2*a));
}
}
}
C-Family 50 if-else

Printing biggest of three numbers


Note: Without using logical operators
ip: 1 4 2 ip: 33 4 22 if(x>y)
op: 4 op: 33 { if(x>z)
big=x;
Logic: let X, Y, Z are input values. else
if X > Y is true then Y is small and it can’t be a big. big=z;
Now big is in X or Z. So compare these two and print }
else
if X > Y is false then X is small and it can’t be a big. { if(y>z)
Now big is in Y or Z. So compare these two and print. big=y;
else
big=z;
}

* As inner if-else statement is a single statement, braces are not required to make into single for outer-if.
Based on this feature, we can remove braces of outer-if statement. The above code after removing braces is

if(x>y)
if(x>y)
big=x; single statement
else
big=z;
else single statement
if(y>z)
big=y; single statement
else
big=z;
printf(“\n biggest=%d”, big );

In this way, in C, any control statement can be taken as single statement including nested-if, thus above en-
tire if-statement can be taken as single compound statement. But sometimes, some people used to give
braces for clarity purpose even though they are not required.
Using logical operators (&&), above code can be simplified as
if( x > y && x > z )
big=x;
else // if control came to else part means, the ‘x’ is not the biggest
if(y>z) // so biggest is either ‘y’or ‘z’, compare and find it.
big=y;
else
big=z;
C-Family 51 if-else

Printing biggest of four numbers


Let a, b, c, d are four variables (This is explained using logical operators &&)

After removing un-necessary braces


if( a>b && a>c && a>d )
x=a;
if( a>b && a>c && a>d )
else
x=a;
{
else
if( b>c && b>d)
if( b>c && b>d)
x=b;
x=b;
else
else single-statement
{
if(c>d) single-statement
if(c>d)
x=c; single-statement
x=c;
else
else
x=d;
x=d;
}
printf(“\n biggest=%d”, x);
}
printf(“\n biggest=%d”, x);

Points to note
*As inner-if is single statement, the braces are not needed to make into single for outer-if. In this way outer-if
also becomes as single compound statement. This sense is to avoid overhead of braces in the program.
* In some cases, the braces make more clarity, so some coders use even though they are not required.
* When nesting is occurred, care should be taken between outer-if and inner-if. The else always belongs to
nearest above if-Statement. Let us see following example

Finding student is passed or not?


The student must secure min 35 marks in all subjects for passing the exam. Let us take 3 subjects and names
are m1, m2, m3. This program explained in three methods using nested-if, using extra variable, and using
logical operators. Let us see one by one.
void main()
{ int m1,m2,m3;
printf(“\n Enter marks in three subjects:”);
scanf(“%d%d%d”,&m1,&m2,&m3);
if(m1>=35)
if(m2>=35)
if(m3>=35)
printf(“passed”);
else
printf(“failed”);
else
printf(“failed”);
else
printf(“failed”);
}
 In the above program, if three conditions are true, the output “passed” is printed. If any condition is
false then corresponding ‘else’ part will be executed with the result “failed”.
 if and else are 1:1 type, so only one else is allowed for one if-statement. So here we need to write three
else-statements respective to three if-statements.
C-Family 52 if-else

Method-2: using Boolean logic(1/0)


x=1; // let us consider, the student is passed, so take x=1
if(m<35) x=0;
if(m<35) x=0;
if(m<35) x=0;
if(x==1) printf(“passed”);
else printf(“failed”);
In the above, you may feel some confusion over the variable ‘x’, if you are new to programming. But if we
examine the code with some sample input values then we can easily follow the logic. Here we first consid-
ered, the student passed; so we set x=1. Later it is replaced with 0, if student failed in any of three subjects.
Finally x value examined and result is printed.
Here x is filled with either 0 or 1 to know status of the result; of course, we can use any other two values.
But most of the programmers use this Boolean value; ‘1’ is used as +ve result and ‘0’ is used as –ve result.

Method-3: (using logical operators)


Most of the cases, we can avoid complexity in nested-if by using logical operators. These operators help us
to put the logic of program into words
if(m1>=35 && m2>=35 && m3>=35) //compound relational expression
printf(“\n passed”);
else
printf(“\n failed”);
In the above ‘if’ construct three relations are combined with ‘&&’ operator, if any one relation fails, the con-
trol enter into the ‘else’ part and “failed” is printed.

Calculating electricity bill


This program calculates the electricity bill based on units consumed by the customer.
The units are calculated by current meter reading – previous meter reading.
Based on number of units, the given tariffs are applied.
 if units <=100 units then // tariff-1

charge is 3.50/- per unit and category is ‘A’


 if units >101 and <=300 then // tariff-2

up to 100 as above said, for remaining units 5.50/- per unit and category is ‘B’
 if units >300 then // tariff-3

up to 300 as above said, for remaining units 8.00/- and category is ‘C’

input: no.of units consmed: 70⤶ input: no.of units consmed: 170⤶
output: bill amount is: 245.00 output: bill amount is: 7355.00
category is: ‘A’ category is: ‘B’

void main()
{ float billAmount;
int units;
char category;
printf(“Enter no.of units consumed: ”);
scanf(“%d”, &units);
C-Family 53 if-else

if (units<101)
{ //  this braces can’t be removed, because two instructions exist in this body
billAmount=units*3.50;
category=’A’;
}
else
{ //  this pair of braces can be removed, as the inner if-else is single statement.
if(units<301)
{ //  this braces can’t be removed, because two instructions exist in this body
billAmount=100*3.50 + (units-100)*5.50;
category=’B’;
}
else
{ // this braces can’t be removed, because two instructions exist in this body
billAmount= 100*3.50 + 200*5.50 + (units-300)*8.00;
category=’C’;
}
}
printf(“The bill is : %.2f”, billAmount);
printf(“\n Category is : %c”, category);
}
C-Family 54 if-else

If-else-if Ladder style


This is not a special control statement; it is one kind of written style of nested-if when several alternative
decisions exist. Normal nested style leads to heavy indentation when more alternative exist.
So it is rearrangement of nested-if like a straight-line unlike crossed-line as shown in the below syntax.
This is applied, when needed to process one decision from several alternative decisions. This structure is
also called ‘if-else-if’ staircase because of its appearance. The main advantage of this structure is, easy to
code, understand, and debug. The syntax is

Normal nested-if if-else-if ladder style


if(condition1) if(condition 1)
instruction 1; instruction 1;
else else if(condition 2)
{ if(condition 2) instruction 2;
instruction 2; else if(condition 3)
else instruction 3;
{ else if(condition 4)
if(condition 3) instruction 4;
instruction 3 ------------
else ------------
{ ----------
--------- else
--------- instruction n;
}
} By removing un-necessary braces and arranging all nested-
} if statements in one column makes the if-else-if ladder
style

Here conditions are evaluated from top to down, as soon as a true condition is found, the instruction
associated with it is executed and the rest of the ladder is bypassed. If none of the conditions are true, the
final ‘else-part’ will be executed. That is, if all other condition tests fail, the final ‘else’ instruction-n will be
performed. If the final ‘else’ is not present, no action takes place.
Although, the above ‘if-else-if’ ladder is technically correct, it can lead to bit confusion to the programmer.
For this reason, the ‘if-else-if’ ladder is usually written as

if(condition 1)
instruction 1;
else
if(condition 2)
instruction 2;
else
if(condition 3)
instruction 3;
-----------
-----------
else
instruction n;
Observe here, the nested statements are started in a new
line unlike same line as above said.
C-Family 55 if-else

Above program using if-else-if ladder style ( finding biggest of 4 numbers)

Normal nested-if if-else-if ladder style


if( a>b && a>c && a>d ) if( a>b && a>c && a>d )
x=a; x=a;
else else if( b>c && b>d )
if( b>c && b>d ) x=b;
x=b; else if( c>d )
else x=c;
if(c>d) else
x=c; x=d;
else printf(“ \n biggest=%d”, x );
x=d;
printf(“\n biggest=%d”, x )

Accepting student marks of 3 subjects & printing result


If student got <35 in any subject then print “F grade”
If student got average>=60 print “A grade”
If student got average>=50 && <60 print “B grade”
If student got average <50 print “C grade”

Normal nested-if style if-else-if ladder style


void main() void main()
{ int m1, m2, m3; { int m1, m2, m3;
float avg; float avg;
printf(“\n Enter 3 subject marks:”); printf(“\n Enter 3 subject marks:”);
scanf(“%d%d%d”, &m1, &m2, &m3); scanf(“%d%d%d”, &m1, &m2, &m3);
avg=(m1+m2+m3)/3; avg=(m1+m2+m3)/3;

if(m1<35||m2<35||m3<35) if(m1<35||m2<35||m3<35)
printf(“\n F grade”); printf(“\n F grade”);
else else if(avg>=60)
{ if(avg>=60) printf(“A grade”);
printf(“A grade”); else if(avg>=50)
else printf(“B grade”);
{ if(avg>=50) else
printf(“B grade”); printf(“C grade”);
else }
printf(“C grade”);
}
}
}
The above left side given nested-if cross aligned, however it is readable(because few decisions exist). If the
programmer did not take care while aligning the code properly, it makes un-readable and difficult to debug.
Hence, if-else-if ladder style is always best. If more than 10 alternative decisions exist, the normal nested-if
seems to be awkward and confusion, so the ladder-style is the alternative under any case.
C-Family 56 if-else

Finding fine amount for a late returned book at a library


The C-Family library charges a fine for every book returned late
 For first 10 days late, the fine is 5/- rupees
 For 11-20 days late, the fine is 10/-
 For 21-30 days late, the fine is 20/-
 For >=31 days late, 1/- per every day;
Write a program to accept the number of days late and display fine or the appropriate message.

These two statements are same with little difference, you can follow whichever you
like
void main() void main()
{ int daysLate, fine; { int daysLate, fine;
printf(“the number days late :”); printf(“the number days late :”);
scanf(“%d”, &daysLate); scanf(“%d”, &daysLate);
if( daysLate <=10 ) if(daysLate <=10)
fine=5; fine=5;
else else if(daysLate<=20)
if( daysLate<=20) fine=10;
fine=10; else if(daysLate<=30)
else fine=20;
if( daysLate<=30) else
fine=20; fine=daysLate;
else
fine=daysLate; printf(“fine amount = %f”, fine);
printf(“fine amount = %d”, fine); }
}

Calculating electricity bill


This program calculates the electricity bill based on units consumed by the customer.
The units are calculated by current meter reading – previous meter reading.
Based on number of units, the given tariffs are applied.
 if units <=100 units then // tariff-1

charge is 3.50/- per unit and category is ‘A’


 if units >101 and <=300 then // tariff-2

up to 100 as above said, for remaining units 5.50/- per unit and category is ‘B’
 if units >300 then // tariff-3

up to 300 as above said, for remaining units 8.00/- and category is ‘C’

input: no.of units consmed: 70⤶ input: no.of units consmed: 170 ⤶
output: bill amount is: 245.00 output: bill amount is: 7355.00
category is: ‘A’ category is: ‘B’

void main()
{ float billAmount;
int units;
char category;
printf(“Enter no.of units consumed: ”);
scanf(“%d”, &units);
C-Family 57 if-else

if(units<101)
{ billAmount=units*3.50;
category=’A’;
}
else if(units<301)
{ billAmount=100*3.50 + (units-100)*5.50;
category=’B’;
}
else
{ billAmount= 100*3.50 + 200*5.50 + (units-300)*8.00;
category=’C’;
}
printf(“The bill is : %.2f”, billAmount);
printf(“\n Category is : %c”, category);
}

Finding state of a person


This program accepts age of a person and prints his stage of life.
 age <=12  Child
 age>12 and <=19 Teenager
 age>19 and <=36  Youngman
 age>36 and <=60  Gentleman
 age>60  Senior Citizen
void main()
{ int age;
printf(“\n Enter age of person:”);
scanf(“%d”,&age);
if(age<=12)
printf(“Child”);
else if(age<=19)
printf(“Teenager”);
else if(age<=36)
printf(“Young man”);
else if(age<=60)
printf(“Gentle man”);
else
printf(“Senior Citizen”);
}
Finding status of a given input character
This program checks the category of a given character, whether it is alphabet or numeric or control
character or any other special symbol.
#include<stdio.h>
void main()
{ char ch;
printf(“Enter a character:”);
scanf(“%c”,&ch);
C-Family 58 if-else

if(ch>’a’ && ch<=’z’)


printf(“it is lowercase alphabet\n”);
else if(ch>=’A’ && ch<=’Z’)
printf(“it is uppercase alphabet\n”);
else if(ch>=’0’ && ch<=’9’)
printf(“it is a digit\n”);
else if(ch==’ ‘)
Printf(“It is a space character\n”)
else
printf(“it is a special symbol\n”);
}
Finding no.of days in a month
This program accepts month & year in a date, and find no.of days in a month
ip: 2 2011 ip: 4 2010 ip: 12 2010
op: 28 days op: 30 days op: 31 days
void main()
{ int m, y ;
printf(“enter month & year :”);
scanf(“%d %d”, &m, &y);
if(m==2 )
{ days=28;
if(y%4==0) // if leap year then month has 29 days.
days=29;
}
else if( m==4 || m==6 || m==9 || m==11 ) // april , june , setp , nov has 30 days
days=30;
else
days=31;
printf(“ no.of days in a month = %d”, days);
}

Checking given date is valid or not?


This program checks the given date is valid or not?
ip: 29/2/2011 ip: 31/4/2010 ip: 1/12/2010
op: invalid date op: invalid date op: valid date
Logic: if month & day is not in between 1-12 & 1-31, report “invalid date”
If day is in between 1-31, check the day according to days of the month and print the result
void main()
{ int d, m, y, bool;
printf(“enter date :”);
scanf(“%d/%d/%d”, &d, &m, &y); // values must be separated by ‘/’ like12/2/2000
bool=1; // let us take date is valid
if(m<1 || m>12 || d<1 || d>31)
bool=0;
else if(m==2 && y%4==0 && d>29) // for February and leap-year checking
bool=0;
C-Family 59 if-else

else if(m==2 && y%4!=0 && d>28) // for February and non-leap year checking
bool=0;
else if((m==4 || m==6 || m==9 || m==11) && d>30) // for 30-days month checking
bool=0;
if(bool==1) printf(“date is valid”); //finally check the bool and print the output
else printf(“date is in-valid”);
}
Incrementing given date by 1 day (let the input date is valid-date)
ip: 29 2 2012 ip: 31 12 2010 ip: 21 1 2010
op: 1 3 2012 op: 1 1 2011 op: 22 1 2010
void main()
{ int d, m, y;
printf(“enter a valid date :”);
scanf(“%d%d%d”, &d, &m, &y);
// incrementing day by 1-day
d++;
// after incrementing, if ‘day’ crosses the end of month limits, then shift to next month
if(m==2)
{ if(y%4==0 && d>29)
{ d=1;
m++;
}
else if(y%4!=0 && d>28)
{ d=1;
m++;
}
}
else if((m==4 || m==6 || m==9 || m==11) && d>30)
{ d=1;
m++;
}
else if(d>31)
{ d=1;
m++;
if(m==13)
{ d=1;
y++;
}
}
printf(“date after incrementing is %d-%d-%d”, d, m, y);
}
Conclusion: The choice of usage of if, if-else, nested-if, if-else-if ladder is left to the programmer. There are
no specific situational suggestions which statement is to be used when and where. However, ensure that,
the written code should be correct, clear, and easy to understand. While writing code, the programmer
should remember that, the C possesses, there is always a good structured alternative control statement
exist whenever complexity rises with one control statement.
C-Family 60 if-else

if - else linking
eg1) In C, if & else are 1:1 type, one else-statement always linked to only one if-statement in the program,
we cannot write one else-statement for two or more if-statements, following example explains it.
if( marks1>50)
if(marks2>50)
if(marks3>50)
printf(“passed”);
else
printf(“failed”);
in above , the else-part joins only to the last if-statement(marks3>50), so we can’t write one else-part to
many if-statements. The solution is, we need to write else-part to every if-statement, this is as
if(m1>=35)
if(m2>=35)
if(m3>=35)
printf(“passed”);
else
printf(“failed”);
else
printf(“failed”);
else
printf(“failed”);
------------------------------------------------------------------------------------------------------------------------------------------------
eg2) In some situations, where the ‘else’ is available to the outer-if and not to the inner-if , in that case, the
inner-if should be enclosed within braces { }, otherwise compiler links outer-else body to the inner-if.
Observe the following example
if(x==1)
if(y==2)
printf(“ x is 1, y is 2 ”);
else
printf(“x is not 1”);
Here, the programmer wrote else-part to the outer-if, but compiler links to the inner-if, to avoid this logical
error, enclose inner-if within braces { }. This is as follows
if(x==1)
{ if(y==2) // now this ‘if’ has no else part of it
printf(“x is 1, y is 2”);
}
else
printf(“x is not 1”);

About Boolean value


In C, any relational or logical expression results either 1 or 0 to determine true or false respectively. Suppose
the relation a<b is true then the operator ‘<’ gives the result 1 otherwise 0. These are known as Boolean
values in computer science.
But, In C, in place of test condition, we can use any arithmetic expression; in such case, the resultant value of
the expression decides the success/failure of the condition. If the expression results any non-zero number
then that condition is said to be true, otherwise false.
C-Family 61 if-else

That means any non-zero value (not necessarily 1) is considered to be true, whereas zero is false.
Observe the following program output
void main()
{ int x=0, y=1, z=10;

if( x+y ) // x+y  0+1  1  true


printf(“ White+Yellow ”);
if( x*y ) // x*y  0*1  0  false
printf(“ White * Yellow ”);
if( x ) // if( x )  if(0)  if(false)
printf(“ White ”);

if( y ) // if( y )  if( 1 )  if( true )


printf(“ Yellow ”);

if( 1 ) // if( 1 )  if( true )


printf(“ Red ”);

if( 5 ) // if( 5 )  if( true )


printf(“ Green ”);

if( -5.34 ) // true


printf(“ Blue ”);

if( 0 ) // false
printf(“ Black ”);

if( !0 ) // ! false  true


printf(“ Black ”);

if( !5 ) // ! true  false


printf(“ Black ”);

if(x&&y)
printf(“Black”); // if( x&&y )  if( 0 && 1 )  if(false && true)  if( false)

if(x||y)
printf(“Grey”); // if( x||y )  if( 0 || 1 )  if(false || true)  if( true)
}

About logical operators


When more conditions exist then they must combine using logical operators, otherwise, program may show
wrong output or syntax error. Let us observe the output of following program.
void main()
{ int k = -5;
if(0 < k <10)
printf(“\n k is in between 0 & 10”);
else
printf(“\n k is not in between 0 & 10”);
}
output: “k is in between 0&10”  wrong output, the evaluation of if-statement is as follows
C-Family 62 if-else

 if(0< -5 <10) // 0 < -5  false  0


 if(0<10) // 0 < 10  true  1
 if(1)
 if(true)
Here the test condition made true hence if-block executed. When two or more relations exist, they must be
composed by logical operators. The correct code is:
void main()
{ if(0 < k && k < 10)
printf(“\n k is in between 0 & 10”);
else
printf(“\n k is not in between 0 & 10”);
}
The condition is evaluated as if(0<k && k<10)  0<-5 && -5<10  0&&1  0 (false)

Null instruction caused by semicolon(;)


The extra semicolon(;) in the program goes to null-instruction, that is, if anybody by mistake is given extra-
semicolon then it forms as null-instruction. For example,
a=10;
b=20;
; // observe the extra semicolon
c=30;; // observe the one more extra semicolon
d=40;
here we have 6 instructions not 4, because extra semicolons considered as null-statement by the compiler.
This extra semicolon does nothing in this example.

Null instruction as if-statement’s body


Observe the following example

void main() void main() void main()


{ int A=10, B=5; { int A=10, B=20; { int A=10, B=20;
if(A<B) if(A<B) if(A>B) ;
; // null-instruction ; else ;
else else printf(“ sky is blue ”);
printf(“ sky is blue ”); printf(“ sky is blue ”); }
} }
Output: the sky is blue output: nothing is displayed output: sky is blue
Do not terminate any control statement’s header with the semicolon (;), otherwise, head and its body
get separated and the semi-colon will be formed as null-instruction as body. For example
A=5; A=5;
if( A<0) ; if( A>0)
printf(“A is -VE”); ;
prntf(“\nGood Night”); printf(“A is +VE”);
printf(“\nGood Night”);
op: A is –VE
Good Night
C-Family 63 if-else

void main() void main()


{ int a=10; { int a=10;
if(a<50) if(a<50)
printf(“ I love C ”); printf(“ I love C “ );
else ; else
printf(“ I marry C ”); ;
} printf(“ I marry C ”); // this is not in else-part
Output: I love C , I marry C }

void main() Output: compile time error


unfortunately here if-block contained two instructions.
{ int A=10,B=20; 1. Null instruction by semicolon
if(A>B) ; 2. printf(“A>B”);
printf(“A>B”);  compile time error 
when two or more instructions exist between if & else then they
else must enclosed by braces, if not, the compiler raises an error.
printf(“A<=B”); (Of course in our view it is only one)
}

Check out errors, if no errors then guess the output values


void main() void main() void main()
{ if(!0) { if( .00001 ) { int k=0;
printf(“test passed”); printf(“test passed”); if(k)
else else printf(“hello”);
printf(“test failed”); printf(“test failed”); else
} } ;
}
void main() void main() void main()
{ int k=20; { int k=1000; {
if( k > 10 ) if(10 > k < 35) if(-1.4)
printf(“I am in Right”); printf(“ I love C”);
else ; else else
printf(“I am in Wrong”); printf(“ I marry C”); printf(“test failed”);
} } }
void main() void main() void main()
{ if(-1.4) { int k=1; { int k=1;
; if(k>10) if(k>10)
else printf(“k is +ve”); printf(“ k is +ve”);
printf(“test failed”); printf(“k is > 10”); printf(“ k is > 10”);
} } else
printf(“ k is <=10”);
}
void main() void main() void main()
{ int a=100,b=1; { int a=10, b=5, c, d; { int a=30, b=40,c;
if( a ||b ) c=a>3; c =(a!=10 && b==50);
printf(“Good Morning”); d=a>6 && b!=10; printf(“b=%d, c=%d”, b ,c);
else printf(“c= %d , d=%d”,c ,d); }
printf(“Good Night”); }
}
C-Family 64 if-else

void main() void main() void main()


{ int a=20, b=230,c; { int k=1; { int k=1;
c =(a==100||b>130); if(k < 0) if(k < 0)
printf(“c=%d”,c); else printf(“k is -ve”);
} printf(“k is +ve”); else
} }
void main() void main() void main()
{ if( 0 ) { if( 10 ) { if( 0-1 )
printf(“A”); printf(“A”); printf(“A”);
else else else
printf(“B”); printf(“B”); printf(“B”);
} } }
void main() void main()
{ if( 10 ) ; { if( 10 ) ;
printf(“A”); printf(“A”);
else }
printf(“B”);
}
C-Family 65 switch statement

Switch Statement
Switch is another conditional control statement used to select one option from several options based on
given expression value. This is an alternative to the if-else-if ladder when comparisons happened against
with constants. The if-else-if seems to be lengthy and awkward when more comparisons exist. Switch is a
good alternative as its construction is simple and looking comfortable even if more cases found or nested.
However it does not support in all situations in which if-else-if support. ie, it compares only against with
integral constants.
In switch construct, the instructions are divided into case blocks based on logical condition and any number
of case blocks can be defined within it. Observe the following syntax and flow chart.
switch(expression) //  switch header
{
case constant-1: instruciton-1;
instruciton-2;
..…
break;
case constant-2: instruciton-1;
instruciton-2;
……
break;
………
.…….
default: instruciton-1;
instruciton-2;
……
}

* The expression in switch() header should be an integral type value such as char, int, long int.
* The expression value compares with constant-1, constant-2,… etc, if anyone matches then the control
jumps into associated case block and executes all the instructions within it, later comes out by break.
The break throws the control out of switch statement. In other words, keyword break used to come out of
switch after execution of selected case block. However break is an optional statement. If it is not present at
end of case-block, the control enters into next case block even though its constant value differs.

*The case constants may not be in ascending or descending order. The two or more case constants may be
associated with single block.

*The default block executes when no case is matched. The default is optional block and generally it is used
to handle input errors.

*In case block of switch, we can write any other control statement, sometimes it can be switch(nested)
C-Family 66 switch statement

Printing single digit value in true English words


input: 3
output: three
void main()
{ int digit;
printf(“Enter any single digit:”);
scanf(“%d”,&digit);
switch(digit)
{ case 0: printf(“zero”);
break;
case 1: printf(“one”);
break;
-------
case 9: printf(“nine”);
break;
default: printf(“Invalid input”);
}
}
 Here the value of digit is compared with given case constants 0, 1, 2, 3,… one by one, if any case matches
then the corresponding printf() prints the English word.

 If no case matches with the given value, then the default block executes and we get “Invalid input”.
Generally, default block used to handle errors like “invalid-input” and other things.

 Suppose the input is 4, then the “case 4:” matches and printf(“four”) executes. Later control comes out
when break gets executed.

 The above program can be written using if-else-if ladder form as shown below.
void main()
{ int k ;
printf(“Enter a digit:”);
scanf(“%d”,&k);
if(k==0) printf(“zero”);
else if(k==1) printf(“one”);
……
else if(k==9) printf(“nine”);
else printf(“Invalid input”); // like default block
}
The above two programs generate exactly same result. However, as you might notice that the first program
is easier to write, understand and modify. Structure of switch statement is more readable even if it is nested
2 or 3 times.

Demonstration of break usage in switch


Note: If break is not given at the end of case block, the control enters into next case block even though it
conveys different case-constant-value.
void main()
{ int a;
printf(“Enter a number:”);
scanf(“%d”, &N);
C-Family 67 switch statement

switch(N)
{ case 1: printf(“red”); // observe “break” not given
case 2: printf(“green”);
break;
case 3: printf(“blue”);
default: printf(“black”);
}
}
if input: 1  red green
if input: 2  green
if input: 3  blue black
if input:4  black
if input:5  black
if input:0  black

Finding number of days in a given month date


This program scans month & year in a date, and prints no.of days in that month
void main()
{ int m,y;
printf(“enter month & year :”);
scanf(“%d%d”, &m, &y);
switch(m)
{ case 2: days=28;
if( y%4==0 )
days=29;
break;
case 4:
case 6:
case 9:
case 11: days=30;
break;
default : days=31;
}
prinstf(“no.of days is %d”, days);
}
Here case blocks 4, 6, 9, 11 are associated with only one instruction, days=30. Thus two or more cases can
be associated with one block of code.

Testing whether a given alphabet is vowel/consonant


Note: two or more cases may associate with one block of instructions.
void main()
{ char ch;
printf(“Enter any lower case alphabet:”);
scanf(“%c”,&ch);
C-Family 68 switch statement

switch(ch)
{ case ‘a’:
case ‘e’:
case ‘i’:
case ‘o’:
case ‘u’: printf(“It is a vowel “);
break;
default: printf(“It is a consonant”);
}
}
Here all case blocks associated with only one instruction, which is printf(“it is a vowel”); Thus, for any input
vowel, the same message “It is vowel” is displayed. Otherwise, we’ll get the “It is a consonant”.

Conditional operator (?)


This is the simple conditional operator used to process one instruction from a given two instructions. It is an
alternative to the simple if-else construct when its body consists of single instruction. It works like inline
version of if-statement (single line). This conditional operator also called ternary operator since it takes
three operands.
The general syntax is: condition? expression1: expression2;
here, the condition is true then the expression1 is evaluated (executed) otherwise expression2 is evaluated.
eg1: big = X>Y ? X : Y; this is equal to: if(X>Y) big=X; else big=Y;
eg2: X>Y ? printf(“X is biggest”) : printf(“Y is biggest”);
eg3: difference = A>B ? A-B : B-A ;
Here, if A>B is true then the value of A-B is assigned to difference, otherwise, B-A is assigned.
This is equivalent to
if(a>b) diff=a-b;
else diff=b-a;
The ternary operator can be nested, but it makes confusion to the programmer, therefore, it is suggested to
use only when two way decisions exist and their expressions are simple.
Let us see the following example, how nesting makes complexity to the programmer. Program prints the
biggest of three numbers, which are located in variables a, b, c.
void main()
{ int a,b,c;
printf(“\n Enter any three numbers:”);
scanf(“%d%d%d”, &a,&b,&c);
a>b ? (a>c ? x=a : x=c) : (b>c ? x=b : x=c); // observe the complexity in nested usage
printf(“Big = %d”, x);
}
In the above program, as conditional operator nested, it seems to be complex and unreadable. So when
nesting takes place then it is better to use if- statement.
C-Family 69 switch statement

goto Statement
It is used to jump the control from one location to another location within a function. This unconditional
control statement diverts the control to a specified location where the label is mentioned. Using this, the
control can be moved to forward or backward or in any order in the function.

The early high level languages such as ALGOL, FORTRAN were influenced by a combination of if & goto
statements. The goto was considered to be a powerful statement as any problem (program) can be solved
using this. But program becomes complex, if the code is big and many goto statements are used.

As a result this statement fell out of favor some years ago, hence several alternative rich set of control
statements are provided in modern languages such as switch, while, for, do-while, break, continue, and
return. However, for some kind of situations like getting out of nested loops, to solve recursive like programs
using loops, …etc. We cannot get a solution using these rich set, so, goto occasionally has its uses.

Syntax: goto label; // Here, the label is a valid identifier followed by a colon, indicates a location to where
the control has to be jumped using goto. Label name follows the rules of a variable name.
void main()
{ printf(“India\n”);
goto end; //observe here, the control will be transferred to “end”
printf(“American\n”);
printf(“Australia\n”);
end: // here ‘end’ is a label
printf(“Russia\n”);
printf(“Japan\n”);
}
Output: India
Russia
Japan
When “goto end” is executed, the control simply jumps over to label “end” and follows next instructions.

Another demo program , how the control jumps using goto


void main()
{ printf(“Red\n”);
goto one;
two: printf(“Green\n”);
printf(“Blue\n”);
printf(“Yellow\n”);
goto end;
one: printf(“White\n”);
printf(“Cyan\n”);
goto two;
end:
}
By observing the above code, we can say that, goto is a powerful statement as control can be moved to any
place but it led to unreadable and complex because of many goto used.
C-Family 70 switch statement

Demo program for identifier “label”


The identifier label is not like a variable and it does not occupy any space in machine code file, instead it
works like a line indicator in the program. Generally, after compilation of a program, every instruction
associate by a line number in the machine code, it tells the sequence of instructions in the program. Let us
see a program, how it creates line numbers in the machine code file.

Code with labels Code after compilation


void main() void main()
{ printf(“Red”); { line1: printf(“Red”);
goto one; line2: goto line5;
two: printf(“Blue”);
goto end; line3: printf(“Blue”);
one: printf(“Green”); line4: goto line7;
goto two; line5: printf(“Green”);
end: printf(“end of program”); line6: goto line3;
} line7: printf(“end of program”);
}

Unconditional control transfer


main()
{ wish: // line1
printf(“Hello, how are you?\n”); // line2
goto wish;
}
In this example ‘wish’ is the label name, which specifies the line number for the goto statement, here it is
line1 .When the ‘goto wish’ executes, resulting diversion of control back to the location wish. Here, the
execution of printf() repeats endlessly.
Hello, how are you?
Hello, how are you?
Hello, how are you? ….
:
(To stop or kill the indefinite loop of this program, we have to press the keys control +break or control+c (in
Dos), alt+control+del (in Windows) or other keys provided by o/s)
As we got to know that, goto is an unconditional (condition less) control statement, therefore, it is always
association with if-statement to provide the conditional control transfer.
The following program prints “Welcome” message 10 times
void main()
{ int counter=1; //take a counter with 1, for counting 10 times
wish:
printf(“Welcome to C-Family, Vijayawada\n”);
counter++; // increment the counter
if(counter<=10)
goto wish; // repeat until counter <=10
}
Here, in this program, the variable counter is used to count the number of times the printf() is repeated.
After completing 10 cycles, the given if-condition will fail and thus the goto statement is skipped, which
turns to end of the program.
C-Family 71 switch statement

Program displays the given multiplication table up to 10 terms.


If input is 8
then output is:
8*1=8
8*2=16
8*3=24
---
void main()
{ int i=1; // take a counter variable ‘i’ and set to 1
int n; // ‘n’ holds the table number
printf("\nEnter the table number:");
scanf("%d",&n);
nextRow: // setting label for next cycle
printf("\n %d * %d = %d", n, i, n*i); // printing terms
i++; // incrementing ‘i’ to generate next term
if( i<=10 ) goto nextRow; // go back to print next term
}

Program to print 1 to 20 tables ( extension to above program)


void main()
{ int n=1; // ‘n’ for table-numbers
int i; // ‘i’ to print 1-10 terms of each table
nextTable:
i=1;
nextRow:
printf("\n %d * %d = %d", n, i, n*i); // printing terms
i++; // incrementing ‘i’ to generate next term
if( i<=10 ) goto nextRow; // go back to print next term
n++;
if(n<=20) goto nextTable;
}
C-Family 72 Loops

Control Looping Statements


In programming, it is common process to repeat instructions more than one time. Using goto statement,
it can be achieved, however, it is an unstructured control transfer statement, which will cause a severe
programming complexity upon nested usage or if their number increases. To eliminate such complexity, C
provides some structural control statements for looping such as while, for and do-while.
These 3 structures manage the execution sequence over some set of instructions repeatedly until a certain
condition is satisfied

These loop control statements are used to execute some set of instructions repeatedly until a given test
condition is attained. Each loop structure has its own style and provides a convenience to the user. The user
can select any loop control statement in the program according to the requirement and convenience and
there are no specific situational suggestions, which loop to use when and where.

All loop control statements are attached with a test-condition and a body. This body contains one or more
instructions, which are to be executed repeatedly until the test condition becomes false. We can write any
type of instructions or even another control statement with in this body.

The while loop


This is a simple loop statement with a terminating condition and associated block of instructions. Syntax is,

while (test condition)


{
instruction 1; Condition false
instruction 2;
------- true
-----
Instruction N; Instruction 1;
} Instruction 2;
Instruction N+1; ------
instruction N+2; Instruction N;
---
---
In the while loop, initially, the test-condition is checked and if it is true, the control transfers into the loop-
body and process the instruction-1, instruction-2,… and instruction-N. Later, control jumps back to the
beginning of loop for next cycle i.e., again the test-condition is checked and if it is true then the control
re-enters into the loop-body and executes all instructions within it. This process continues as long as test-
condition becomes false.

If the test-condition becomes false then the control jumps out of loop-body and follows the bottom
instructions “instruction n+1, instruction n+2 ….”

If loop body has only one instruction, the pair of braces {} are optional. This is as said in if-statement.
If loop-body has more instructions exist, they must enclose by pair of braces{}.

The test-condition must fail after certain number of times. Otherwise, it goes to infinite loop.
Don’t terminate loop header with semi-colon, otherwise, the head & body gets separated.

The following examples explain the different formats of while-loop usage


C-Family 73 Loops

Loop with single instruction in its scope

while(test-condition) // only the first instruction is repeated here. (Observe no braces is given)
instruction 1;
instruction 2;
instruction 3;
instruction 4;
--
In the above loop, only the instruction1 repeats until the test-condition becomes false. When the test-
condition fails then loop will be terminated and follows instruction-2, instruction-3… onwards.
(if braces not provided then compiler takes only first instruction into loop body)

Loop with more instructions in its scope

while(test condition) // repeats all instructions with in the body


{ instruction-1;
instruction-2;
-----
instruction-n;
}
if loop has more instructions, they must be surrounded by pair of braces {}, this rule same as in if-statement

By mistake, what happens if loop header terminated by semicolon?


Do not terminate the loop header with semicolon, otherwise head and its body gets separated and an empty
loop is formed with a null instruction. The semicolon forms as a null instruction as loop body.
The following example gives the clarity how semicolon formed as null instruction as loop body

Observe semicolon at the end of loop-header Let us imagine this semicolon in the next line
and how it formed as null-body (null instruction)

while (test condition); while (test condition)


{ ;
instruction 1; {
instruction 2; instruction 1;
------ instruction 2;
----- ------
instruction N; instruction n;
} }

Printing 1 to 10 natural numbers using while loop


Algorithm
step1. take ‘i’ as loop variable with 1, here ‘i’ works as counter for 1 to 10
step2. print ‘i’ value as output
step3. increment ‘i’ by 1
step4. repeat step2 and step3 until i<=10
step5. stop.
C-Family 74 Loops

void main()
{ int i=1; // initialization of loop variable with 1
while(i<=10) // loop begins here
{ printf(“%d ”, i ); // printing ‘i’ value on the screen
i++; // incrementing ‘i’ by 1
}
printf(“\n this is end of loop ”);
}
Generally, programmers always take loop variable name as ‘i’ , because loop cycles are called iterations and
first letter of it taken as loop variable. Generally loop variable begins with value ‘1’ and increments up to ‘N’.

Printing 1 to 10 and 10 to 1 using while loop


Write two loops, loop after loop, first loop prints 1 to 10, and second loop prints 10 to 1
void main()
{ int i=1; // initialization of loop variable with 1

while(i<=10) // loop begins here


, printf(“%d ”, i); // printing ‘i’ value on the screen
i++; // incrementing ‘i’ by 1
}

i=10;
while(i>=1) // loop begins here
, printf(“%d ”, i); // printing ‘i’ value on the screen
i--; // decrementing ‘i’ by 1
}
}

Printing numbers between two given limits


ip: 14 45
op: 14 15 16 17 18 …..45
step1: take lower & upper as input variables and scan data from KB(keyboard)
step2: take ‘i’ as loop counter and initialize with lower limit (i=lower)
step3: print ‘i’ value
step4: increment ‘i’ by 1, to generate next number
step5: repeat step3 and step4 until i<=upper
step6: stop.
void main()
{ int lower, upper, i ;
printf(“\n enter lower and upper limits :”);
scanf(“%d%d”, &lower, &upper);
i=lower; // begins ‘i’ with lower limit
while(i<=upper) // loop to repeat up to upper limit
{ printf(“%d\t “, i);
i++;
}
}
C-Family 75 Loops

Printing 1, 10, 100, 1000, 10000, 1000000 for 6 times [ do not use pow() fn ]
1. take ‘i’ as loop variable with starting value 1, here ‘i’ works as loop counter as well as to print output(s)
2. print ‘i’ value as output
3. multiply 10 to ‘i’, to generate next value of output
4. repeat step2 and step3 until i<=100000
5. stop.
void main()
{ int i=1;
while(i<=1000000)
, printf(“%d “, i );
i=i*10;
}
}

Printing 1000000, 100000, 1000, 100, 10, 1 for 6 times


1. take ‘i’ as loop variable with starting output value 1000000
2. print ‘i’ value as output
3. diminish ‘i’ by 10, to generate next output value
4. repeat step2 and step3 until i>0
5. stop.
void main()
{ int i=1000000;
while( i>0 )
, printf(“%d “, i );
i=i/10;
}
}

Printing 1, 2, 4, 8, 16, 32 ------ for 10 times [ do not use pow() fn ]


1. take ‘i’ to repeat loop for 10 times
2. take ‘p’ to generate values 1, 2, 4, 8, 16, … etc [ 20 , 21 , 22 , 23 , 24 , 25 ... ]
3. set i=1, p=1; // starting values of i & p
4. print( p );
5. multiply 2 with ‘p’, to get next output of 2i value
6. increment loop variable ‘i’ by 1
7. repeat step4 to step6 until i<=10
8. stop.
void main()
{ int i=1, p=1;
while( i<=10 )
{ printf(“%d “, p );
p=p*2;
i++;
}
}
C-Family 76 Loops

Printing N, N/2, N/4, N/8, …1.


ip: 100
op: 100 50 25 12 6 3 1
1. read N value from keyboard
2. print N value
3. decrement N to N/2, to get next value of output
4. repeat step2, step3 until N>0 and stop
void main()
{ int N;
printf(“enter N value :”);
scanf(“%d”, &N);
while( N>0 )
{ printf(“%d “, N);
N=N/2;
}
}

Generate and print list of numbers from N to 1


Here N is input from keyboard and print the list of numbers as long as the value of N >1.
if N is even then next number of N is → N/2 (half),
if N is odd then next number of N is → 3N + 1
if input N is 13, then we have to print like: 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
void main()
{ int N;
printf(“enter N value :”);
scanf(“%d”, &N);
while( N>1 )
{ printf(“%d “, N);
if( N%2==0) // if N is even then reduce N=N/2
N=N/2;
else
N=3*N+1; // if N is odd then raise N=3*N+1
}
}

Printing odd numbers for first N terms


ip: 10
op: 1 3 5 7 9 11 13 15 17 19
1. take ‘i’ as loop variable and initialize with first odd number 1 (here ‘i’ used as loop counter and output)
2. print ‘i’ value as output
3. increment ‘i’ by 2 to generate next odd number
4. repeat step2, step3 until i<2*N (Nth term in odd series is 2*N-1)
void main()
{ int i=1, N;
printf(“enter number of terms to print :”);
scanf(“%d”, &N)
C-Family 77 Loops

while(i<2*N)
, printf(“\t %d “, i );
i=i+2;
}
}

Printing odd numbers from N to 1 in reverse order


Note: The input value N may be odd or even entered by the user, for example
ip: 15 ip: 24
op: 15 13 11 ….1 op: 23 21 19 …..1
1. take input to N
2. If N is even then convert to odd, because we have to print odds only.
if( N%2==0 ) // if input N is even like 24, then changing to next odd 23
N=N-1;
3. print ‘N’ value
4. decrement N to N-2 to get next odd number
5. Now repeat step3, step4 until N>0
void main()
{ int N;
printf(“enter n value :”);
scanf(“%d“, &N);
if(N%2==0)
N=N-1;
while( N>0 )
{ printf(“%d ”, N);
N=N-2;
}
}
The above code can be written in other way as
[Here each number from N to 1 checked in favor of oddness and printing it on the screen]
while(N>0) // loop to print odd numbers up to 1.
{ if( N%2 == 1 ) // if N is odd then print it
printf(“%d ”, N ); // remember braces not given
N--; // decrement N towards to 1.
}
input: 25
Sample run 25%2==1  1==1  true  print( 25 as output)
24%2==1  0==1  false skips
23%2==1  1==1  true  print(23 as output)
22%2==1  0==1  false  skips
21%2==1  1==1  true  print(21 as output)
20%2==1  0==1  false  skips
19%2==1  1==1  true  print(19 as output)
----
C-Family 78 Loops

Printing 10 numbers preceding and succeeding of a given N


ip: 36
op: 26 27 28….34 35 36 37 38… 45 46
1. scan input to N
2. take loop variable ‘i’ with starting value N-10, as first value in output
3. print(i) on the screen
4. increment ‘i’ by 1, to generate next number
5. repeat step3, step4 until i<=N+10
void main()
{ int i , n;
printf(“\n enter n value :”);
scanf(“%d”, &n);
i=n-10; // start from n-10
while(i<=n+10) // loop to repeat up to n+10
{ printf(“%d “, i);
i++;
}
}

Printing 1 to 10 numbers by skipping 5


op: 1 2 3 4 6 7 8 9 10
void main()
{ int i=1;
while(i<=10)
{ if( i!=5) // if ‘i’ value is not 5 then print(i)
printf(“%d “, i );
i++;
}
}

Printing multiplication table up to 10 terms for a given table N


ip: 9
op: 9*1=9
9*2=18
9*3=27
....
9*10=90
Logic: print( N*i ) for 10 times where i=1 to 10
void main()
{ int n , i;
printf(“enter table number :”);
scanf(“%d”, &n);
i=1;
while(i < 11) // loop to print 10 terms
{ printf(“\n %d * %d = %d”, n, i, n*i );
i++;
}
}
C-Family 79 Loops

** Checking Lucky number 58 is entered or not?


Note: This is just a demo program, used to explain Boolean logic which we used vastly in the programming.
This program accepts 5 numbers from keyboard and checks whether user entered lucky number 58 in that 5
input numbers or not?
ip: enter number 1: 34 ip: enter number 1: 10
enter number 2: 12 enter number 2: 82
enter number 3: 23 enter number 3: 98
enter number 4: 11 enter number 4: 58
enter number 5: 6 enter number 5: 9
op: lucky number 58 not found op: lucky number 58 found
Logic: read input values one by one for 5 times, while scanning if any input is 58 then mark it as found, later
print found or not?
void main()
{ int n, found, i=1;
found=0; // user not yet entered any input at the beginning , so take found=0 (found=false)
while( i<6)
{ printf(“enter number %d :”,i);
scanf(“%d”, &n);
if(n==58)
found=1; // found=true
i++;
}
if( found==1 )
printf(“ lucky number 58 found”);
else
printf(“lucky number 58 not found”);
}
Here ‘found’ is an integer variable, used to store either 1 or 0 (true or false), first we assumed found=false,
later while scanning 5 values, if user entered 58 then it replaces found=true; finally after completion of loop,
result displayed using ‘found’ variable. We can use any other name instead found in the program

Printing factors of a given number (N)


ip: 18
op: 1 2 3 6 9 18.
Logic: to get factors, divide N with 1,2,3,4,5,…N, that is, check with all possibilities from 1 to N, which ever
divides the N then it will be a factor, so print it on the screen.
1. take input into N
2. set loop variable ‘i’ with 1, to check for factors from 1
3. divide N with ‘i’ to check for factors, if divisible then print(i) as factor
if N%i==0 then
print(‘i’) as factor.
4. increment ‘i’ by 1
5. repeat step3, step4 until i<=N
6. stop.
void main()
{ int i , N;
printf(“\n enter n value :”);
scanf(“%d”, &N);
i=1; // checking for factors starting from 1.
C-Family 80 Loops

while(i<=N) // loop to check N with 1,2,3,4…for finding factors


{ if(N%i==0) // checking N, whether it is divisible or not
printf(“%d\t “, i); // if N is divisible then print ‘i’ as factor
i++;
}
}
input: 15
sample run: 15%1==0  true print(1) as a factor
15%2==0  false skips
15%3==0  true print(3) as a factor
15%4==0  true skips
15%5==0  true print(5)

Finding small factor of N (excluding ‘1’ as a factor)
ip: 15 ip: 18 ip: 35 ip: 17
op: 3 op: 2 op: 5 op: 17
logic: for small factor, divide N with 2,3,4,5,… upto N, that is check with all possibilities from 2 to N, but
whichever divides first then it will be small factor and stop the loop.
void main()
{ int i, N;
printf(“enter N value :”);
scanf(“%d”, &N);
i=2; // checking for factors starting from 2
while(i<=N) // we have to check up to N.
{ if(N%i==0) // verifying N with each number in ‘i’.
break; // break stops the loop.
i++;
}
printf(“%d\t “, i); // printing big factor
}
Here N verified repeatedly for small factor from 2 to N, meanwhile, if it is divided with any number then loop
stops by break and prints it as small factor. The break statement stops the loop and moves the control out of
loop-body, which is as above shown arrow. This program can be simplified as
i=2;
while(N%i!=0) // the loop stops when ‘i’ divides the N
{ i++;
}
printf(“small factor is %d”, i);

Finding biggest factor of N (excluding N as a factor)


ip: 15 ip: 18
op: 5 op: 9
Hint: Generally, for any number, the possible factors lies in range 1,2,3,…N/2 (exclude N). That is, there
should not be factors found beyond N/2. For example, if we take 100 then possible factors are 1,2,3, …50.
The value 100 never divides with 51, 52, 53,…,98, 99, so it is useless to check beyond N/2.
In this program, as we want big factor, it is wise to check from N/2 to 1 (in reverse order)
C-Family 81 Loops

void main()
{ int i,n;
printf(“enter n value :”);
scanf(“%d”, &n);
i=n/2; // checking for factors starting from n/2
while(i>0) // we are expected to check up to 1.
{ if(n%i==0) // verifying ‘n’ with each number.
break; // break stops the loop.
i--;
}
printf(“%d\t “, i); // printing big factor
}
Here N verified repeatedly for big factor from N/2 to 1, meanwhile, if it is divided with any of ‘i’ then loop
stops by break and prints it as big factor. The break statement stops the loop and moves the control out of
loop-body, which is as above shown arrow.
Above program can be written in simple form as
i=n/2;
while(n%i!=0)
i--;
printf(“big factor is %d”, i);

**Printing given number is prime or not?


Write a program to find the given number N is prime or not.
ip: N = 17 ip: N = 18
op: yes, it is prime op: no, it is not prime
Prime number does not divide with any number except 1 & N itself. So, to know primness of N, divide &
check the N by dividing from 2,3,4,….N/2. If not divided with any of these numbers then it is said to be
prime. Based on this concept, a beginner may write prime logic as bad as
i=2;
while( i <= N/2 )
{ if(N%i==0)
printf(“\n not prime”);
else
printf(“\n prime”);
i++;
}
ip: N=10 (many outputs)
op: not prime // when 10%2==0 is true
prime // when 10%3==0 is false
prime // when 10%4==0 is false
not prime // when 10%5==0 is true
Here we get many outputs and it is wrong, because prime-ness can be declared only after checking with all
numbers from 2 to N/2. Here we have to take output decision only after completion of loop (not inside loop)
so to solve this problem, better to use Boolean logic, there several other logics to find prime-ness, but this
Boolean logic is standard and best, the code as given below
C-Family 82 Loops

void main()
{ int n, i, bool ;
scanf(“%d”, &N);
i=2, bool=1; // assume ‘N’ is prime, so take bool as 1 (true).
while(i<=N/2)
{ if(N%i==0)
{ bool=0; // here N divided, therefore N is not prime, so set bool to 0 (false) and stop
break;
}
i++; // if N is not divided then check with next ‘i’ value until i<=n/2
}
if( bool==1) printf(“prime”); // printing output, after completion of loop
else printf(“not prime”);
}
Logic2: Count all factors of N, that is, divide N with all numbers from 1 to N and count them, if factors
count==2 then say it is “prime” or else “not prime”. This is simple logic but execution is slow, because it is
unnecessary check with all numbers if once N is divided. (here we are not stopping by break)
count=0; i=1;
while(i<=N) // loop to count all factors between 1 to N
{ if(N%i==0)
count++; // increments ‘count’ when N is divided with ‘i’
i++;
}
if( count==2) printf(“not prime”);
else printf(“prime”);

Summing 2+2+2+2+ …. for N times (do not use multiplication operator)


Logic: take ‘sum’ with zero, and repeatedly add 2 to ‘sum’ for N times.
step1: take ‘sum’ to store sum of 2+2+2+ … for N times
step2: set sum=0 to clean the garbage sum = sum+2
step3: add ‘2’ to sum, this is as “sum=sum+2”
step4: repeat step3 for N times sum = 0+2
step5: print (sum)
Look at the picture, how 2 is added to ‘sum’ in cycle
sum = 0+2+2
void main()
{ int sum , i , N ;
sum = 0+2+2+2
scanf(“%d”, &N);
i=1, sum=0;
sum = 0+2+2+2+2
while(i<=N)
{ sum=sum+2;
sum = 0+2+2+2+2+2
i++;
}
printf(“sum is %d”, sum); sum = 10 , if n=5
}
Note: if sum is not initialized with 0 in the beginning, then it contains garbage value, so the instruction
sum=sum+2 is executed as “sum=GarbageValue+2”. So set sum=0, at the beginning to clean the garbage.
C-Family 83 Loops

Counting –ve’s values, also finding sum of given N values


This program accepts numbers one by one from keyboard until last input value is 0, when zero is entered
then stops scanning and prints the count of -ve and sum of all values.
Ip: 11
-3
44
30
23
-6
0 ( zero is end of input )
op: -ve count = 2, sum = 99
void main()
{ int i=1, n, sum=0, nCount=0 ;
while(1)
{ printf(“enter a value * zero is end + :”);
scanf(“%d”, &n); // scanf() must be written inside loop, to scan value by value until n==0
if(n==0)
break;
if(n<0)
nCount++; // counting –ve’s
sum=sum+n; // summing all values
}
printf(“\n sum=%d \n -ve count =%d ”, sum, nCount);
}

In programming, the most of the logics fall under 5 types


1. Sum accumulation logic: used to find sum of values. for example
 finding total bill of all items at supermarket
 sum of polynomial equation terms like x1 + x2 + x3…
 monthly or yearly reports of all transactions at bank or inventory …etc
2. Product accumulation or diminishing logic: used to find product of n terms
 finding product of values like factorial
 finding value like xy value
3. Boolean logic: Mainly used to check or search for particular element in a group
 finding given number is a prime or not
 Finding status of process, whether it is successfully processed or not?
 finding specific record in a file
4. Selection logic: used to select a desired value from a group of values
 finding big/small from array of elements
 finding smallest path in the network
 finding optimistic position in chess game
5. Data exchange logic: here variable values are advances based on previous values
 printing Fibonacci series
 finding GCD of two numbers
6. Other miscellaneous logics are counting, checking, increment/decrementing …etc
C-Family 84 Loops

Finding sum & product of 1 to n. (1+2+3+4…+n; 1*2*3*4*…*n)


Here the formula n(n+1)/2 is not used to get the sum of all terms
ip: n=5
op: sum=15 (1+2+3+4+5)
product=120 (1*2*3*4*5)
1. scan ‘n’ value from keyboard ( ‘n’ is upper bound ).
2. take variables ‘sum’ and ‘product’ to store sum & product of 1 to n values.
Initialize sum with ‘0’ and product with ‘1’ to clean the garbage.
3. take loop variable ‘i’ and initialize with ‘1’ as series starts with 1.
4. add ‘i’ values 1, 2, 3… to ‘sum’ in each iteration (this is like sum = sum + ’i’ )
similarly multiply ‘i’ values to product ( this is like product = product * ’i’ )
5. increment ‘i’ by 1
6. repeat step4 to step6 until i<=n
7. print( sum, product) sum = sum+i
8. stop
Observe the picture, how sum = sum + ’i’ is processed in every iteration sum = 0+1
void main()
{ int i, n, sum, product; sum = 0+1+2
printf(“enter n value :”);
scanf(“%d”, &n);
sum=0, product=1, i=1; sum = 0+1+2+3
while(i<=n)
{ sum=sum+i; sum = 0+1+2+3+4
product=product*i;
i++; sum = 0+1+2+3+4+5
}
printf(“\n sum=%d \n product=%d”, sum, product);
sum = 15 , if n=5
}

Printing values of 1, 1+2, 1+2+3, 1+2+3+4, 1+2+3+4+5 for N terms


Output: 1, 3, 6, 10, 15, ….
note: this is same as above program but prints ‘sum’ value in every iteration.

void main() here after every cycle, the sum accumulated to as


{ int i, n, sum; After cycle1 sum is: 0+1  (1)
printf(“enter n value :”); After cycle2 sum is: 1+2  (3)
scanf(“%d”, &n); After cycle3 sum is: 1+2+3  (6)
sum=0, i=1; After cycle4 sum is: 1+2+3+4  (10)
while(i<=n) After cycle5 sum is: 1+2+3+4+5  (15)
{ sum = sum + i ; ----
printf(“%d “, sum); ----
i++;
} So print ‘sum’ value in each cycle to print output.
}
C-Family 85 Loops

Finding sum of (1) + (1+2) + (1+2+3) + (1+2+3+4) + .............N times


The sum of series is: (1) + (3) + (6) + (10) + --- + N times
Note: do not use any formula or nested loop
ip: N=5
op: sum=35
Logic: In the above program, we already discussed, after every cycle, the sum value are 1, 1+2, 1+2+3, …etc.
these values need to be added again to get total sum.
void main()
{ int i, n, sum1, sum2;
printf(“enter n value :”);
scanf(“%d”, &n);
sum1=0, sum2=0, i=1;
while(i<=n)
{ sum1 = sum1 + i ;
sum2=sum2+sum1;
i++;
}
printf(“%d “, sum2);
}

Finding sum of series of 12+22+32+42+52 …..+102


Prove that sum of 12+22+32+42+52 …..+102 is equal to 385 or not?
op: yes/no
logic: take ‘sum’ with zero, repeatedly add i2 value to sum for 10 times, where i=1 to 10
after finding sum, compare with 385 for equality.
void main()
{ int i, sum;
sum=0; i=1;
while(i<=10) // loop to add up to 10 terms
{ sum=sum + i*i;
i++;
}
if(sum==385) printf(“program is correct”);
else printf(“program has some logical mistakes”);
}

Printing values of 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , ….. 10 times


Output: 1 2 4 8 16 32 …. Up to 10 terms
0 1 2
1. take a variable ‘p’ to generate terms of 2 , 2 , 2 , … in each cycle
2. take ‘p’ with 1(20), this is first value in the series
3. print (p), later multiply ‘p’ with 2 to get next value in the series
4. repeat step3 for 10 times using loop variable ‘i’, where i=1 to 10 do
5. stop.
void main()
{ int p=1, i=1;
while(i<=10) // loop to repeat 10 terms
{ printf(“%d “, p);
i
p=p*2; // generating next 2 value
i++;
}
}
C-Family 86 Loops

Finding sum of 20+ 21+22+……+2n without using pow() function


Like above program, instead of printing values of 2i , add all values of ‘p’ to sum.
ip: n=5
op: sum=31
void main()
{ int n, sum, p, i;
printf(“enter n value :”);
scanf(“%d”, &n);
sum=0; p=1; i=1;
while(i<=n) // loop to add ‘n’ terms
{ sum=sum + p; // adding 2i values to sum
i
p=p*2; // generating next 2 value
i++;
}
printf(“\n sum=%d”, sum);
}

Print values of x1 x2 x3 x4 ….xn (without using power function)


ip: 3 5 ( x=3 , n=5 )
op: 3 9 27 81 243
1. scan values of x,n
2. take ‘p’ to generate the terms x1, x2, x3 … one by one in each cycle
3. initialize p=x1
4. repeat following instructions for n times
print ‘p’ value
i
p = p*x // to generate next term x value
5. stop
void main()
{ int n, x, p, sum=0, i=1;
printf(“enter x , n values :”);
scanf(“%d%d”, &x, &n);
1
p=x; // first value of ‘p’ is x
while(i<=n) // loop to add up to ‘n’ terms
{ printf(“ %d ”, p);
i
p=p*x; // to generate next x value
i++;
}
}

Finding sum of series of x1+x2+x3+x4+ ….xn (without using power function)


ip: 3 5 (x=3, n=5)
op: 3+9+27+81+243  363
1. scan x, n values
2. Take ‘sum’ to store sum of all terms
3. take ‘p’ to generate the terms x1, x2, x3 … one by one in each cycle
4. Initialize sum=0 and p=x1
5. Repeat following instructions for ‘n’ times
 sum = sum + p; // adding term by term to sum
i
 p = p*x // to generate next term x
6. print(sum)
7. stop
C-Family 87 Loops

void main()
{ int i, n, sum, x, p;
printf(“enter x , n value :”);
scanf(“%d%d”, &x, &n);
sum=0; i=1;
1
p=x; // first value of p is x
while(i<=n) // loop to add up to ‘n’ terms
1 2 3
{ sum=sum + p; // adding x , x , x … to sum
i
p=p*x; // to generate next x value
i++;
}
printf(“\n sum=%d”, sum);
}

Finding xy value based on given input values (x,y)


ip: 2 3
op: 8 (2*2*2)
1. scan input values to x, y
product = product * x;
2. take variable ‘p’ to store value of x*x*x … for y-times
3. initialize ‘p’ with 1 to clean the garbage
4. now repeatedly multiply ‘x’ to ‘p’ for y-times to get xy value
5. print(p) product = 1*2
6. stop
void main()
{ int i, x, y, p; product = 1*2*2
printf(“enter x , y values :”);
scanf(“%d%d”, &x, &y);
p=1; product = 1*2*2*2;
while(i<=y) // loop to multiply y-times
{ p=p*x;
i++; product = 8, if n=3
}
printf(“\n x^y =%d”, p);
}

Printing values 1/2, 2/3, 3/4, ……. n/n+1


op: 0.5 .66 .75 0.8 ….
step1: take ‘i’ as loop variable with 1.
step2: print i/(i+1)
step3: increment i by 1
step4: repeat step2 & step3 until i<=n
step5: stop
void main()
{ int i=1, n;
float p;
scanf(“%d”, &n);
while( i<=n )
{ p=i/(i+1);
printf(“%f “, p );
i++;
}
}
C-Family 88 Loops

Finding sum of series of 1/2 + 2/3 + 3/4 + ……. n/n+1


ip: n=5
op: sum=3.55 [ 0.5 + 0.66 + 0.75 + 0.8 + 0.83  3.55 ]
Like above program, but just adding all terms.
void main()
{ int i,n; float sum, p;
printf(“enter n value :”);
scanf(“%d”, &n);
sum=0; i=1;
while(i<=n) // loop to add ‘n’ terms
{ p=(float) i/(i+1); // converting ‘i’ to float
sum = sum + p;
i++;
}
printf(“\n sum=%f”, sum);
}
 The expression i/(i+1) always gives the result zero, as ‘i’ and ‘i+1’ are integers
 If both operands are integers then result will be an integer
 If anyone operand is float type then result will be float
 Therefore here numerator ‘i’ converted to float by casting as “(float)i”

Printing values 1/2 , 3/4 , 5/6 , ……. 2N-1/2N


op: 0.5 0.75 0.83 0.87 ….
step1: take ‘i’ as loop variable
step2: print i/(i+1)
step3: increment i by 2 to get next odd number
step4: repeat step2 & step3 until i<2*n
step5: stop
void main()
{ int i, n; float p;
printf(“enter n value:”);
scanf(“%d”, &n);
i=1;
while( i<2*n)
{ p = (float) i/(i+1);
printf(“%f “, p );
i=i+2;
}
}
Printing values of 1, -2, 3, -4, 5, -6, 7, …N times
1. take a loop variable ‘i’ with values 1 to N in the loop
2. take a variable ‘s’ with 1, and change its value alternatively to +1, –1, +1, –1,… in the loop.
for this multiply ‘s’ with –1 in the loop, so that sign changes alternatively.
3. print s*i value in the loop, then s*i value are: 1, -2, 3, -4, 5, …
In the loop, the values of ‘i’ and ‘s’ are
i  1, 2, 3, 4, 5, 6, 7, …
s  1 , -1, 1, -1, 1, ,-1, 1, …
s*i  1, -2, 3, -4, 5,
void main()
{ int i, s, n;
printf(“enter n value:”);
scanf(“%d”, &n);
C-Family 89 Loops

i=s=1;
while( i<=n)
{ printf(“%d “, s*i );
s = -1*s;
i++;
}
}

Printing list of factorials as given below


ip: 4
op: !1  1
!2  2
!3  6
!4  24 …
1. take a variable ‘fact’ to store factorial value(s)
2. take loop variable ‘i’ to repeat for ‘n’ terms
3. initialize fact=i=1
4. repeat following instructions for ‘n’ terms
 print fact value
 increment ‘i’ by 1
 multiply incremented ‘i’ value to the ‘fact’ to generate next factorial value
5. stop
void main()
{ long int n,i, fact;
printf(“enter n value :”);
scanf(“%ld”, &n);
i=fact=1;
while(i<=n)
{ printf(“\n ! %ld  %ld”, i, fact);
i++;
fact=fact*i;
}
}

Printing list of odd factorials


ip: 4
op: !1  1
!3  6
!5  120
!7  5040 …
Logic: to get odd factorial values, multiply fact with 2*3, 4*5, 6*7 (two terms)… in every iteration
void main()
{ long int n,i, fact;
printf(“enter n value :”);
scanf(“%ld”, &n);
i=fact=1;
while(i<2*n)
{ printf(“\n ! %ld  %ld”, i, fact);
i=i+2; // to get next odd number
fact=fact*(i-1)*(i); // to get next factorial value
}
}
C-Family 90 Loops

X1/1! + X2/2! + X3/3!..... N times [do not use pow() fn]


ip: x=3, N=5
op: sum= 17.4 [3.0 + 4.5 + 4.5 + 3.37 + 2.02  17.4]
1. Take a loop variable ‘i’, its value ranges from 1 to n.
2. Take a variable ‘p’ and generate its values to x1, x2, x3, x4, x5, …
for this multiply ‘x’ to the ‘p’ to get next value.
3. Take a variable ‘fact’ and generate its values to 1!, 2!, 3!, 4!, …
for this multiply ‘i’ to the ‘fact’ to get next factorial value. (pre-increment ‘i’ before this operation)
4. Take sum and add all these ‘p/fact’ value to sum, this is like sum=sum + (float)p/fact;
void main()
{ int i, fact, x, p, n;
float sum;
printf(“enter x n value :”);
scnaf(“%d%d”,, &x, &n);
i=1, fact=1, sum=0, p=x;
while( i<=n)
{ sum = sum + (float) p/fact;
p=p*x;
i++;
fact=fact*i;
}
printf(“sum = %f”, sum);
}

Finding sine series value: sin(x) x1/1! - x3/3! + x5/5! – x7/7! … up to 10 terms
ip: x=3, N=5
op: sum=0.1453 [ (3.0) + (-4.5) + (2.025) + (-0.4339) + (0.05424) ]
void main()
{ long int i, fact, sign;
float x, sum, p;
printf(“enter sign(x) value :”);
scanf(“%f”, &x);
i=fact=1; p=x; sign=1; sum=0;
while(i<20) // adding 10 terms ( not 20, because ‘i’ is incrementing by 2)
{ sum=sum+ sign* p/fact;
sign=-1*sign; // changing ‘sign’ for next term
i
p=p*x*x; // getting next x value
i=i+2; // getting next odd number
fact=fact*(i-1)*(i); // getting next factorial value
}
printf(“\n sum =%f”, sum);
}

Finding whether a given number is power of 2 or not


ip: 8 (23) ip: 10
op: yes op: no
1. take N as input variable
2. take variable P and generate its values to 20, 21, 22, 23, …
3. now repeatedly compare P with N until P<N
4. after completion of loop, if P==N print(“yes”); or else print(“no”);
5. stop
C-Family 91 Loops

The comparisons is as follows, say input value N is 8


P<N
-----------------------------
At cycle1 1<8 (true)
At cycle2 2<8 (true)
At cycle3 4<8 (true)
At cycle4 8<8 (false, stop)
void main()
{ long int N, product;
printf(“enter N value :”);
scanf(“%ld”, &N);
product=1;
while(product<N)
0 1 2 3
product=product*2; // p = 2 , 2 , 2 , 2 …
if(product==N) printf(“yes”);
else printf(“no”);
}
Logic2: try yourself
1) cut down N=N/2 as long as N is even
2) finally, after loop, if N==1 then say “yes”, or else say “no”
for example, if N=20 then N=N/2 is 20, 10, 5 ( here N==1 is false so print “no”)
for example, if N=16 then N=N/2 is 16, 8, 4, 2, 1 ( here N==1 is true so print “yes ”)

Printing prime factors of given N (The product of factors should be equal to N)


ip: N=100
op: 2 2 5 5
step1: divide N with first possible factor 2, here the number 2 is prime.
if N is divided with 2 then print(2) as prime factor and decrement N to N/2.
step2: repeat step1 as long as ‘2’ divides the N.
step3: Now take 3 and proceed as long as 3 divides the N, as said in step1. Of course ‘3’ is also prime.
step4: Now take 4, we know 4 is not prime, but 4 will not be divided the N because we already did with 2
before, so there should not be 2 multiples left behind in N. [you may ask one question, why to divide
with 4 when it is not prime, because it is difficult to take only primes, taking only primes is another
problem. So continuously/blindly divide the N with 2,3,4,5,6,7,8,9 ….
step5: repeat this process until N>1
i=2;
while(N>1)
{ if( N%i==0)
{ printf(“%d “, i);
N=N/i;
}
else
i++;
}
C-Family 92 Loops

Program to print prime factors of given N. ( without duplicates)


This process is same as above program but it prints factors only once. ( not like 2, 2, 5, 5)
ip: N=100
op: 2 5
logic: In loop cycles, previously printed factor is not equal to current factor then it prints it. Here extra
variable ‘prev’ is taken to store previous prime factor of ‘i’ (for first time, take prev=1 )
i=2; prev=1;
while( N>1 )
{ if( n%i==0 )
{ if( prev != i ) // if previous printed factor is not equal to current factor then print
{ printf(“ factor %d “, i);
prev=i; // take this current ‘i’ value as ‘prev’ for next cycle
}
n=n/i ;
}
else i++;
}
C-Family 93 Loops

Printing each digit separately in a given number (N) [ printing right to left ]
ip: 2345 ip: 724
op: 5,4,3,2 op: 4, 2, 7
Logic: extract digit by digit from N, and print on the screen, given below logic extracts the digits from right-
to-left in N, and prints on the screen
step1: divide N with 10 and collect the remainder(s), the remainder is always the last digit of N, when it is
divided with 10 (lastDigit=N%10)
step2: now print the last digit
step3: to get next digit of N, now remove current last digit from N by doing N=N/10
step4: repeat step-1, step-2, step-3 until N>0
Let the input is 2345 and program prints as given below table

Iteration-1 10 ) 2345 (234


N is 2345 2340 void main()
----------- {
5 printf(“5”) int N , lastDigit;
printf(“enter N value :”);
scanf(“%d”, &N);
Iteration-2 10) 234 (23 while(N>0)
after N=N/10 230 {
N is 234 ----------- lastDigit=N%10; // gives last digit of N
4 printf(“4”)
printf(“%d,”, lastDigit ); // printing lastDigit

Iteration-3 10) 23 ( 2 N=N/10; // removes last digit of N


after N=N/10 20 }
N is 23 ----------- }
3 printf(“3”)

Iteration-4 10 ) 2 (0
N is 2 0
----------
2 printf(“2”)

N is 0
( stop ) 0 (stop)

Finding sum of all digits in a given number (N)


ip: 2345
op: 2+3+4+5  14
step1: take ‘sum’ to store sum of all digits
step2: take ‘N’ to store input value
step3: repeat following instructions until N>0
 get the last digit(d) of N by dividing 10, the remainder will be last digit [ lastDigit=N%10 ]
 add lastDigit to sum [ sum = sum + lastDigit ]
 remove lastDigit from N, for this divide N with 10 and collect the quotient to N [ N=N/10 ]
step4: print(sum)
step5: stop
C-Family 94 Loops

void main() The variable values in every iteration is as follows


{ int N, sum, d; d=N%10 sum=sum+d N = N / 10
printf(“enter n value :”);
st
scanf(“%d”, &N); After 1 cycle 2345%10 5 0+5 5 2345/10 234
sum=0; nd
After 2 cycle 234%10 4 5+4 9 234/10 23
while(N>0) rd
After 3 cycle 23%10 3 9+3 12 23/10 2
{ d = N%10; // taking last digit of n
th
sum=sum + d; // adding digit to sum After 4 cycle 2%10 2 12+2 14 2/10 0
N=N/10; // removing last digit
}
printf(“\n sum of digits = %d”, sum);
}

Finding whether the given number (N) contains a digit 5 or not?


ip: 2357 ip: 2346
op: yes, 5 is exist op: no, 5 is not exist
without deep study on logic, one may write the program in wrong way as
void main()
{ int N, d;
scanf(“%d”, &N);
while(N>0)
{ d=N%10; // gives last digit of N
if(d==5)
printf(“ 5 exist”);
else
printf(“5 not exist”);
N=N/10; // removing last digit of N
}
}
ip: 2357
op: 5 not exist, 5 exist, 5 not exist, 5 not exist ( many outputs and wrong )
Whether “5 exist or not” can be conformed only after comparing with all digits in N, but here, in this loop,
after every digit comparison immediately the output is shown on the screen. Therefore, the result is
displayed 4 times wrongly. Solution is, use Boolean logic, compare digit by digit until ‘5’ is found or N>0.
If 5 is found in loop, then set bool=1 & stop, after looping, show the result based on bool.
step1: first of all, assume, the digit ‘5’ is not exist in N, so initialize bool=0
step2: repeat following instructions until N>0
 get the last digit in N [ d=N%10 ]
 if d==5 then keep the result-status as found (bool=1) and stop the process
 if not 5, then go back and compare with next digit, before going back, remove the current last
digit by doing N=N/10.
step3: print the result, based on the bool value
if(bool==1) print(“ found”);
else print(“not found”);
step4: stop.
void main()
{ int N, d, bool;
printf(“enter N value :”);
scanf(“%d”, &N);
bool=0; // let us assume digit ‘5’ not exist in N.
C-Family 95 Loops

while(N>0)
{ d = N%10;
if(d==5)
{ bool=1; // now the digit ‘5’ is found
break;
}
N=N/10;
}
if(bool==1) printf(“the digit 5 is exist”);
else printf(“the digit 5 is not exist”);
}

Finding sum of even and odd digits separately in a number (N)


ip: 23456
op: evens sum: 2+4+6 12
odds sum: 3+5  8
* Take evenSum , oddSum to store sum of even & odd digits separately
step1: take N and scan input to it
step2: repeat following instructions until N>0
 get last digit of N by dividing with 10 and collect the remainder [ d=N%10 ]
 if d is even then add to evenSum otherwise add to oddSum
 remove the current last of digit of N [ N=N/10 ]
step3: print(evenSum, oddSum)
step4: stop
void main()
{ int N, evenSum, oddSum, d;
printf(“enter N value :”);
scanf(“%d”, &N);
evenSum=oddSum=0;
while(N>0)
{ d=N%10; // gives last digit of N
if( d%2==0) // checking digit is odd or even
evenSum+=d;
else
oddSum+=d;
N=N/10; // removing current last digit from N.
}
printf(“\n even sum = %d, odd sum = %d”, evenSum, oddSum);
}

Counting no.of digits in a given number (N)


ip: 234 ip: 45
The variable values in every cycle as
op: count=3 op: count=2
digitsCount++ N=N/10
 take variable digitCount to count digits in a given N
 Remove the last digit of N by doing N=N/10 and count Initially 0 2345
st
it as one digit by incrementing digitCount After 1 cycle 1 234
Repeat this step until ‘N’ becomes zero nd
After 2 cycle 2 23
 Print output ‘digitCount’ rd
After 3 cycle 3 2
th
After 4 cycle 4 0
C-Family 96 Loops

void main()
{ int N, digitCount=0;
printf(“enter N value :”);
scanf(“%d”, &N);
while(N>0)
{ N=N/10; // removing last digit from N.
digitCount++; // counting the digits
}
printf(“no of digits = %d”, digitCount);
}

*Finding given number (N) is Armstrong or not?


The number 153 is Armstrong, as sum of cubes of all digits is equal to N: 13+53+33  1+125+27  153
ip: 153 ip: 234
op: Armstrong op: not Armstrong
void main()
{ int N, sum, rem, temp;
printf(“enter N value :”);
scanf(“%d”, &N);
sum=0; temp=N;
while(N>0)
{ rem=N%10;
sum = sum + (rem*rem*rem); // adding sum of cubes of digit
N=N/10;
}
if(sum==temp)
printf(“ Armstrong”);
else
printf(“not a Armstrong”);
}
The instruction N=N/10 makes the N to zero after completion of loop. There by, the original value of N is
missed after looping. So it is saved in ‘temp’ before looping and checked with ‘sum’ to print result.

*Finding reverses of a given number (N)


ip: 234 ip: 4673
op: 432 op: 3764
 Let us assume the variable ‘rev’ already has a value 23 at the moment (rev=23)
 Now 4 is inserting at the end of ‘rev’ by doing “rev=rev*10+4”  23*10+4  234
 In this way, the digits are extracted one by one from N, and added at the end of ‘rev’.
step1. Take N and scan input it
step2. Take ‘rev’ to hold reverse number of N. Initialize ‘rev’ with zero
step3. Repeat following instructions until N>0
 get the last-digit(D) of N
 Insert digit D at the end of ‘rev’, this is as rev=rev*10+D;
 N=N/10;
step4. print(rev)
step5. Stop
void main()
{ int N, rev=0, digit;
printf(“enter N value :”);
scanf(“%d”, &N);
C-Family 97 Loops

while(N>0)
{ digit=N%10;
rev=rev*10+digit; // adding digit at end of ‘rev’
N=N/10;
}
printf(“reverse = %d”, rev);
}
Let input is 2345, then the instruction “rev=rev*10+digit” in every iteration is as follows
Let N=2345 d=n%10 rev = rev*10+digit N=N/10
st
After 1 cycle 2345%10  5 0*10+5  5 234
nd
After 2 cycle 234%10  4 5*10+4  54 23
rd
After 3 cycle 23%10  3 54*10+3  543 2
th
After 4 cycle 2%10  2 543*10+2  5432 0

Finding whether a given number (N) is palindrome or not


If the number and its reverse are equal then it is said to be palindrome
ip: 234 ip: 434
op: not a palindrome op: palindrome
step1: find the reverse of given number(N) as said in above program
step2: after loop, compare reverse-value with N and print output.
void main()
{ int N, rev=0, digit, temp;
printf(“enter N value :”);
scanf(“%d”, &N);
temp=N; // saving ‘N’ value in temp
while(N>0)
{ digit=N%10;
rev=rev*10+digit;
N=N/10;
}
if(temp==rev) printf(“ given number is palindrome”);
else printf(“given number is not palindrome”);
}
Finding the biggest digit of a given number (N)
ip: 5394 ip: 5374
op: big= 9 op: big= 7
Take a variable ‘big’ and compare it with all digits of input N, if any digit is bigger than the ‘big’ then copy to
big and finally print the big. Initially the big is zero.
void main()
{ int N, digit, big=0; Let us see, how digits are compared and assigns to big
scanf(“%d”, &N); If(big<digit)
d=N%10 N=N/10
while(N>0) big=digit
st
{ digit=N%10; After 1 cycle 2375%10  5 0<5  5 2375/10  237
if(big < digit ) nd
After 2 cycle 237%10  7 5<7  7 237/10  23
big=digit;
rd
N=N/10; After 3 cycle 23%10  3 7<3  7 23/10  3
} th
After 4 cycle 2%10  2 7<2  7 2/10  2
printf(“\n big digit = %d”, big);
}
C-Family 98 Loops

Finding left most odd digit in a given number (N)


Note: If odd digit is not found then show an error message called “odd digit not found”
ip: 2345 ip: 2468
op: 3 op: odd digit not found
Logic: extract digit by digit in N, if any odd digit found then store into a variable called ‘temp’ and finally
print it. Initially take ‘temp’ with ‘0’ as it indicates no odd exists in N. Later replace ‘0’ by odd if found.
void main()
{ int N, rem, temp=0;
printf(“enter N value :”);
scanf(“%d”, &N);
while(N>0)
{ rem=N%10;
if(rem%2==1)
temp=rem; // if odd found then store into temp
N=N/10;
}
if(temp=0) printf(“odd digit not found”);
else printf(“\n odd digit = %d”, temp);
}

Printing each digit of a number in English words


This program separates all digits in a given number and then prints all from left to right in a number.
Here it prints each digit in English words.
ip: 2345 ip: 724
op: two three four five op: seven two four
 It is hard to get digits from left-to-right of N; because, the input N may have any number of digits entered
by the user (not exactly 4-digits as above shown in first input)
 For example to get the first digit ‘3’ from 3456, it has to be divided by 1000, similarly to get 7 from 765,
it has to be divided by 100. According to number of digits in N, it has to be divided with 1000/100/10/1
to generate such value, take ‘P’ and generate its value to 10no.of digits of n-1 , for this, the code is
P=1;
no.of digits of n-1 ,
while(N/P>9) // loop to generate P value to 10
P=P*10;
After above loop, the value of ‘P’ generates according to no.of digits in N.
Suppose, if N has 3-digits then P generates as 100, if N has 4-digits then P generates as 1000.
step1: Take N for input variable, scan input to N.
step2: Take variable P and generate its value to 10no.of digits of(n)-1 (as said above)
step3: Repeat following instructions until P>0
 Divide the N with P and get the quotient(s) one by one in each cycle
q=N/P;
 Print quotient in English words
if(q==0) printf(“zero”); // better to use ‘switch’ control statement
else if(q==1) printf(“one”);
else if(q==2) printf(“two”);
---
else printf(“nine”);
 Remove first digit in N, so that we can get next digit easily for next cycle
N=N%P;
 Decrement P by 10
P=P/10;
C-Family 99 Loops

Let the input is 2345 and program prints as given below table
N=2345, P=1000 Program code is
p) N (q void main()
Iteration1 1000)2345(2 printf(“two”) { int N, q, P=1;
N2345 2000 printf(“enter N value:”);
P1000 ----------- scanf(“%d”, &N);
345
count-1
Iteration2 while(N/P>9) // generating ‘p’ to 10
N345 100) 345 (3 printf(“three”) { P=P*10;
P100 300 }
-----------
45 while(P>0) // printing each digit in English words
{ q=N/P; // gives first digit of N as quotient
switch(q)
Iteration3 10) 45 (4 printf(“four”)
{ case 0: printf(“zero”); break;
N45 40
case 1: printf(“one”); break;
P10 -----------
case 2: printf(“two”); break;
5

case 9: printf(“nine”);
Iteration4 1 ) 5 (5 printf(“five”) }
N5 5 N=N%P;
P1 ---------- P=P/10;
0 }
N0 Stop }

Printing decimal value from a given binary input


ip: 1101 ip: 1111
op: 13 op: 15
1. multiply all digits of N with 20 21 22 23… from right-to-left
2. The sum of such all products forms a decimal number.

3 2 1 0
1 1 0 1  1*2 + 1*2 + 0*2 + 1*2  13
3 2 1 0
2 2 2 2 8 + 4 + 0 + 1

Iteration-1 10 ) 1101 ( 110 #include<math.h>


N1101 1100 void main()
----------- {
0
1 1*2 long int rem, N, sum, i;
printf(“enter any binary number :”);
Iteration-2 10) 110 ( 11 scanf(“%ld”, &N);
sum = i = 0;
N110 110
while(N>0)
-----------
1 { rem=N%10;
0 0*2
sum=sum + rem * pow(2,i);
i++;
Iteration-3 10) 11 ( 1
N=N/10;
N11 10
}
-----------
2 printf(“\n decimal number = %ld”, sum);
1 1*2
}
Iteration-4 10) 1 ( 0
N1 0
----------
3
1 1*2
N0
Stop
C-Family 100 Loops

Printing binary of a given decimal value


ip : 13 ip: 10
op : 1101 op: 1010
1. let us suppose the given number is 13 (N=13)
2. to get binary equivalent of 13, divide N repeatedly by 2 until N>0.
3. collect the remainders obtained in the division
4. this collection of remainders from bottom to top forms a binary as: 1101

2 13
2 6- 1
2 3- 0
3 2 1 0
2 1- 1 10 * 1 + 10 * 1 + 10 * 0 + 10 * 1
0- 1 L  R

The remainders, we get one by one must be inserted in first position of ‘sum’ value. (‘sum’ holds output)
For example, the remainders of 13 are: 1, 0, 1, 1 (from top to bottom). These remainder should be inserted
in ‘sum’ as 1 01  101  1101
step1: multiply each reminder with 10i and sum up
step2: the binary number formed as 1000*1+100*1+10*0+1*1  1101
void main()
{ int N, i, rem;
long int sum;
printf(“enter any decimal number :”);
scanf(“%d”, &N);
sum=0; i=0;
while( N>0 )
{ rem=N%2;
sum=sum + rem*pow(10,i); // include math.h file for pow() fn.
N=N/2; i++;
}
printf(“\n binary number = %d”, sum);
}

Printing hexadecimal value from a given number


ip: 370359 ip: 159
op : 5A6B7 op: 9F
process: repeatedly divide the N with 16, and collect(insert) the remainders into variable ‘sum’
step1: R=N%16
step2: insert this R into sum, this is like “sum=sum*100+R” //here R can be 2-digit number, so multiply with 100
step3: cut down N to N/16
repeat above 3 steps until N>0
Let N=370359

16 370359
16 23147  7 0*100+7  7
16 1446  11 (B) 7*100+11  711
16 90  6 711*100+6  71106
16 5  10(A) 71106*100+10  7110610
 5 7110610*100+5  07 11 06 10 05
C-Family 101 Loops

The hexadecimal value collected in ‘sum’ as  07 11 06 10 05 (7B6A5)


but output should be displayed in reverse form as  5A6B7.
to print this number in hexadecimal form, extract 2-digits at a time right-to-left from ‘sum‘ and print.
Use two loops, one to generate ‘sum’ and second to print in hexadecimal form.
void main()
{ long int N, sum, rem;
printf(“enter N value:”);
scanf(“%ld”, &N);
sum=0;
while(N>0)
{ rem=N%16;
sum=sum*100+rem;
N=N/16;
}
// after above loop, the hexadecimal collected in ‘sum’ in reverse format, now printing on the screen
while(sum>0)
{ rem=sum%100;
if(rem<10)
printf(“%d”, rem);
else
printf(“%c”, ‘A’+ rem%10 ); // ‘A’+1  ‘B’ , ‘A’+2  ‘C’
sum=sum/100;
}
}

Printing first 10 terms of Fibonacci series


The first two terms in this series are 0,1 and remaining terms are generated by adding previous two terms.
This is endless series, but here we are printing first 10 terms
op: 0 1 1 2 3 5 8 13 21 34 55….
step1: Let us take first two terms are X=0, Y=1;
step2: Print the term X.
step3: Generate next term by adding X+Y to ‘new’
step4: Now advance X to Y and Y to ‘new’ for next cycle
step5: Repeat step2 to step4 for 10 times
Let us see how the X,Y are advancing in every iteration of loop

Iteration-1 0 1 1 2 3 5 8…
X Y new=X+Y

Iteration-2 0 1 1 2 3 5 8…
X Y new=X+Y

Iteration-3 0 1 1 2 3 5 8…
X Y new=X+Y
C-Family 102 Loops

void main()
{ int X, Y, new, i;
X=0; Y=1; i=1
while(i<=10)
{ printf(“%d\t”, X);
new=X+Y; // generating next fibo number
X=Y; // advancing X to Y and Y to new
Y=new;
i++;
}
}

Finding given number is in Fibonacci series or not?


void main()
{ int X, Y, new, i, searchValue;
printf(“enter number to search in Fibonacci series :”);
scanf(“%d”, &searchValue);
X=0; Y=1;
while(searchValue<X)
{ new=X+Y; // generating next number
X=Y; // advancing X to Y and Y to new
Y=new;
}
if( searchValue==X) printf(“element found”);
else printf(“element not found”);
}

Finding GCD of two numbers


ip: 12 18
op: gcd = 6

step1: Let X , Y are input values


step2: Divide Y with X and collect the remainder to R (don’t care if X<Y)
step3: If remainder(R) is zero then stop and print X as GCD
step4: If R is not zero then take X as Y and R as X for next cycle and continue this process until R is zero.
Let X=12, Y=18

void main()
{ int x , y , rem;
printf(“enter x, y values :”);
x y x y stop scanf(“%d%d”, &x, &y);
12 ) 18 ( 1 6 ) 12 ( 2 while(1)
12 12 { rem=y%x;
6 if(rem==0)
0 break;
y=x; // take x as y
x=rem; // take rem as x
}
printf(“\n GCD = %d”, x);
}
C-Family 103 Loops

Finding LCM of three numbers


ip: 12 18 45
op: 180
1. Let X, Y, Z are three input numbers
2. Start finding LCM of three by dividing with first factor 2
3. Now divide each X, Y, Z with 2
4. If any X, Y, Z divided with 2 then take ‘2’ as factor in LCM. (LCM=LCM*2)
and cut down all divided numbers to its quotient obtained in the division.
For example, if X is divided with 2 then cut down X=X/2
5. Now repeat step-4 as long as ‘2’ divide the any of X, Y, Z
6. If 2 is no longer divide the X,Y,Z, then next try with next factors 3, 4, 5…etc,
Repeat this process until any of these (X, Y, Z)>1. For example, while(X>1 || Y>1 || Z>1) {….}
Let the numbers are 20, 15, 35 and following table shows how …

2 20 15 35
2 10 15 35
2, 3 5 15 35

3,4,5 5 5 35
5,6,7 1 1 7
1 1 1

void main()
{ int x,y,z, lcm=1, i=2, bool;
printf(“enter 3 numbers :”);
scanf(“%d%d%d”, &x, &y, &z);
while( x>1 || y>1 || z>1) // repeat until all become 1.
{ bool=0;
if( x%i==0 )
{ bool=1;
x=x/i;
}
if( y%i==0 )
{ bool=1;
y=y/i;
}
if( z%i==0 )
{ bool=1;
z=z/i;
}
if(bool==1) lcm=lcm*i; // then take ‘i’ as factor
else i++; // if no number divisible then try with next number(s)
}
printf(“\n lcm = %d”, lcm);
}
C-Family 104 Loops

Incrementing given date by N days


Note: here Date increments by 1 in each cycle for n times
1. Take three variables for day, month, year to hold the given Date
2. Scan the Date
3. Repeatedly increment ‘day’ in a Date
4. If ‘day’ is reached to end of month then update ‘day=1’ and ‘month++’
5. If ‘month’ is reached to end of year then update ‘month=1’ and ‘year++’
6. This process continues for N times
void main()
{ int d, m, y, i=0, N;
printf(“ente date :“);
scanf(“%d%d%d”, &d, &m, &y);
printf(“enter how many days to increment:”);
scanf(“%d”, &N);
while( i++ < N )
{ d++; // incrementing day by 1-day
if(m==2)
{ if( y%4!=0 && d>28 || d>29 ) // if day reached to end of February
{ d=1;
m++;
}
}
else if((m==4 ||m==6 || m=9 || m==11) && d>30)
{ d=1; // if day reached to 30-days month ending like april, june,sept…
m++;
}
else if( d>31 ) // if day reached to 31-days month’s ending
{ d=1; m++;
if(m==13) // if date reached to end of year
{ m=1; y++;
}
}
} // end-while
printf(“\n date after incrementing = %d/%d/%d”, d, m, y);
} // end-main

Finding difference of two dates in days


1. scan two dates date1(d1,m1,y1), date2(d2,m2,y2) from keyboard
2. if( date1>date2) then swap them.
3. here every time in the loop, the date1 is incrementing until it reaches date2
4. the ‘count’ increments by 1 in each cycle in loop to count the no.of days between 2-dates.
void main()
{ int d1, m1, y1, d2, m2, y2, count=0;
scan (d1,m1,y1)
scan (d2,m2,y2)
while(d1<d2 || m1<m2 || y1<y2) // loop to repeat until date1<date2
{ // incement date1 (d1,m1,y1) by 1-day, for this write above program logic here
count++; // counting no.of days between dates
}
printf(“\n no.of days between 2 dates = %d”, count);
}
C-Family 105 for- loop

The for loop


The structure of while-loop is simple and used when loop construct contains only condition part, however,
most of the times, loop constructs involve initialization, incrementing or decrementing. In such case, for-
loop is more suitable than any other loop. For-loop consists of three expressions in its header: initialization,
test condition, and incrementing of loop variable.
When your loop to be repeated 10 or N times then for-loop is the choice otherwise while-loop is choice.
Remember, when your loop has parameters like i=1 and i++ then for-loop is the choice.
The For-loop is more flexible as it gives complete idea about the loop such as initial value, condition and
increment. It is the programmer’s choice, which loop to use when and where and it is fairly depends on his
convenience. Some people say for-loop is faster than while-loop, actually same machine code is generated
for both loops

intialization
Syntax for for-loop is
for(initialization; test-condition; increment)
{ instruction 1; condition
false
instruction 2; increment ntion
true
----
---- Instruction 1
instruction N; Instruction 2
} ---
instructionN
instruction N+1;
instruction N+2;
----
----
Instruction N+1
Instruction N+2
---

This loop repeats as long as the condition is true, first it enters into loop-body through initialization-part.
From 2nd cycle, the control enters through increment/decrement part. This is as given below

for(initialization; condition; increment)


{ for ( i=1; i<11; i++ )
instruction-1; {
instruction-2; printf(”hello1”);
----
---- printf(”hello2”);
instruction-n;
} printf(”hello3”);
Comes out when }
Comes out when
the condition fails
the condition fails

Note: for-loop header must have only two semicolons, if not, it is an error.
Let us have some examples,
C-Family 106 for- loop

Loop to print 1 to 10 numbers Same code in while loop


for(i=1; i<=10; i++) i=1;
{ while( i<11)
printf(“%d “, i ); { printf(“%d “, i );
} i++;
}
Loop to print 5 multiples for 10 times Loop to print 10 to 1 numbers
for(i=5; i<=50; i=i+5 ) for(i=10; i>0; i--)
{ {
printf(“%d “, i ); printf(“%d “, i );
} }

loop to print odd numbers from 1 to 100 loop to print odds from n to 1.
for(i=1; i<100; i=i+2) for(i=n; i>0; i--)
{ { if( i%2==0)
printf(“%d “, i ); printf(“%d “, i );
} }

eg) loop with more initializations


we can initialize more than one variable in the loop header, in that case use comma (,) operator to separate
them. (do not use semi-colon)
for( i=1 , j=2, k=3; ----- ; ----- )
{
separate by coma (not semicolon)
}
eg) loop with more increments or decrements
we can increment/decrement more than one variable in header, but use comma operator to separate them
for(---------- ; ---------; i++ , j=j+2 , k-- )
{
separate by coma (not semicolon)
}
eg) loop with more relational conditions in its part
logical operators are used to combine two or more relations
for( ----; i<10 && j<20; ----)
{
} use logical operators to combine relations
eg) infinite loop
for( ; ; ) // If three expressions are empty then compiler take it as infinite loop, like while(1) { … }
{
}
eg) infinite loop // like while(1){…}, the for loop can be made as
for( ; 1 ; )
{
}
C-Family 107 for- loop

eg) all the three parts of loop header may not present, we can avoid any part just by leaving it blank.
However, the two semicolons must present as they indicates the separation of three parts.

void main() void main()


{ int i=1; { int i;
for( ; i<11 ; i++) for( i=1; i<11; )
{ { printf(“%d “, i);
printf(“%d “, i); i++;
} }
} }
i=1; i=1;
for( ; i<11 ; ) while( i<11)
{ printf(“%d “, i ); { printf(“%d “, i);
i++; i++;
} }
this structure is same as while-loop

Displaying natural numbers between two given limits


ip: 23 45
op: 23 24 25 ….45
void main()
{ int lower , upper , i ;
printf(“Enter lower & upper limits :”);
scanf(“%d%d”, &lower, &upper);
for(i=lower; i<=upper; i++)
{ printf(“%d “, i);
}
}
Displaying factors of a given number
ip: 18
op: 1 2 3 6 9 18
Logic: User may enter any input value, to find factors of such unknown value, divide N with each number
from 1 to N and print factor when it is divided.
void main()
{ int N, i ;
scanf(“%d”, &N);
for(i=1; i<=N; i++)
{ if( N%i==0) // if i divided the N then print ‘i’ as factor
printf(“%d “, i);
}
}
Displaying small factor of a given number(N) (exclude 1 as factor)
Divide N with 2, 3,….N, the first divisible factor is the small factor then stop the loop and print it.
for(i=2; N%i!=0; i++) // loop stops when ‘i’ divides the N.
{ // empty loop
}
printf(“%d “, i);
C-Family 108 for- loop

Finding given number is prime or not?


ip: 18 ip: 17
op: “prime” op: “not prime”
Logic: As we know prime numbers does not have factors except 1 and itself.
So check N by dividing from 2 to N/2; if anywhere divides then print “not prime” otherwise “prime”
void main()
{ int n,i,bool;
printf(“Enter number:”);
scanf(“%d”, &N);
bool=1; // let N is prime
for(i=2; i<=N/2; i++)
{ if( N%i==0)
{ bool=0;
break;
}
}
if(bool==1) printf(“prime”);
else printf(“not prime“);
}

Printing uppercase alphabets and its ASCII values


op: upper case alphabets ( A B C D E F G …. Z )
The ASCII values are: 65 66 67 68 69 ….
void main()
{ char ch;
printf(“\n upper case alphabets :”);
for (ch=’A’; ch<=’Z’; ch++) or // for(i=65; i<=90; i++)
printf(“%c”,ch); printf(“%c “, ch );
printf(“\n the ASCII values are:”);
for (ch=’A’; ch<=’Z’; ch++)
printf(“%d”,ch);
}
In the above program, the variable ‘ch’ internally (in memory) contains the ASCII value of characters.
Therefore, we can perform arithmetic operations like incrementing and decrementing. When ‘ch++’ is done
then it attains next character ASCII code.

Printing odd numbers form N to 1.


Scan N value, if N is even then decrement to next odd, now print(N) repeatedly until N>0
scanf(“%d”, &N);
if(N%2==0)
N- -;
for( ; N>0; N=N-2 ) // here N=N-2 is to get next odd number
{ printf(“%d “, N);
}
C-Family 109 for- loop

do-while loop
The do-while loop is quite opposite to while-loop, in case of while-loop, the condition part appears at the
top of loop-body, whereas for do-while loop, the condition part appears at bottom of loop-body.
Thus while-loop is top-test construct, and do-while is bottom-test construct.
As a result, the do-while body executes at least once irrespective of condition is true/false.

The while-loop may or may not be executed; it may fail at the beginning, at least without executing once.
But do-while loop executes at least once irrespective of condition is true/false.
This is rarely used in the programing, who wants to execute loop body at least once.
Syntax is

do
Instruction 1
{ instruction 1; Instruction 2
instruction 2; ---
instruction N
-----
----
instruction N; true
condition
} while( condition ); // bottom test-condition
instruction N+1; false
instruction N+2;
Instruction N+1
InstructionN+2
---

Some programmers dislike do-while loop because of its structure, so they always avoid with the help of
while-loop using break statement, which is as given below
while(1)
{ ----
----
----
----
if(condition) break; // bottom test-condition, now it is like do-while loop
}

Printing 1 to 10 numbers using do-while loop


void main()
{ int i=1;
do
{ printf(“%d “, i );
i++;
} while( i <= 10 ) ;
}
C-Family 110 for- loop

Printing sum of ‘n’ values using do-while


This program accepts values one by one from keyboard until last value is zero, when zero is entered then
stops scanning and prints sum of all values.
void main()
{ int n, sum=0;
do
{ printf(“enter values one by one :”);
scanf(“%d”, &n);
sum = sum+n;
} while(n!=0); // if input value is zero then program terminates
pirntf(“sum = %d”, sum);
}
Suggestion: try this program using while loop

The break and continue statements


Jumping out of loop using “break”
Loops perform a set of operations repeatedly until given condition is reached. However, in some situations,
loop need to be stopped unexpectedly when required result is attained earlier.
The break is a condition-less control statement, used to terminate the loop unexpectedly when required
result found earlier. The break throws the control out of loop-body, that is, it stops the execution of loop.
Let us see syntax and example
while (condition)
{
instruction-1;
instruction-2;
if( condition)
break;
instruction-3;
instruction-4;
...
instruction-N;
}
When the if-condition is true, the control move out of loop as shown like arrow
for example:
i=0;
while( i<20)
{ i++;
if( i==8 )
break;
printf(“%d “, i );
}
output: 1 2 3 4 5 6 7
C-Family 111 for- loop

Skipping some iterations of loop by “continue”


Sometimes, some iteration of loop need to be bypassed for some kind of data, for example, we want to
calculate rank of each passed student in a class, but if student failed then we need to skip such record.

“Continue” is also a condition less control statement, skips some instruction in the loop when it gets
executed. When continue gets executed then the control immediately transfers back to beginning of loop
and follows next cycle, so that bottom instructions are bypassed. This is as shown below

while ( condition )
{
instruction 1;
instruction 2;
if( condition )
continue;
instruction 3;
instruction 4;
instruction 5; // instructions-3 to instruction-N are bypassed by continue
----
instruction N;
}

Examples for “break” Example for “continue”


void main() void main()
{ int i; { int i;
for(i=1; i<=10; i++) for(i=1; i<=10; i++)
{ {
if(i==5) if(i==5)
break; continue;
printf(“%d “, i); printf(“%d “, i);
} }
printf(“\nend of program”); printf(“\nend of program”);
} }
output: 1 2 3 4 output: 1 2 3 4 6 7 8 9 10
end of program end of program
C-Family 112 Nested-Loop

Nested Loop construct


Construction of one loop with in another loop is known as nested loop, the inner and outer loop can have
same or different combination. For example, while-loop can be nested by for-loop. Similarly, we can nest as
many times as we want in the programming. Some examples of nested loops structures is as follows
while( -----) For( -----; -----; -----)
{ {
while(----) while(----)
{ {
---- ----
---- ----
} }
} }

for( -----; -----; -----) while( -----)


{ {
for( -----; -----; -----) for( -----; -----; -----)
{ {
----- while(----)
----- {
} ----
} ----
}
}
}

while(condition )
while(condition 1) {
{ instruction 1; instruction 1;
instruction 2; instruction 2;
….. …..
instruction k; instruction k;
for( initialization; condition; increment )
while(condition 2) {
{ instruction k+1; instruction k+1;
instruction k+2; instruction k+2;
…… ……
instruction m; instruction m;
} }
instruction m+1; instruction m+1;
instruction m+2; instruction m+2;
…... …...
instruction n; instruction n;
} }
C-Family 113 Nested-Loop

Printing following pattern(s)


345678
345678
……
10 rows
Here the pattern looks like a matrix, it is like columns and rows. We know, to display numbers in a row, we
need a loop. Similarly to display all such rows in 10 times, we need an extra loop. This extra loop is an outer
loop which repeats the inner loop 10 times.
void main()
{ int i, j;
for( i=1; i<=10; i++) // loop to print 10 rows
{
for(j=3; j<=8; j++) // loop to print 3-8 column values of each row
printf(“%d “, j);

printf(“\n”); // inserting new line after each row


}
}
Here the outer-loop is used to repeat the pattern for 10 rows and inner-loop is to print 3to8 of each row.
=======================================================================================
8 7 6 5 4 3
8 7 6 5 4 3
……..
10 rows
void main()
{ int i, j;
for( i=1; i<=10; i++) // loop to print 10 rows
{ for(j=8; j>=3; j--) // loop to print 8 to 3 column values of each row
printf(“%d “, j);
printf(“\n”); // inserting new line after each row
}
}
Here outer loop is used to repeat for 10 rows, whereas the inner loop displays numbers from 8 to 3.
========================================================================================
1 In first row, only one number presented
1 2 In second row, two numbers presented
1 2 3 In ith row, ‘i’ numbers presented
………..
10 rows
for(i=1; i<=10; i++)
{ for(j=1; j<=i; j++) // as ‘i’ increases, the number of columns increases
printf(“%d “, j);
printf( “\n”); // inserting new line after each row
}
C-Family 114 Nested-Loop

Observe the inner loop ‘j’ in each & every iteration at outer loop is
1st iteration, when i=1  for(j=1; j<=1; j++)
printf(”%d “, j); // 1

2nd iteration, when i=2  for(j=1; j<=2; j++)


printf(”%d “, j); // 1 2

3rd iteration, when i=3  for(j=1; j<=3; j++)


printf(”%d “, j); // 1 2 3

4th
iteration, when i=4 
for(j=1; j<=4; j++)
printf(”%d “, j); // 1 2 3 4
=======================================================================================

123456 for( i=6; i>=1; i--) The ‘j’ loop repeats as follows
12345 {
1234 for(j=1; j<=i; j++) for(j=1; j<=6; j++) // 1 2 3 4 5 6
123 printf(“%d “, j); printf(“%d “, j);
12 printf(“\n”);
1 } for(j=1; j<=5; j++) // 1 2 3 4 5
printf(“%d “, j);

for(j=1; j<=4; j++) // 1 2 3 4


printf(“%d “, j);

654321 for( i=6; i>=1; i--) The ‘j’ loop repeats as follows
54321 {
4321 for(j=i; j>=1; j-- ) for(j=6; j>=1; j--) // 6 5 4 3 2 1
321 printf(“%d “, j); printf(“%d “, j);
21 printf(“\n”);
1 } for(j=5; j>=1; j--) // 5 4 3 2 1
printf(“%d “, j);

for(j=4; j>=1; j--) // 4 3 2 1


printf(“%d “, j);
….

123456 The ‘j’ loop repeats as follows


23456 for( i=1; i<7; i++)
3456 { for(j=1; j<7; j++) // 1 2 3 4 5 6
456 for(j=i; j<7; j++ ) printf(“%d “, j);
56 printf(“%d “, j);
6 printf(“\n”); for(j=2; j<7; j++) // 2 3 4 5 6
} printf(“%d “, j);

for(j=3; j<7; j++) // 3 4 5 6


printf(“%d “, j);
….
C-Family 115 Nested-Loop

123456 The ‘j’ loop repeats as follows


12345 for( i=6; i>0; i--)
1234 { for(j=1; j<=6; j++) // 1 2 3 4 5 6
123 for(j=1; j<=i; j++ ) printf(“%d “, j );
12 printf(“%d “, j);
1 printf(“\n”); for(j=1; j<=5; j++) // 1 2 3 4 5
} printf(“%d “, j );

for(j=1; j<=4; j++) // 1 2 3 4


printf(“%d “, j );
….

1 2345 for(x=i=1; i<=8; i++)


6 7 8 9 10 { for(j=1; j<=5; j++)
11 12 13 14 15 { printf(“%d “, x++);
……. x++;
8 rows }
printf(“\n”);
}
the ‘i’ loop repeats 8 times to print 8 rows in the pattern
the ‘j’ loop repeats ‘5’ times to print 5 columns in a row;
the ‘x’ value continuous increments as output is continuous numbers

1234554321 for(i=1; i<=8; i++)


1234554321 { for(j=1; j<=5; j++) // to print 5 columns in first half of row
1234554321 printf(“%d “, j);
1234554321 for(j=5; j>=1; j--) // to print 5 columns in second half of row
… 8 rows printf(“%d “, j);
printf(“\n”);
}

The first ‘j’ loop prints the 12345, whereas second ‘j’ loop prints the 54321

5 blanks 
for(x=5,i=1; i<=6; j++)
1
{ for(j=1; j<=x; j++) // loop to print blanks
4 blanks 2 2
printf(“⨿“);
3 blanks 3 3 3 for(j=1; j<=i ; j++)
2 blanks 4 4 4 4 printf(“*⨿“);
1 blanks 5 5 5 5 5 printf(“\n”);
0 blanks 6 6 6 6 6 6 x--;
…6 rows
}
The 1st inner j-loop prints the spaces before
printing numbers
the second inner loop prints the stars.
Try without using ‘x’.
C-Family 116 Nested-Loop

11 to get this pattern, some spaces need to be added before each row,
1221 which is below shown
123321 7 blanks  1 1
12344321 6 blanks  1 2 2 1
1234554321 5 blanks  1 2 3 3 2 1
123456654321 4 blanks 1 2 3 4 4 3 2 1
12345677654321 3 blanks 1 2 3 4 5 5 4 3 2 1
1234567887654321 2 blanks 1 2 3 4 5 6 6 5 4 3 2 1
1 blacks 1 2 3 4 5 6 7 7 6 5 4 3 2 1
0 blanks  1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1

for(x=7,i=1; i<=8; j++)


{ for(j=1; j<=x;j++) // loop to add blanks before each row
printf(“⨿“);
for(j=1; j<=i; j++) // loop to print first half of values in a row
printf(“%d “,j);
for(j=i; j>=1; j--) // loop to print second half of values in a row
printf(“%d “,j);
printf(“\n”);
x--;
}
First j-loop prints the blanks, the second & third j-loop prints the 1st & 2nd halves.
Try without using ‘x’

5 blanks 
for(x=5,i=1; i<=6; j++)
*
{ for(j=1; j<=x; j++) // loop to print blanks
4 blanks * * *
printf(“⨿“);
3 blanks * * * * * for(j=1; j<2*i; j++)
2 blanks * * * * * * * printf(“*“);
1 blanks * * * * * * * * * printf(“\n”);
0 blanks * * * * * * * * * * * x--;
…6 rows
}
The 1st inner j-loop prints the spaces before
printing numbers
the second inner loop prints the stars.
Try without using ‘x’.

0 blanks  * * * * * * * * * * *
N=6;
1 blanks * * * * * * * * * for(x=0,i=1; i<=N; j++)
2 blanks * * * * * * * { for(j=1; j<=x; j++) // loop to print blanks
3 blanks * * * * * printf(“ “);
4 blanks * * * for(j=1; j<2*N-2*i; j++)
5 blanks * printf(“*“);
printf(“\n”);
x++;
}
C-Family 117 Nested-Loop

Printing multiplication tables from 5 to 12


void main()
{ int n,i;
for(n=5; n<=12; n++) // loop to print tables from 5-12
{
for(i=1; i<=10; i++) // loop to print 10 terms in the table
printf(“\n %d * %d = %d”, n, i, n*i);
printf(“\n\n“); // inserting two extra new lines after each table
}
}

Printing multiplication table(s) for a desired values


This program continuously accepts table numbers from k.B until zero as end of program. When zero is
entered then loop stopped by break and program gets closed. For every input, related table is printed.
void main()
{ int n , i ;
while(1)
{ printf(“\n\n enter table number :”);
scanf(“%d”, &n);
if(n==0)
break;
for(i=1; i<=10; i++)
printf(“\n %d * %d = %d”, n, i, n*i);
}
}

Printing prime numbers list between 50-100


void main()
{ int n,i,bool;
for(n=50; n<=100; n++) // loop to print prime numbers from 50-100
{ bool=1; // let us assume ‘n’ is prime, so bool=1
for(i=2; i<=n/2; i++) // loop to check prime-ness of ‘n’
{ if(n%i==0)
{ bool=0;
break;
}
}
if(bool==1)
printf(“%d “, n);
}
}
The outer loop is used for tracing all numbers between 50 to 100 whereas the inner loop is used to check
whether each number (n) is prime or not. This inner loop checks prime-ness by dividing from 2 to n/2.
C-Family 118 Nested-Loop

Printing twin prime numbers between 2-100


The twin prime numbers are 3-5, 5-7, 11-13, 17-19 …. The difference of their numbers is 2
Logic: initially, let us take first prime 2 (say previous=2), now start finding primes from 3 to 100 (N=3 to 100)
if N is prime then check out if N-previous==2 or not? If yes then print previous & N as twin primes.
Now take this current N value as ‘previous’ for next cycles.
void main()
{ int n, i, prev, bool;
prev=2; // let us take firs prime 2 for ‘prev’
for(n=3; n<=100; n++) // loop to print prime numbers from 3-100
{ bool=1; // let us assume ‘n’ is prime, so bool=1
for(i=2; i<=n/2; i++) // loop to check prime-ness of ‘n’
if(n%i==0)
{ bool=0;
break;
}
if(bool==1)
{ if(n-prev==2)
printf(“\n %d - %d “, prev, n);
prev=n; // taking current prime as previous prime for next cycle
}
}
}
Adding sum of digits in a given number until it gets single digit
ip: 19999 op: 1
process: 1+9+9+9+9  37  3+7  10  1+0  1
void main()
{ int n, sum;
printf(“\n enter number :”);
scanf(“%d”, &n);
while(n>9) // loop to add repeatedly until n becomes single digit, if n>9 means more digits
{ sum=0;
while(n>0) // loop to add all digits in ‘n’
{ sum=sum+n%10;
n=n/10;
}
n=sum;
}
printf(“\n sum = %d”, n);
}
C-Family 119 Nested-Loop

Menu driven program to find given number is odd/even, Palindrome, etc


Menu driven program to find given number is odd/even, Palindrome, Prime, Armstrong, and perfect or not;
Even: The number is divisible by 2 (remainder is zero)
Palindrome: If ‘n’ and its reverse are equal then it is called palindrome
Prime: The number has no divisible other than 1 and itself
Armstrong: sum of cubes of digits equal to given number (153  1^3+5^3+3^3  153)
Perfect: sum of factors equal to given number like 6 (1+2+36)
While executing the program, the menu appeared as given below
Menu run
==========================
1. Even/add
2. Palindrome
3.Prime or not
4.Armstrong
5. Perfect
0.exit
Enter choice [1,2,3,4,5,0]:
void main()
{ int N,i,t,r,rev, sum, choice;
printf("\n enter N value:");
scanf("%d", &N);
while(1)
{ printf("\n\n Menu run ");
printf("\n ==========================");
printf("\n 1.Even/Odd ");
printf("\n 2.prime or not");
printf("\n 3.Palindrome");
printf("\n 4.Armstrong");
printf("\n 0.exit");
printf("\n Enter choice [1,2,3,4,5,0]: ");
scanf("%d", &choice);
printf("\n\n output is: ");
switch( choice )
{ case 1: if( N%2==0 ) printf("Even");
else printf("Even");
break;
case 2: rev=0; t=N;
while(t>0)
{ rev = rev*10 + t%10;
t = t/10;
}
if(N==rev) printf("palindrome");
else printf("not palindrome");
break;
C-Family 120 Nested-Loop

case 3: for(i=2; i<=N/2; i++)


{ if(N%i==0)
break;
}
if(i>N/2) printf("prime");
else printf("not prime");
break;
case 4: t=N; sum=0;
while(t>0)
{ r=t%10;
sum=sum + t*t*t;
t=t/10;
}
if(sum==N) printf("Armstrong");
else printf("not Armstrong");
break;
case 0: exit(0); // program closes
default: printf("invalid input");
}
printf("\n\n");
}
}
C-Family 121 1D-Arrays

Single Dimension Arrays


In real world, we often need to maintain collection of data such as marks of a student, items price at
supermarket, matrices data, etc. To handle this kind of collection of data, arrays are the alternative.
The word array means, collection of homogenous items arranged sequentially like a rack of items in the
shelf.
In computer science, an array is a collection of adjacent memory locations used to store and access several
similar values using single name. It is a mechanism to access collection of similar values with a single name.
The new definition is, array is a collection-type data-type for handling collection of similar values with a
single name. According to mathematics terminology, array is a vector and single variable is a scalar.
For example, {13, 26, 7, 15, 10, 67, 984} are array of integer values.

Space for all items of array is allocated in contiguous memory locations in the RAM and each item is
accessed with their index value in the program. For example, in the above array values, the index of 13 is 0,
26 is 1, and 7 are 2 and so on.
Arrays can be extended to any number of dimensions, but most of the time, we use single or double
dimension arrays in the programming, the arrays are represented as,
int x[5];  single dimensional array int y[5][6];  two dimensional array

Y[0][0] Y[0][1] Y[0][2] Y[0][3] Y[0][4] Y[0][5]


x[0] x[1] x[2] x[3] x[4]
Y[1][0] Y[1][1] … … … Y[1][5]

Y[2][0] … … … … Y[2][5]

Y[3][0] … … … … Y[3][5]

Y[4][0] … … … … Y[4][5]

Single dimensional arrays


Syntax to define one-dimensional array variable is: data-type array-name[arrSize];

for example, int X[7];


x[0] x[1] x[2] x[3] x[4] x[5] x[6]

Here, the ‘X’ is an array name, which holds 7 integer items. The declaration of array is same as any other
normal variable except the arrSize. The size should be mentioned with constant value and which represents
count of elements that are collectively created as array.
Accessing array elements
Each value in the array is accessed independently using its index value with the array name. Especially in C,
the index ranges from 0 to arrSize-1.
The syntax to access array element is: array-name[index]

For example, 13 26 7 15 10 67 984


x[0] x[1] x[2] x[3] x[4] x[5] x[6]

the expression x[0] accesses the 1st element in array. x[0] 13
the expression x[1] accesses the 2nd element of array. x[1] 26
the expression x[i] accesses the i+1th element of array.
Printing first ‘5’ elements of an array is
for(i=0; i<5; i++)
printf(“%d “, x*i+); // 13 26 7 15 10
C-Family 122 1D-Arrays

Initialization of array
Assigning values at the time of declaration of array is called “array initialization”
So we can assign (initialize) values to array just like normal variable’s initialization.
Syntax: data-type array-name[arrSize]={ list of values };

int a[5]={10,20,30,40,50}; 10 20 30 40 50

a[0] a[1] a[2] a[3] a[4]

size of array is nothing but number of


int a[ ]={10,20,30,40,50}; 10 20 30 40 50
values assigned to array
a[0] a[1] a[2] a[3] a[4]

int a[5]={10,20,30}; 10 20 30 0 0 zeroes filled by compiler for last two


a[0] a[1] a[2] a[3] a[4]

int a[5]={9}; 9 0 0 0 0 zeroes filled by compiler


a[0] a[1] a[2] a[3] a[4]

compiler shows error, because


10 20 30 40 50
int a[3]={10,20,30,40,50}; the array size < count of values
a[0] a[1] a[2] a[3] a[4]

Checking array boundaries


The compiler does not check whether the array index is in valid range or not, because such provision not
provided/available in C, therefore, it is the programmer responsibility to check array index before running a
program. Ensure that, the index value must lie within the range of 0 to arrSize-1, otherwise program may
crash due to accessing unauthorized memory which is out of range. For example,
int A, B[3], C, D;

A B[0] B[1] B[2] C D


This memory beyond array limits

A=10; C=20; D=40;


B[1] = 300; // valid expression
B[2] = 400; // valid expression
B[3] = 500; // in-valid expression
B[4] = 600; // in-valid expression
B[100]=700; // in-valid expression
The last two expressions B[3]=500, B[4]=600 crosses the array limits and possibly they enter into (C,D)’s
memory, the expression B[3]=500 indirectly puts 500 in ‘C’ and B*4+=600 indirectly puts 600 in ‘D’s memory.
In this way, some array indexes infiltrate into next memory cells and may corrupt their data or code.
If program’s code(instructions) damaged and processor tries to execute damaged instructions then it leads
to program crash.

Scanning ‘5’ values to array


void main()
{ int a[5], i;
printf(“enter 5 values :”);
for(i=0; i<5; i++)
scanf(“%d”, &a*i+ );
------
}
We can scan like scanf(“%d%d%d%d%d”, &a*0+, &a*1+, &a*2+, &a*3+, &a*4+ ); but this leads to complex(heavy)
C-Family 123 1D-Arrays

Scanning ‘n’ values to array


Sometimes we can’t expect the size or count of input values, the count may vary day to day or time to time,
in that case, first we scan the count and then array values. For example, in a college, the class room capacity
is 60, but count of joining students may vary year to year, say 40-to-60. In this case, first we scan count of
joined students and then their data. Following example explains how to scan marks of ‘n’ students and
printing average marks of a class.
void main()
{ int a[60], i, n, sum=0;
printf(“enter no.of students joined:”);
scanf(“%d”, &n);
if( n>60 )
{ printf(“error, not enough array size”);
return; // closes the program
}
printf(“ enter %d student marks:”, n );
for(i=0; i<n; i++)
scanf(“%d”, &a*i+ );
for(i=0; i<n; i++)
sum=sum+a[i];
printf(“average marks is %d”, sum/n);
}
ip: enter no.of students joined: 6 ⤶
enter 6 student marks: 79 56 67 90 89 78 ⤶
average marks is 75.90

How arrays are useful?


To understand the benefits of arrays, consider the following problem of reading marks of 4 students and
then displaying their total & average.
void main( )
{ int m1,m2,m3,m4, total, avg;
printf(“enter marks 1:”);
scanf(“%d”, &m1);
printf(“enter marks 2:”);
scanf(“%d”, &m2);
printf(“enter marks 3:”);
scanf(“%d”, &m3);
printf(“enter marks 4:”);
scanf(“%d”, &m4);
total=m1+m2+m3+m4;
avg=total/4;
printf(“\n total = %d, average = %d”, total, avg );
}
The above program looks simple since we are taking the marks of 4 students. If more students exist then it
leads to hard coding and cumbersome in writing printf() and scanf() functions as many no of times. For this
kind of problems, arrays are the alternative. Let us try the above program with arrays,
C-Family 124 1D-Arrays

void main()
{ int m[4], total, avg, i;
printf(“enter marks of 4 students :”);
for( i=0; i<4; i++)
scanf(“%d”, &m*i+);
for(i =0; i<4; i++)
total = total + m[i];
avg = total/4;
printf(“\n total = %d, average = %d”, total, avg);
}
The size of program will remain same even if the number of students increases. Also it leaves the code
simple & readable.

About array size


At the time of compilation, the space of variables including arrays logically arranged in an order how they
declared in the program. For example, int a, b, c[5], d, e;

A B c[0] c[1] c[2] c[3] c[4] d e

2byte 2byte  10 bytes  2byte 2byte


Here 18 bytes of memory is allocated for all these variables including arrays, generally, these occupy
continuous locations as shown in picture. If array size “int c*5+” is not given then compiler can’t allocate
space for variables (d,e). Because, at compile time all variable’s space is arranged logically one after the
other, if you don’t mention array-size then compiler cannot allocate space for adjacent variables (here d,e).
So array-size must be given while declaration and it must be constant, if not, we get compile time error.

Let us see some valid and invalid declarations


eg1) int a[5]; // valid declaration

eg2) int n=5;


int a[n]; // invalid declaration, the size must be constant (not variable)

eg3) int a[ ]; // error, size must be given at coding time ( empty array not allowed)

eg4) printf(“enter n value :“);


scanf(“%d”, &n);
int a[n]; // this is also a brutal error

Note: These arrays are called static-size-arrays(fixed size arrays), these are used when we know the size of
array at coding time. For examples phone[12], name[30], pincode[6], address[50].
Sometimes, we can’t expect the array-size(data-size) at coding time, then dynamic arrays are the alternative.
We will see at end of chapters [ malloc(), calloc(), realloc(), free() ]
C-Family 125 1D-Arrays

Finding sum, big and small of N values in the array


input: enter how many input values : 6 ⤶ ( no.of input values to the array)
enter 6 values to array : 4 12 43 6 19 10 ⤶
output: sum = 94, big = 43, small = 4
* to sum all values of array, take variable ‘sum=0’ and do sum=sum+a[i], where i=0 to n-1
* to find big value, take variable ‘big=0’ and compare if big<a*i+ then take big=a[i].
void main()
{ int a[10], sum, Bigx, Smallx, i, n; // Bigx is to hold big-value, Smallx is to hold small-value
printf(“enter how many input values to be scanned to array:”);
scanf(“%d”, &n);
if( n>10)
{ printf(“error, insufficient array size “);
exit(0); // closes the program
}
// now scanning each element one by one to the array
printf(“enter %d values to array :“, n);
for( i=0; i<n; i++)
scanf(“%d”, &a*i+);
sum=Bigx=Smallx=0; // to clean the garbage with zero
for(i=0; i<n; i++)
{ sum=sum+a[i];
if( Bigx < a[i] )
Bigx=a[i];
if( Smallx > a[i] )
Smallx=a[i];
}
printf(“\n sum = %d, big = %d, small = %d”, sum, Bigx, Smallx);
}
In the above program Bigx is meant to store the biggest value and Smallx to store the smallest value.
In the for-loop, the value of Bigx is compared with all values in the array. If any a[i] is found bigger than the
Bigx, then it is taken into Bigx. In this way, finally the bigger is achieved.

If all inputs are –ve like -12, -45, -6, then the condition if(Bigx<a[i]) always fails, because initial value of big is
zero, and no array value is > zero, so output zero is printed as big value. So to solve this problem, initialize
Bigx & Smallx with any one element in the array before comparison. It is better to initialize with a[0].

Finding how many 3 divisible exist in the array.


Logic: Divide each a[i] with 3 and count them when they divided perfectly, like if a[i]%3==0 then count++;
input: enter how many input values : 4
enter value of a[0] : 7
enter value of a[1] : 18
enter value of a[2] : 12
enter value of a[3] : 10
output: no.of 3 divisible are: 2
void main()
{ int a[50], i, n, count=0;
printf(“enter how many input values :”);
C-Family 126 1D-Arrays

scanf(“%d”, &n);
for( i=0; i<n; i++)
{ printf(“enter value of a*%d+ :”, i );
scanf(“%d”, &a*i+);
}
for( i=0; i<n; i++)
{ if( a[i]%3 ==0 )
count++;
}
printf(“no.of 3 divisible are: %d”, count);
}

Finding at least one value in the array is –ve or not?


input: enter how many input values:4
enter value of a[0] : 7
enter value of a[1] : -18
enter value of a[2] : 12
enter value of a[3] : 10
output: yes, –ve value exist
void main()
{ int a[50], i, bool, n;
printf(“enter how many input values :”);
scanf(“%d”, &n);
for(i=0; i<n; i++)
{ printf(“enter value of a*%d+ :”, i );
scanf(“%d”, &a*i+);
}
bool=0;
for( i=0; i<n; i++)
{ if( a[i] < 0 )
{ bool=1;
break;
}
}
if(bool==1) printf(“yes, –ve value exist”);
else printf(“no, -ve is not exist”);
}
Finding all input values of array is in ascending or not?
Logic: if any one value is bigger than next value, then we can say not in ascending order
input: enter how many input values: 5
enter value of a[0] : 7
enter value of a[1] : 18
enter value of a[2] : 32
enter value of a[3] : 41
enter value of a[4] : 63
output: yes, in ascending order
C-Family 127 1D-Arrays

void main()
{ int a[20], i, bool, n;
printf(“enter how many input values :”);
scanf(“%d”, &n);
for( i=0; i<n; i++)
{ printf(“enter value of a*%d+ :”, i );
scanf(“%d”, &a*i+);
}
bool=1;
for( i=0; i<n-1; i++)
{ if( a[i] > a[i+1] ) // if any one value is bigger than next value, not in ascending order
{ bool=0;
break;
}
}
if(bool==1) printf(“yes, in ascending order”);
else printf(“no, not in ascending order”);
}

Finding no.of days in a given month


ip: 2 2003 ip: 4 2009
op: 28 days op: 30 days
void main()
{ int m;
int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
printf(“enter month:”);
scanf(“%d”, &m);
printf(“ days in month is %d”, days*m+ );
}
The array “days[]” holds the number of days in each month. The days in a month initialized to array is
relative to the month-index, for example
a[1]  January,
a[2]  February,
a[0]  0  dummy value..
note: here leap-year in not considered.

Checking given date is valid or not?


ip: 30 2 2001 ip: 30 4 2010 ip: 31 12 2021
op: invalid date op: valid date op: valid date
void main()
{ int arr[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int d,m,y;
printf(“enter a date :”);
scanf(“%d%d%d”, &d,&m,&y);
arr[2] = 28 + (y%4==0); // February has 29 days in leap year, if y%4==0 is true then it gives 1.
C-Family 128 1D-Arrays

if( m<0 || m>12 || d<1 || d>arr[m] )


printf(“ invalid date”);
else printf( “ valid date”);
}
Finding NCR of two numbers
Ip: 4 2 ip: 7 1
N
op: CR = 6 op: NCR = 1
void main()
{ long int a[10]={ 1,1,2,6,24,120,720,5040,… -;
int n, r, result;
printf(“enter n & r values :”);
scanf(“%d%d”, &n, &r);
result = a[n] / (a[r]*a[n-r]);
printf(“\n NCR = %d”, result);
}
N
Initially, the array already filled with calculated factorial values. Therefore, the CR value is easily obtained
by substituting in the equation from already calculated values. Finally the result is printed.

Reversing array elements


ip: 23 34 56 32 78 89 53 81 18 86
op: 86 18 81 53 89 78 32 56 34 23 ( reversed array)
Program accepts ‘n’ numbers from keyboard and then reverses the elements of the array.
To reverse the elements, we have to swap elements in the opposite ends i.e., swap the first element with
the last element, second element with the previous of last element, and so on.
23 34 56 32 78 89 53 81 18 86
A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9]

void main()
{ int a[20],i,j, n, temp;
printf(“enter no. of input values ‘n’:”);
scanf(“%d”, &n);
printf (“enter %d values to array :“, n);
for( i=0; i<n; i++)
scanf(“%d”, &a*i+);
for(i=0, j=n-1; i<j; i++, j--)
{ temp=a[i];
a[i] = a[j];
a[j] = temp;
}
printf(“\n after reversing, the array elements are \n”);
for(i=0; i<n; i++)
printf(“%d “, a*i+);
}
C-Family 129 1D-Arrays

Deleting kth position element in the array


ip: 23 34 56 32 78 89 96
th
op: 23 34 56 32 89 96 //after deleting 5 element (78)
The following array contained 10 values, and it gives demo how to delete 5 th element.
The code to delete 5th element is as follows
for(i=5; i<10; i++)
a[i-1] = a[i]; // it replaces a*4+ by a*5+, a*5+ by a*6+, …etc.
45 56 77 60 99 87 43 34 17 22
A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9] A[10] A[11] A[12]

99 87 43 34 17
45 56 77 60 22
87 43 34 44 22
A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9] A[10] A[11] A[12]

Now write a program, where accept N values from keyboard and delete kth element in the array(k<N)
later print all elements after deleting kth element.

Inserting a new element at kth position


ip: 45 56 77 60 99 87 43 34 44 22
op: 45 56 77 60 99 ‘11’ 87 43 34 44 22 // after inserting 11 at 6th position
Program inserts a new element at kth position in an existing array of ‘n’ elements, where k<n.
To insert a new element at A[k], shift all existing elements of A[k], A[k+1], A[k+2]...a[N-1] to the right side by
one position. So that we get a gap at A[k], where new element can be inserted.
For example, to insert a new element 11 at A[5], shift all elements 22,44,34, 43, 87 to the right side by one
position, so that we get a gap after 87, where 11 can be inserted.

45 56 77 60 99 87 43 34 44 22
A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9] A[10] A[11] A[12]
void main()
{ int a[20],i, k, new;
printf(“enter no.of input values n :”);
scanf(“%d”, &n);
printf(“enter %d values to array : “, n);
for( i=0; i<n; i++)
scanf(“%d”, &a*i+);
printf(“enter new element and position to insert :”);
scanf(“%d%d”, &new, &k);
for(i=n; i>=k; i--) // shifting elements to right-side
a[i] = a[i-1];
a[k-1]=new; // inserting new element
n++; // now array contains n+1 elements
printf(“\n after inserting elements, the array is :”);
for( i=0; i<n; i++)
printf(“%d “, a*i+ );
}
C-Family 130 1D-Arrays

Printing list of primes in given array of values


Ip: 23 11 19 20 87 65 42
op: 11 19 87 // primes
void main()
{ int a[20], i, bool, j;
printf(“enter the no.of input values n :”);
scanf(“%d”, &n);
printf(“enter %d values to array :“, n);
for( i=0; i<n; i++)
scanf(“%d”, &a*i+);
for(i=0; i<n; i++) // loop to check each number in the array, whether it is prime or not?
{ bool=1; // let a[i] is prime, so set bool to 1
for(j=2; j<=a[i]/2; j++) // loop to check a[i] is prime or not
{ if( a[i]%j==0)
{ bool=0;
break;
}
}
if(bool==1) // if not divided anywhere, it is prime
printf(“%d “, a*i+);
}
}
i-loop is to check all numbers in the array,
j-loop is to check each a[i] is prime or not?, it is by dividing from 2 to a[i]/2

Finding standard deviation from set of values


ip: A[] = { 7 , 1 , -6 , -2 , 5 }
op: result=4.69
The formula for standard deviation is sqrt (∑(A*i]–mean A[])2/N )

Let the average(mean) of all values are M, the formula as given below
sd = sqrt ( (A0-M)2 + (A1-M)2 + (A2-M)2 + (A3-M)2 + … + (An-M)2 / N )

void main()
{ int a[20], i, N, mean;
float sum, sd;
printf("enter the no.of input values N :");
scanf("%d", &N);
printf("enter %d values to array :", N);
for( i=0; i<N; i++)
scanf("%d", &a[i]);
for(i=sum=0; i<N; i++) // calculating sum of all values
{ sum=sum+a[i];
}
C-Family 131 1D-Arrays

mean=sum/N; // calculating mean value


for(i=sum=0; i<N; i++) // calculating sum of squares to convert –ve values to +ve
{ sum = sum + (a[i]-mean)*(a[i]-mean);
}
sd=sqrt(sum/N);
printf("standard deviation is %.2f", sd);
}

Printing common elements of two arrays


ip: 23 34 45 32 78 44 72 85
21 44 55 62 56 23
op: 23 44
Let us say, two arrays a[ ] & b[ ] contained n1 & n2 number of elements respectively.
step1: compare a[0] with all the elements of b[ ], if found anywhere then print it.
step2: compare a[1] with all the elements of b[ ], if found anywhere then print it.
In this way elements are compared and common elements are printed.
Note: Let each array contained distinct elements (no duplicate exist)
The following figure and code shows how the comparison is done for every element.

23 34 56 32 78 44 The code is,


A[0] A[1] A[2] A[3] A[4] for(i=0; i<n1; i++)
for( j=0; j<n2; j++)
{ if( a[i] == b[j] )
21 44 55 62 56 23 , printf( “%d “, a*i+);
B[0] Bb[1] B[2] B[3] B[4] B[5] break;
}
}
23 34 56 32 78
A[0] A[1] A[2] A[3] A[4]

21 44 55 62 56 23
B[0] Bb[1] B[2] B[3] B[4] B[5]
C-Family 132 Functions

Functions
Function is a subprogram that performs a specific independent sub-task in a program. It is a self-contained
block of instructions with an associated name to perform a specific, well-defined task. Functions mainly
provide reusability and modularity. It breaks down a big program into several sub programs and each is
designed and developed to perform a specific task. Thus collection of functions makes a C-program.
In computer science, the function is also called as routine, subroutine, subprogram, procedure, or method or
module.
While developing a big application, it should be designed in such a way that, it is divided into several
meaningful modules and each module again divided into several sub-modules called functions. For example,
let us consider Bank automation project, it can be divided into several modules say account, transaction,
customer, loan, etc. Each of these modules is made up of several functions which accomplish individual
tasks. Generally, every module is developed in separate files like “accounts.c”, “customers.c”, “loans.c”, etc;
finally, all such files which are developed by several people are integrated to build the whole project.

Types of functions
Functions are classified into two types: 1. Library functions 2. User-defined functions
Library functions: These are ready-made functions, which are designed and written by the C
manufactures to provide solutions for basic and routine tasks in the programming. For example I/O
functions printf() & scanf(), mathematical functions pow() & sqrt(), etc. The vendor of C, supply these
predefined functions in compiled form(object code format) with C software. There is huge collection of
functions available to meet all requirements in the programming, thus collection of such compiled functions
are called as function Library.

User-defined functions: We can write our own functions as per our requirement just like any library
function. There is no conceptual difference between user-defined and library functions, all works in similar
way, besides, our functions can be added to existing library and we can use like a library function. If more
collections found, then we can create our own library.

In C, the main() is also a user defined function, the word main is reserved by the complier but the body is
implemented by the programmer. The main() function works as start & end point of program. The remaining
functions execute by transferring the control temporarily from main().There is no syntax difference between
main() and other functions, all works in similar way.

Let us see the following example, which illustrates how the functions are executed in the program. The
instruction k=findBig(4,23) is a function-call statement in main(), when it gets executed, the control jumps to
the findBig() fn body along with values (23,4), and these values are assigned to (x, y) variables , after
calculating big value(z), it returns and assign back to k, this is as shown below.

main() function body findBig() function body

void main()
{ int findBig ( int x, int y)
int k; { int z;
if( x>y)
k=findBig(23,4); z=x;
else
printf(“%d”,k); z=y;
} return(z);
}
C-Family 133 Functions

*While jumping the control from main() to findBig(), the values(23,4) are passed and assigned to (x, y),
after finding the big value to ‘z’, it returns and assign back to ‘k’. In this way functions are executed.

*the passing input values to function are said to be arguments, whereas the receiving variables of such
arguments are said to be parameters. In this example, the values(23,4) are arguments and (x, y) are
parameters. The arguments and parameters count must be matched, and type should be compatible.

*In this program, we have two functions main() and findBig(). Here the main() is invoking(calling) the
findBig(), so in this context main() is said to be calling-function, whereas findBig() is said to be called-
function.

*Here the word “findBig” is said to be the name of function and it follows the rules of variables name. We
can give any name to the function just like a variable name in the program.

*The type int before the function name is said to be return-value-type. In this example, the function is
returning integer value of ‘z’, therefore return-value-type declared as int. The return-type explicitly tells
what type of value the function is returning. It is useful for compiler to check syntax errors as well as to the
programmer for documentation.

*Thus, every function does something and returns calculated result to the calling-function. Every function
including main() fn follows same syntax rules with one or two optional statements. The following figure
shows the each & every entity of function
Return-value-type
Return-value-type

Function name Function name

Function header with


Function calling with
parameters (x, y)
arguments (23,4)

main() function body findBig() function body

void main() int findBig( int x, int y)


{ {
int z;
int k;
if( x>y)
k=findBig(23, 4);
z=x; findBig() fn body
main() fn body
else
printf(“%d”,k); z=y;
return(z);
return; }
}

Here this ‘return’ statement is not required, because, the last closing
braces ‘}’ of function works as “return” statement.

This last closing braces works as “return” statement. This rule is


applicable to all functions when they are not returning any value.

This is said to be “return-value-type” of a function, this type must be matched with the return-value
of a function. In this example x+y is returning as int, therefore return-value-type declared as int.
C-Family 134 Functions

Finding tax on employee salary using function


If salary<=10000 then tax=0%
if salary>10000 && salary<=20000 then tax=5%
if salary>20000 then tax=8%

main() function body findTax() function

void main() float findTax( float sal ) // the variable (pa


{ {
float salary, tax; float t;
printf(“enter salary :”); if( sal<=10000)
scanf(“%f”, &salary); t=0;
else if( sal<=20000)
tax=findTax( salary ); t=5*sal/100;
else
printf(“tax is %f”, tax ); t=8*sal/100;
return( t );
} }

The function findTax() is taking employee salary as input(argument), and after calculating tax amount, it
returns and assigns back to ‘tax’. This is as shown in the above figure, here the variable ‘salary’ is said to be
argument, whereas ‘sal’ is said to be parameter. In the above findBig() example, the arguments (23,4) are
constants, but in this example, argument salary is a variable. Here value of salary is passed as argument to
the function. Sometimes argument and parameter names can be same, but they are different copies, let us
see following example

main() function body findTax() function

void main() float findTax( float salary )


{ {
float salary, tax; float tax;
printf(“enter salary :”); if( sal<=10000)
scanf(“%f”, &salary); tax=0;
else if( salary<=20000)
tax=findTax( salary ); tax=5*salary/100;
else
printf(“tax is %f”, tax ); tax=8*salary/100;
} return(tax);
}
salary tax salary tax

Here argument and parameter variable’s name are same, but they are different copies, so in this total
program two ‘salary’ variables and two ‘tax’ variables exist. One set belongs to main() fn and second set
belongs findTax() fn (A separate memory space is created for each set like above shown picture).
So, argument variables are always different from parameter variables, parameters work like a copy of
arguments. It can be imagined as parameters are place-holder of arguments. Generally, beginners get
confusion when argument & parameters names are same.
C-Family 135 Functions

Finding factorial of a given value using function


input: 5
output: 120

main() function body fact() function


long int fact(int);
void main() long int fact(int X)
{ {
int N=5; long int f , i ;

long int k; for(i=f=1; i<=X; i++)


f=f*i;
k = fact(N);
return(f);
printf(“factorial = %d”, k); }

* The fact() function takes argument ‘N’(5) as input and stores into parameter ‘X’.
* After calculating factorial value, it returns and assigns back to ‘k’.
* In this way, function can be called as many times as we want. Let us see in next examples, how functions
can be called more than once.

Finding sum of 1 to N using function (1+2+3+4+5+ …..+N)


Following “findSum()” function calculates the sum of 1+2+3+…+N without using formula, this function takes
‘N’ as argument and returns the sum of 1 to N. Later main() function checks the “findSum()” returned value
is equal to formula N(N+1)/2 or not?. If equal then says “program is correct”, or else says “program has
some logical errors”.

void main()
{ int N=5, result; int findSum( int N)
result=findSum(N); // function call { int i , sum=0;
if(result==N*(N+1)/2) for(i=1; i<=N; i++)
printf(“program is correct”); sum=sum+i;
else return sum;
printf(“program has some logical errors”); }
}
C-Family 136 Functions

Syntax of function
Function has 3 syntaxes
1. Function definition/body ( defines the code of function )
2. Function calling/invoking ( activating the function )
3. Function declaration ( also called proto-type )
① Syntax of function-body
return-value-type function-name( parameters-list )
{ variable-declaration;
instruction1;
instruction2;
……..
return(result);
}

The function body defines the task of function, ie, what it does. This body executes when this is called
explicitly from other part of program. Every function follows this syntax with one or two optional
statements.

② Syntax of function-call statement


variable = function-name( arguments-list );

* Calling a function means invoking the function task, ie, asking the function to do his respective job. When
the above function-call statement gets executed, the control transfers to its body along with arguments and
after executing all instruction within the body, the control returns to same point of call-statement.

* To understand the mechanism of function-call, let us consider a simple example. Suppose a bank manager
wants to verify cash in the bank, he calls his assistant and gives argument to him, later assistant returns the
details of cash. In the first example, the manager is main() and assistant is findBig(). Here main() wants to
find the big of two, so it called the findBig() and gave arguments (23,4) to him. In this way functions work.

* Function name: The body of function associate with a name and this name should be relevant to
function’s task, it should express the purpose of function. For example, if a function is written to find the
square root of a value, then it is better to name it as ‘sqrt()’. The body of function invokes by calling with this
name in the program.

* Calling vs Called: Here the main() is calling the findBig() function, so in this context, main() is said to be
calling-function whereas findBig() is said to be called-function.

* Arguments vs Parameters: Arguments are nothing but input values of function. When a function is called,
they are passed from calling-function to called-function along with the control. Whereas parameters are
variables, which receives (hold) the argument values at called-function. (Arguments are values whereas
parameters are variables)

* Arguments belong to calling-function, whereas parameters belong to called-function.

* Arguments and parameters must be matched or compatible.

* The following figure illustrates the relation between argument and parameters.
C-Family 137 Functions

calling() function called() function

return-type calling-fn() return-type called-fn( parameters)


{ ----- { -----
----- -----
function-call(arguments); -----
----- -----
----- -----
return(expression); return(expression);
} }
* in old definitions, arguments are also called actual-arguments or actual-parameters, whereas parameters
are also called formal-arguments or formal-parameters.
* return statement terminates the current task of function and returns the control to calling-function
with/without a value.
* function’s-limitation: The ‘C’ function can return either one or none value using ‘return’ statement,
because the syntax provided in that way, to return more values pointers are used. (we will see later)

③ Syntax of function-declaration (proto type)


return-value-type function-name( parameters-type );

As per old compilers, function proto-type must be given at the beginning of program followed by #include
statements. This declaration is nothing but introducing the function to the compiler about function-name,
parameters-type and return-type. This is similar to variable declaration in the program. It has no special
syntax like control statements. This syntax is simply a header line of function-body with the semicolon
termination. For example, int big(int,int);  this syntax is telling, the function name is “big” and taking two
int-arguments and returning int-value. In this way, we define proto-types as given below example.
#include<stdio.h>
int big(int,int);  // big() function proto-type
void main() // main() function body
{ ………
}
int big(int x, int y) // big() function body
{ …….
}
Note: if called-function body is provided before calling-function, then this body itself works as proto-type.
In this case, no special proto-type required in the program, for example,
#include<stdio.h>
int big(int x, int y)  // this body also works as proto-type
{ …….
}
void main()
{ ………
}
Note: we have a freedom to write function in any order, even main() fn can be written at bottom of program
like above shown. But as main() fn is starting point of program, the compiler automatically moves to
beginning in .exe file. In this way programmer has a freedom to write functions in any order.
C-Family 138 Functions

Finding NCR of given N and R values


Logic: NCR is a summation of n!, r!, and n-r!. Using fact() function, we can find these three factorials by calling
3 times. The control goes & returns three times to the fact() fn. This is as given below
main() function body fact() function body
long int fact(int);
void main() long int fact(int x)
{ int n,r; {
long int f1,f2,f3; int product,i;
printf(“enter n & r values :”);
scanf(“%d%d”, &n, &r); for(i=product=1; i<=x; i++)
product=product*i;
f1 = fact(n);
f2 = fact(r); return(product);
f3 = fact(n-r); }
printf(“ ncr = %d”, f1/(f2*f3));
}

Let input n=7, r=3; then function calls as given below


f1 = fact(7); // here value 7 passes as argument to fact()
f2 = fact(3); // here value 3 passes as argument to fact()
f3 = fact(7-3); // here value 4 passes as argument to fact()
In first call, the control goes with argument ‘7’ and returns 5040(7!) and assigns to ‘f1’.
In second call, the control goes with argument ‘3’ and returns 6(3!) assigns to ‘f2’.
In third call, the control goes with argument ‘4’ and returns 24(4!) assigns to ‘f3’.
In this way, reusability of code is possible with the functions whenever it is required.

Finding value of equation A10+B5+C2 using power() function


The power() function takes two arguments(x,y) as base and exponent and returns the power value.
Later the main() function calls power() to find value of equation: A10+B5+C2
int power( int , int ); // fn proto-type
void main()
{ int k, A=2,B=3,C=4 ;
k=power(A , 10) + power(B , 5) + power(C , 2); // here power() fn called 3 times.
printf(“\n output is = %d”, k );
}

int power( int x, int y )


{ int product,i;
for(i=product=1; i<=y; i++)
product=product*x; // multiplying x*x*x … y times
return(product);
}
C-Family 139 Functions

A demo program how return-value substitutes at fn-call statement


If function is returning any value, then function-call statement can be used as variable or expression in the
program, because the return-value substitutes in place of function-call as a variable. Let us see, how it is

void main()
{ float pie()
float area, radius=8; {
return 3.14;
area = pie() * radius *radius; }

printf(“\n area = %f”, area);


}
When the pie() function calls in the main(), it returns the float value 3.14 and substitutes at the
function-call statement as “area=3.14*radius*radius”
Actually, the function’s return-value is stored into a temporary variable (created by compiler) before
returning control to main() function, and such value substitutes in place of function-call. Thus above
function call can be imagined as
void main()
{ float area, radius=8;
temp=pie(); // here this ‘temp’ created by compiler
area = temp * radius *radius;
printf(“\n area = %f”, area);
}
here ‘temp’ is assumed name, actually it is a name-less variable created and used by compiler

Finding given number is palindrome or not?


The following function takes integer N as argument and returns the reverse of it, later main() function
prints given number is palindrome or not?
int reverse(int n)
{ int rev=0;
while(n>0) // loop to find reverse number
{ rev = rev*10+ n%10;
n=n/10;
}
return(rev);
}
void main()
{ int n;
printf(“enter n value :”);
scnaf(“%d”, &n);
if( n==reverse(n) )
printf(“palindrome”);
else
printf(“not a palindrome”);
}
As above told example, the function’s return-value is stored into a temporary variable and such value
substitutes in place of function-call. Thus above function call can be imagined as given below
C-Family 140 Functions

if( n == reverse(n) ) temp=reverse(n);


printf(“palindrome”); if( n == temp)
else printf(“palindrome”);
printf(“not a palindrome”); else
printf(“not a palindrome”);

Finding big of three numbers using function


This big() function takes two arguments as input values and returns the biggest of them.
Later main() function calls this function to find biggest of 3 given numbers.
int big(int , int); // fn declartion
void main()
{ int x,y,z,k;
printf( “\n enter 3 values :”);
scanf(“%d%d%d”, &x, &y, &z);
k=big(x,y); // k=big(x, big(y,z) );
k=big(k,z);
printf( “biggest = %d“, k);
}
int big(int a, int b) // fn body
{ if(a > b)
return a;
else
return b;
}
The above two function-calls can be written in single line as k=big(x, big(y,z) )
Let the x, y, z are 23, 42, 31, then function calls are k=big( 23, big(42,31) )  k=big(23 , 42)  k=42.
First the inner-call big(42,31) will be made and it returns 42, and this value substitutes in outer-call as
second argument. Finally outer-call will be made as k=big(23,42);

Finding given number is Armstrong or not?


This function takes integer ‘N’ as argument and returns Armstrong or not? If yes returns 1, otherwise 0.
Later the main() function scans ‘N’ as input and printing it is Armstrong or not?
int isArmstrong(int n)
{ int t, sum;
t=n; sum=0;
while(n>0)
{ r=n%10;
sum=sum+r*r*r;
n=n/10;
}
if( t==sum)
return 1;
else
return 0;
}
C-Family 141 Functions

void main()
{ int n;
printf(“enter n value :”);
scanf(“%d”, &n);
if( isArmstrong(n)==1)
printf(“yes, it is Armstrong“);
else
printf(“no, not Armstrong”);
}
Printing list of Armstrong numbers between 1 to 1000 (using above fn)
Output: 1, 153, 370, 371, 407.
void main()
{ int n;
for( n=1; n<=1000; n++)
if( isArmstrong(n)==1 )
printf(“%d “, n);
}
Finding prime-ness of a given number using function
This function takes integer N as argument and returns the prime or not. If prime returns 1, otherwise, 0;
int isPrime(int n)
{ int i;
for(i=2; i<=n/2; i++) //checking ‘n’ by dividing from 2 to n/2
{ if(n%i==0)
return(0); // here N divided, so returning ‘0’ as not-prime
}
return(1); // not at all divided, so returning ‘1’ as prime
}
void main()
{ int n;
printf(“enter n value :”);
scanf(“%d”, &n);
if( isPrime(n) ==1)
printf(“prime number “);
else
printf(“not prime number”);
}
Printing prime numbers from 50 to 100 using above “isPrime()“ fn.
void main()
{ int n;
for(n=50; n<=100; n++)
{ if( isPrime(n)) if(1)  true or if(0)  false
printf(“%d “, n);
}
}
Here isPrime() will be called 50 times with arguments 50, 51, 52, 53, 54, 55, 56, ….,100;
C-Family 142 Functions

About “void” data-type


In case, if function is not returning any value, then the return-value-type should be ‘void’, the keyword void
is also a data type like int, float, char. It represents empty-type/null-type. The following function welcome()
is returning no-value, therefore kept “void” as return-type.
Main() function welcome() function
void main()
{ printf(“\n Before welcome fn“); void welcome()
welcome(); {
printf(“\n After welcome fn“); printf(“\nWelcome to C-Family Computers”);
return; // this is optional, not required return; // this is optional, not required
} }
output: Before welcome fn
This ‘void‘ represents, the welcome()
Welcome to C-Family Computers function is returning no-value
After welcome fn

The above “welcome()” function is just displaying a message on the screen, it is taking no argument and
returning no-value. Therefore, the return-value-type ‘void’ has given in this example. The last closing braces
of a function works as “return” statement, therefore “return” an optional statement at the end of function.
As we know, the main() function generally returns no-value, that is why we always write main() function
body as “void main(){…}”

Printing multiplication table(s) up to 10 terms


This function takes table number N as argument and prints the 10 terms of a table and returns nothing, just
it is printing table. Later using main() function printing tables 3, 6 and 12.
note: if table number is –ve value, then shows an error message, “should not be -ve”
void printTable( int n)
{ int i;
if(n<0)
{ printf(“error, table Number should not be –ve”);
return; // this return statement throws the control back to main() fn. (this is not an optional statement)
}
for(i=1; i<11; i++) // loop to print 10 terms in a table
{
printf(“\n %d * %d = %d”, n, i, n*i);
}
return; // this return statement is not required
}
void main()
rd
{ printTable(3); // fn call to print 3 table
th
printTable(6); // fn call to print 6 table
th
printTable(12); // fn call to print 12 table
}
The printTable() function is not calculating any value, it is just printing table on the screen. Since, it is not
returning any value, the return type “void” specified here.
C-Family 143 Functions

Program prints 3-digit number in English words


The function printDigit(), prints given digit in English words, for example, if input argument is 4 then prints
“four” as English word. This function returning nothing because it is not doing any calculations, it is just
printing given digit on the screen.
Now using this fn, write a main() fn, where scan 3-digit number like 247 and print output as two-four-seven.
void printDigit(int n)
{ switch(n)
{ case 0: printf(“zero”);
break;
case 1: printf(“one”);
break;
--------
case 9: printf(“nine”);
break;
}
}
void main()
{ int n=247; // or scan from keyboard
st
printDigit(n/100); // passing 1 digit 2
printDigit(n/10%10); // passing 2nd digit 4
rd
printDigit(n%10); // passing 3 digit 7
}

A demo program, how multi-level calls are made


Let us see one more example, how the control jumps several levels of function calls and returning to same
point of call.
void x(); void y(); void z(); // function proto-types.
void main()
{ printf(“\n before x() function”);
x();
printf(“\n after x() function”);
}

void x()
{ printf(“\n before y() function”);
y();
printf(“\n after y() function”);
}

void y()
{ printf(“\n On behalf of C-Family Computers”);
}
before x() function
before y() function
On behalf of C-Family Computers
after y() function
after x() function
C-Family 144 Functions

 Here x() function is said to be called-function as well as calling-function.


 The main() is calling the x(), and x() is calling the y(). Therefore, x() is said to be called-function as well as
calling-function based on context.
 The order in which the functions are written, they may not be the same order to be called.
 Functions cannot be nested like control structures, because their body is independent.
 A program can have any number of functions.
 In programming, to accomplish one task, one function may take assistance of other functions and that
functions may take assistance of some other functions. In this way, software designed and developed with
the collection of functions and that are provided by several people in the industry.

* Scope of variables
If any variable declared within a block then it becomes private and cannot be used or accessed outside of
that block, same way, we cannot use/access one function’s variable in other function. In this way, every
function is independent as per their data & code. Only the data is exchanged between functions by passing
and returning.
void main()
{
{
int k=10;
}
{
printf(“%d ”, k); // error, undefined symbol ‘k’
}
}
Here compiler shows an error message “undefined symbol k”, because the variable ‘k’ declared in 1st inner
block and we are trying to access in 2nd inner block. Thus ‘k’ cannot be used other than 1st block as it is
private to that block. In this way, variables are block-scope types. Let us see one more example
void main()
{ int k=100;
test();
printf(“the k value =%d”, k);
}
void test()
{ k++; // error, undefined symbol ‘k’
}
Here compiler again shows same error message “undefined symbol k”. The variable ‘k’ declared in main()
function body and it cannot be accessed in test() function body.
example3
void test()
{ int k=100;
return(k);
}
void main()
{ test();
printf(“%d “, k ); // error, undefined symbol ‘k’
}

The variable ‘k’ declared in test() fn, cannot be accessed in main() fn, so it is an error.
C-Family 145 Functions

Demo program, how arguments VS parameters behave


If argument is a variable, then its value is passed and assigned to parameter, as we know, the parameter is a
copy of argument, if any changes made in the copy (parameter) that doesn’t effects the original (argument).
The following examples explain in two-ways

Example 1 Example 2
n n
void main() 10 void main() 10
{ int n=10; { int n=10;
printf(“\n before calling =d”,); printf(“\n before calling = %d”, n);
test(n); test(n);
printf(“\n after calling = %d “, n); printf(“\n after calling = %d “, n);
} }

void test( int x) void test( int n) // int n=5; n


X
{ { 10
10
x++; 11
n++; 11
} }
Output: before calling = 10 Output: before calling = 10
after calling = 10 after calling = 10
1) When test() calls, the argument n value 10 passes Here names of argument & parameter are
and assigns to parameter x. same; both variable names are n, but they
are different copies, creates in separate
Now, x is said to be copy of n. (like above picture)
memory area in the RAM. So, if any changes
If any changes made in x, it doesn’t effects the n.
made in parameter n, it doesn’t effects to
if one wants to change the n through x, then pointer argument n.
are required. We will see in next chapter.
Both programs shows same output.

Swapping of two values


void swap( int , int); //function-signature
void main()
{ int x=5,y=7;
printf(“\n before swapping = %d, %d”, x, y);
swap(x, y);
printf(“\n after swapping = %d, %d”, x, y);
}
void swap(int x, int y)
{ int temp;
temp=x;
x=y;
y=temp;
}
before swapping = 5, 7
after swapping = 5, 7
The swap() function cannot swap the x, y values of main() fn, instead, it swaps the x, y of its own function.
As we know, if parameter (copy) changes, it doesn’t effects the argument (original) values.
To swap x, y values of main() using swap() function, pointers concept is used, we will see in the next chapter.
C-Family 146 Functions

Passing array values one by one to function and printing on screen


void main()
{ int a[5]={ 55, 64, 67, 89, 32 };
for(i=0; i<5; i++)
display( a[i] ); // calling 5 times using loop, and passing each value one after one.
}
void display( int x )
{ printf(“%d “, x);
}
Here in this program, 5 elements are passed one by one in every call of function, this is just demo program.

Passing all elements of array at a time to a function


void main()
{ int a[3]={ 55, 64, 67 };
display( a[0], a[1], a[2] );
}
void display( int x, int y, int z )
{ printf(“%d %d %d“, x, y, z);
}
Here each element passed separately as an argument to the function, so for 3 arguments, 3 parameters are
required. Here we have taken x, y, z, for a[0], a[1], a[2].
Generally, this logic is not recommended for standard programming, because for more elements, more
parameters are required and it makes complex, for this problems we have a solution in pointers concept.

More about functions


1. return and return-value-type
2. about main() function and returning value to O.S
3. types of data communications between functions (calling types)
4. function signature (proto-type)
5. local and global variables
6. rules and regulations applied to functions.

1) return & return-value-type


return: The job of ‘return’ statement is, terminating the execution of current function and transferring the
control back to its calling-function with/without a value. The syntax is
syntax 1: return; // returning the control without value
syntax 2: return(value); // returning with value, here parenthesis are optional
Function can have any number of return statements but executes only one, upon executing one statement,
the control immediately transfers back to calling-function.
return-value-type: It is the data-type of a value which is being returned from a function, if return-type is
not mentioned explicitly, then compiler takes default type, which is int.
The return-type explicitly tells what type of value the function is returning. It is useful for compiler to check
syntax errors as well as to the programmer for documentation.
C-Family 147 Functions

int test() float test()


{ {
int f=56.78 return(14);
return(f); }
} Here, compiler returns 14 as 14.00
Here we are trying to return 56.78, but compiler returns only Because the return-type is ‘float’
56. Because, the return type is int.
void test() int test()
{ {
return 10; return; //observe no value
} }
If return-type is ‘void’ then can’t return a value. Here compiler shows an error/warning.
It shows compiling error when we trying to return a value. Because return-type is int, but we are not returning
any value;
test() // return-type is int int test( int k)
{ {
--- if(k<5)
--- return(100);
return 10; else
} return;
Here the return-type is not mentioned, so compiler takes }
default type, which is int. In some compilers, the default type is Error, both ‘return’ statements are not same, first one
void. is returning 100 but second one is not.
The ‘return’ statements must be same type.

2) about main() function


One can get a doubt, if main() is a function, by whom it is being called or from which point it is being called.
Actually, it is called by O.S, which is in turn by our self by giving run command such as F9 or typing exe file in
OS shell, or in some other form. In some compilers, the main() must return a value, which goes to O.S and
takes some actions like closing streams, files and other resources allocated for the program. It can be any of
following ways

void main() int main() int main()


{ { {
---- --- ---
---- --- if( condition)
---- return 0; return 1; // equal to exit(1)
} } -----
return(0) defines normal termination of program. -----
Turbo C and other compilers return(errorCode) defines some error found, here return 0; //equal to exit(0);
allow this syntax. errorCode is code of an error like return(1)/return(2),… }
This error codes defined in OS level

return(0) defines the normal termination of program and it closes all files, i/o streams and other resources
before termination of program.
return(1),return(2), etc defines the abnormal termination of program, here OS records the error-code or
error-type in log files for future reference. (Like history in web-browsers)
C-Family 148 Functions

3) Types of data communications between functions


1. function with arguments and return value: most of the calculation functions take arguments and
returns a value. For example, finding factorial value.
void main() int fact( int n )
{ int k; { int f=1;
k=fact(4); while(n>1) f=f*n--;
printf(“factorial is %d”, k); return f;
} }

2. function with arguments and no return value: some functions take arguments but returns nothing,
eg printing multiplication table.

void main() void printTable( int n )


{ { int i;
printTable(7); for(i=1; i<11; i++)
} printf(“\n %d * %d = %d”, n,i,n*i);
return;
}

3. function with no arguments but returns a value: this task is less common in programming , takes no
arguments but returns a value, like calling: rand() fn, getTime() fn, getDate() fn, getGPS() fn.

void main() int scanMarks()


{ int m1,m2; { int m;
m1=scanMarks(); printf(“enter marks:”);
m1=scanMarks(); scanf(“%d”, &m);
if( m>50 && m2>50) return m;
printf(“passed”); }
else
printf(“failed”);
}

4. function with no arguments and no return value: this is used for fixed jobs, the tasks like clearing
screen, printing common messages.

void main() void showAddress()


{ { pritnf(“Vijayawada”);
showAddress(); pritnf(“AP,India”);
} pritnf(“pin:520010”);
}

5) Function proto-type
This concept is very good for senior programmers when they want to create abstract data-type, but for
beginners who learning C/C++, it seems to be worst concept. It creates much confusion over function-call vs
function-proto type. Good news is, in modern compilers this concept eliminated/removed.
The English word proto-type means a model to an actual implementation, in C, it is used to introduce the
function to the compiler to give an idea about the return-type, function-name, argument-type and count.
Let us see, why it is required
C-Family 149 Functions

void main()
{ ---
k=test(20,30); // function-call
---
}
float test(float a, float b) // function body
{
return(a+b);
}
In C, functions are compiled in an order in which they are written in the program. Here first main() fn, later
test() fn will be compiled. While compiling main() function, at that time, compiler doesn’t know about test()
function( because it appeared at bottom). When compiler faces the call statement “k=test(20,30)”, it
notices and assumes, the ‘test()’ is a function with arguments 20,30. Based on this call statement, compiler
understands it as, the function is taking two int-type arguments by seeing (20,30) and returning int-type
value. (because default return type is int)
But later when compiling test() function-body, it will notices as, it is taking ‘float-type’ arguments with
return value float, therefore, this leads to data-type mismatch error between call and body.
To solve this problem, we have two options,
1. Declare the function before first call (or)
2. Define the function body before first call. (called-function before calling-function )
float test(float , float); // function proto-type Float test(float a, float b) // this body also works as proto-type
void main() {
{ --- return a+b;
k=test(); }
---
} void main()
float test(float a, float b) { ---
{ k=test();
return(a+b); ---
} }

6) Rules and regulations applied to functions


1. Argument and parameter must be compatible as per their count, types and order. If argument is int-type
then the matching parameter should be int/long/float or higher types.
2. In C, all functions are global, so any function may call anywhere in the program. Sometimes self-calling is
also possible, this is called recursion, we will see later.
3. Function can return only one value using return statement, to return more values pointer are required.
4. The default return type of function is int. But for some compilers it is void.
5. Some people think that, parameters are special kind of variables and cannot be used other than receiving
arguments. Actually, these are like any other normal variable in the program.
6. Passing arguments and returning value makes the function independent, reusable, easy to write the logic
and understand. Always divide the code as possible as independent blocks of functions.
C-Family 150 Functions

7) Advantages of functions
Reduces repetition of code: the repeated code can be converted into a function and called as many
times as we want in the programing.

Code reusability: Once, if function is made ready for use, it can be used several times in several programs
where ever it is necessary. Thus, reuse of function makes the programming easier and speed. Generally,
programmers develop applications from already existing code not from zero level. As we know pow(), sqrt(),
printf(), scanf(),…etc are preexisting functions and they are using many times almost in every program.

Reduces complexity: when a big program is divided into several functions, it reduces complexity,
improves readability, easy to modify and also debugging made easy.

Ease of debugging: debugging means finding syntax and logical errors. If any error occurs in a particular
function then it doesn’t require checking in other functions. Therefore, it is easy to find errors.

Increases readability: By observing function call statements (function-name), one can understand what
the function does, functions written by several people for several purposes. Generally, one doesn’t involve
or try to know how other’s functions made it. For example, we are calling “sqrt()” without knowing how it
works. So it is easier to understand the logic when program is made up with collection of functions. By
observing only function call statements in the program one can easily understand the entire logic.

Easy to modify: if one function is modified, that does not affect the other functions as they are
independent.

Portability: in computer science, C became a vital language, its usage extended in almost all fields in the
real world. Therefore, today, the C software is available in most of the computer environments. If a function
is developed on a particular operating system then it can be easily adapted to other operating systems
without/negligible modifications. Such written functions are portable and generic.
C-Family 151 pointers

Pointers
Pointers play an important role in C language, the excellent features of pointers have made ‘C’ a vital
language in computers world. In some other languages like Pascal, Basic, etc pointers are not programmers-
friendly as they are in C. In C, pointers are simple to use and programs can be made efficiently and
compactly. They give tremendous power to the programmer. A veteran programmer feels that, in the
absence of pointers no application could be made as efficiently as he expected. However pointers are
dangerous too, for example a pointer variable containing an invalid address can cause the program to crash.

In C program, in all situations, we cannot access the data directly using variable name. The alternative is,
accessing the data indirectly through its address; this is achieved through pointers. Pointer is a special type
of variable, which is used to store address of memory location, so that, such memory location can be
accessed using pointer from any point in the program. In this way, pointers provide indirect memory
accessing. Pointers are preferred mostly in manipulation of arrays, lists, tables, files, etc. Pointers and arrays
are closely related. Pointers provide quick and dynamic access of arrays. They have well support of
implementing linked lists, stacks, queues, trees, graphs and other dynamic data structures.

As we know, one function’s local variable visible/access within that function and cannot be accessed in other
function. This feature makes security, comfort and hidden away from other part of program. But some
variables (but not all) need to be accessed in other part of the program. In such case, pointers are the
alternatives. Using pointers, we can access calling-function’s data at called-functions. In case of large
collection of data like arrays, we cannot provide name for every data item to refer individually. For such kind
of data, pointers are the alternatives. Using pointers, we can access all items under one name using their
addresses, since the data items are stored sequentially one after the other in the memory. If we know the
address of one item, we can access adjacent items using pointer. Actually, the items of an array are accessed
internally through this technique only. Here array name acts as a pointer. Thus, arrays and pointers are
conceptually same. In case of dynamic collection of data, the size of input data cannot be estimated until the
execution time unlike static arrays. To provide space & access for such random size input data, pointers are
the alternative.

Definition of pointer
Pointer is a special kind of variable used to store address of memory location through which indirect
memory accessing can be performed. In other words, pointer is a variable used to access the data in the
memory through its address, i.e., pointers provide indirect memory accessing.
We know that, memory is a collection of bits, in which each eight-bits constitute one byte. Every byte has its
own unique location number called address. This location number (address) is just a serial number of the
byte sequence. For example, first byte address is 1, second byte address is 2, and so forth. To store this
address we need a special kind of variable called ‘pointer variable’.
Address of memory location is just a serial number in the byte sequence, so, to store such address, a normal
integer variable is enough. However, indirect accessing of memory is difficult, because the compiler cannot
determine whether the variable is holding an address or value. To work with pointers, we have two unary
operators
 Reference operator (&)
 De-reference operator (*)
The ‘&’ and ‘*’ operators work together for referencing and de-referencing.
C-Family 152 pointers

Reference operator (&)


This referencing operator is also called address operator, which gives the address of memory in which the
variable is resided.
Syntax to get the address of a variable is: &variable-name // prefix the ‘&’ before the variable name

k  variable name
For example: int k=10; 10  value
2020 2021  assumed addresses

printf(“ value = %d , address = %u “ , k , &k ) ;  value = 10 , address = 2020


// %d  signed int , %u  unsigned int (address is unsigned int value)

The address of a variable may not be always a fixed location like 2020 as shown in above, and it is
randomly given by the computer. Here we assumed k’s address as 2020.

Here the expression ‘&k’ is pronounced as “address of k”. The space for ‘k’ at run time may allocate
anywhere in the RAM, and to get such address, the reference operator(&) is used.
The format string %u or %p is used to print the address. [%pprints the address in hexadecimal format]

We know that, the variable ‘k’ occupies two bytes in memory. Suppose if it has occupied memory
locations 2020 & 2021, only the first byte address (2020) is considered to be the address of ‘k’ by the
compiler. As compiler aware that ’k’ occupies two bytes in memory, if the first byte address is 2020 then
obviously the second byte address would be 2021. So we always take first byte address as the address
of a variable irrespective of variable size.
Remember that, address is an unsigned-int type value.

Data type of address


If variable type is “int” then its address type is “int*”, similarly, if variable type is “float“ then its address type
is “float*”. In this way, we can easily identify the address-type. Let us see,
int X=10;
float Y=20.45;
char Z=’A’;

X Y Z
10 int 20.45 float ‘A’ char
2000 int* 3000 float* 4000 char*

Address types are derived types, by adding a symbol star (*) to the any existing data-type, it becomes as
address-type.
The data type “int*” derived from “int”
“float*” derived from “float”
“char*” derived from “char”
“int**” derived from “int*”
“int***” derived from “int**”
In this way address types are defined in the program, these are infinite types.
C-Family 153 pointers

De-Reference operator (*)


We misunderstand this operator with multiplication operator, we use this operator for both aspects and
there is no confusion over this operator, both do different actions.
This de-referencing operator is used to get the value at a given address, for example, *(2020)  10;
the value at address 2020 is 10. This is k’s value. This operator is also called ‘value’ operator as it gives the
value at given address, but calling ‘value operator’ is informal.
Most of the time, this operator is called ‘indirection operator’ as it changes the direction of control from one
location to another location (pointer-variable to value-variable) within the program’s memory to access the
required data. The action of ‘de-reference’ operator is just opposite to the action of ‘reference’ operator,

Syntax to get ‘value’ at given address is: *addressable_expression // prefix the symbol ‘*’ before the address

For example: printf(“\n the value of k = %d”, *&k); // output = 10


*&k  *2020 10
*&k  k  10 // the operators “* and &” can be cancelled when they found in adjacent places

The reference operator (&) gives the address of ‘k’, whereas de-reference operator (*) gives the value in that
address, so finally it is ‘k’ value.

Declaration of pointer variable


The symbol star (‘*’) is a multipurpose operator used in the following 3 cases
1. As a multiplication operator, to multiply two values
2. As a de-reference operator, to get value at a given address
3. To declare variable as a pointer
Now let us see how to declare a pointer variable
It is just like a normal variable declaration, but the symbol star (*) should be prefixed to the variable name.
(The star symbol differentiates the normal and a pointer variable)

Syntax to declare pointer variable is: data-type *pointer-name1, *pointer-name2, … ;

For example: int *p; // integer pointer, it holds a integer variable address
float *q; // float pointer, it holds a float variable address

Here p and q are pointer variables and they are capable of holding address of int & float variables
respectively. Here p is also called a pointer to int and q is called a pointer to float. The integer pointer is
used to access the integer data indirectly and a float pointer is used to access the float data indirectly.

int k=10; P k
int *p; 2020 10
4040 2020
p=&k; //p=2020
printf(“\n the value of k = %d”, *p); // output is 10
printf(“\n the value of k = %d”, **&p);

The expression *p is evaluated as : *p  *&k  k  10


In other way, it can be taken as : *p  *2020  k  10
The expression **&p is evaluated as : **&p  **4040  *2020  10
C-Family 154 pointers

So the expression *p indirectly accesses the k’s memory


So you always visualize the expression *p as k
Always see the expression *p as k, as p pointing to k
Whenever the expression *p found in the program, you treat like,
we are accessing k’s memory. (pointing memory)

Note: Address is an integer type value, to store such address pointers take 2-bytes memory.
Therefore, in C, all pointers occupy 2-bytes memory. Here p & q pointers occupy 2-bytes each.
Let us see some demo programs to get command over pointers and their applications and to know how the
pointers can be applied in programs efficiently.

Demo1
void main()
{ int k=10;
int *p; // here ‘*’ used to declare ‘p’ as a pointer
p=&k;
printf(“\n output1 = %d”, *p); //here ‘*’ used to get value of k
*p=20; // here ‘*’ used to assign value 20 to k
printf(“\n output2 = %d”, *p); // here ‘*’ used to get value of k
printf(“\n output3 = %d”, k);
}

Output: output1 = 10 P k (*p)


2020 10
output2 = 20 4040 2020
output3 = 20
Here the purpose of the instruction ‘int *p’ is to declare p as a pointer variable. So here, the purpose of
‘*’ is to specify the p as a pointer variable instead of normal variable.
The expression ‘*p’ in printf() statement accesses the k’s memory
When the p is assigned with ‘&k’, it can be called as “the pointer p is pointing to k”, this is visualized as
above figure.

Demo2
This demo program tells how two pointers can points to same location.

void main()
2020
{ int k=10, *x, *y; X 4040
x=y=&k; // both pointers x, y is assigned with &k K
printf(“\n output1 = %d %d”, *x, *y); 10
*x=20; Y 2020 2020
*y=30; 5050
k=40;
printf(“\n output2 = %d %d %d”, *x, *y, k);
}
Output1: 10 10
Output2: 40 40 40
*Any number of pointers can points to one variable (one location), if the value is changed through one
pointer then the other pointers also gains changed value.
*Here both pointers x,y pointing to the same location ‘k’. Hence k’s memory can be accessed in three ways
using direct access k, using indirect access *x, and *y; here *x, *y, k  accessing same location(k).
C-Family 155 pointers

Demo 3
This demo program swaps two values using pointers.

void main()
{ int k1=10, k2=20, *x, *y, t; X K1 (*x)
x=&k1; 2000 10
y=&k2; 4000 2000
t=*x; // t=k1; Y K2 (*y)
*x=*y; // k1=k2; 3000 20
6000 3000
*y=t; // k2=t;
printf(“\n output1 = %d %d”, *x, *y);
printf(“ \n output2= %d %d”, k1, k2);
}
Output:
output1 = 20 10
output2 = 20 10

Demo 4
Demo program for swapping two pointers and it is just like swapping two integer values.

void main() Before swapping


{ int k1=10, k2=20, *x, *y, *t;
X K1
x=&k1; &k1 10
y=&k2; 2000 4000
t=x; Y K2
x=y; &k2 20
y=t; 3000 5000
printf(“\n output1 = %d %d”, *x, *y );
printf(“ \n output2= %d %d”, k1, k2 ); After swapping

} X K1
Output: &k2 10
output1 = 20 10 2000 4000
output2 = 10 20
Y K2
&k1 20
3000 5000

Initially x,y holding address of k1,k2; after swapping x & y, ‘x’ redirected to k2, ‘y’ to k1.
In this way we can change the pointing address while running a program. Let us have one more example

Demo 5
Expect the output of following program.
void main() X K1 K2
{ int k1=10, k2=20, *x; &K1 10 20
x=&k1;
*x=30;
x=&k2; X K1 K2
*x=40;
&K2 10 20
printf(“\n %d %d %d %d”, *x, k1, k2);
}

Here the pointer ‘x’ initially pointing to ‘k1’, later it is changed to point ‘k2’;
so the expression “*x” accesses the memory which is currently pointing to.
C-Family 156 pointers

Demo 6
Expect the output of following program.
void main() x K1
{ int k1=10, k2=20, *x, *y, t; &k1 10
x=&k1;
Y K2
y=&k2;
&k2 20
*x=*x+*y;
*y=*x+*y;
printf(“ \n output2= %d %d”, k1, k2);
}

Demo 7
Expect the output of following program X Y K
void main() &k &k 10
{ int k=10, *x, *y;
x=&k;
y=x;
*y=55;
*x=66;
printf(“\n %d %d %d %d”, *x, *y, k);
}

Demo 8
Expect the output of following program
void main()
{ int k1=10, k2=20;
int *x,*y;
x=&k1;
y=&k2;
printf(“\n enter any two values “);
scanf(“%d%d”, x, y); // passing x, y values to scanf(), which are nothing but &k1 , &k2
printf(“\n %d + %d = %d”, k1, k2, *x+*y);
}
C-Family 157 pointers

Types of pointers (address types)


Some people confused over pointer and an address, actually, it is something like a variable and its holding
value. Similarly, pointer holds address, therefore, we can treat pointer is nothing but address.
Already we discussed before about address types, now we deal with more detailed.
Pointers are derived types as they can be derived from any existing data-type. By adding a symbol star (*) to
the any existing data-type, it becomes as pointer-type.
The data type “int*” derives from “int”
“float*” derives from “float”
“char*” derives from “char”
“int**” derives from “int*”
“int***” derives from “int**”
Similarly all pointers can be derived in this way and these are infinite types.
For example: int *p; // the data-type of ‘p’ is ‘int*’
float *q; // the data-type of ‘q’ is ‘float*’

Here ‘p’ and ‘q’ are pointers of type ‘int*’ and ‘float*’ types respectively.
If there is any data type like ‘XYZ’ then ‘XYZ*’ will become pointer type.

In first version of C, the syntax to declare a pointer was


int* x, y, z; // x, y, z are ‘int*’ types

In next version, it was modified as


int *x, *y, *z; // the ‘*’ shifted before the name of variable

How much memory occupied by a pointer?


 As we know, address is like an integer number; hence, to store such address, 2 bytes is enough for the
pointer variables. In windows/unix based C-compilers pointers occupy 4-byte memory.
 In other point of view, only the first byte’s address is considered to be the address of a variable, so to
store such 2 byte integer value, so pointer requires 2 byte.
 In other words, irrespective of type/size of a variable, only the first byte address assigns to the respective
pointer, therefore, 2 bytes enough for any type of pointer.
void main()
{ int *p;
float *q;
char *x;
int k;
long int v;
printf(“sizeof(p) = %d”, sizeof(p) ); // sizeof(p) = 2
printf(“sizeof(q) = %d”, sizeof(q) ); // sizeof(q) = 2
printf(“sizeof(x) = %d”, sizeof(x) ); // sizeof(x) = 2
printf(“sizeof(&k) = %d”, sizeof(&k) ); // sizeof(&k) = 2
printf(“sizeof(&v) = %d”, sizeof(&v) ); // sizeof(&v) = 2
}
C-Family 158 pointers

Memory is a large collection of bytes, in which it is divided into several logical blocks called segments, and
each segment contains 65,535 bytes (64K) called offsets. The size of segment may vary from one to another
operating system. This is as given below
Segment 1 Segment 2 Segment 3 …

1 2 3… 64k 1 2 3… 64k 1 2 3… 64k

For example: int k=10; // Let us say, the variable ‘k’ allocated in 2020th offset of 3rd segment, then k address
would be 3:2020, but our programs print this address as a single number like 32020.

K  variable name
10  value
th rd
3 : 2020  allocated in 2020 offset of 3 segment
Conclusion: based on compiler and operating system, the pointer takes 2/4 byte.

Difference between one to another pointer


Even though all pointers occupy same size of 2 bytes to store address, they differ in two cases.
1. While accessing pointing value
2. While incrementing/decrementing the pointer (when accessing array elements through pointer)
Difference is, int* points to int,
float* points to float
Similarly, all pointers behave in this way
For example: int *p;
float *q;
Let us say here p&q is assigned with same memory address 2000, then see how they access

p
2000
3000 Byte1 Byte2 Byte3 Byte4 Byte5 Byte6...
2000 2001 2002 2003 2004 2005
*p
q
2000 *q
4000

Here the expression *p accesses the first 2-bytes of pointing memory like above picture.
Here the expression *q accesses the first 4-bytes of pointing memory like above picture.
As p is int* pointer, it access only first 2-byte memory as ‘int’ type.
As q is float* pointer, it access only first 4-byte memory as ‘float’ type.
in this way, pointer access pointing memory.
printf(“sizeof(p) = %d”, sizeof(p)); // sizeof(p) = 2
printf(“sizeof(*p) = %d”, sizeof(*p)); // sizeof(*p) = 2
printf(“sizeof(q) = %d”, sizeof(q)); // sizeof(q) = 2
printf(“sizeof(*q) = %d”, sizeof(*q)); // sizeof(*q) = 4
printf(“\n before incrementing, the address is =%u %u”, p , q); // say output 2000, 4000
p++; q++; // p increments by 2, q increments by 4
printf(“\n after incrementing, the address is =%u %u”, p , q); // output will be 2002, 4004
}
 sizeof() is an operator, which gives number of bytes occupied by a variable or expression.
 While accessing array elements using pointer, the incrementing/decrementing is required, where ‘int*’
increments by 2, ‘float*’ increments by 4 to access next value in the array. We will see later topics.
C-Family 159 pointers

**Precautions with pointers


Variable and its pointer must be matched, if not, then the pointer may access more or less bytes at pointing
time, resulting, the program may behave strangely such as showing garbage output or crashing of program.
Crashing of program means hanging or closing program abnormally in the middle of execution.
void main() k
p
{ int *p; &k
long int k=10; 2bytes 2bytes
p=&k;
printf(“\n output = %ld”, *p);
}
Did you observe?, here p is int*, k is long-int, even though k is long-int type variable, its address can be
assigned to int* pointer of p. At compile time, it shows a warning and not an error. But *p accesses the first
2byte of k out of 4byte, since it is an int* pointer. So pointers blindly access pointing value as its base type.
Example 2:
void main()
{ long int *p;
p K
int k=10; 10 Beyond
&k K memory
p=&k;
printf(“\n output = %ld”, *p);
}
output = unknown value (garbage)
Here the expression *p access 4 bytes of target pointing memory, first 2bytes belonging to k and rest of 2
bytes unknown memory beyond k. it is said to be illegal accessing, and often called memory leak error, or
pointer leak error. You don’t run this type of programs otherwise may crashed(closed in the middle of
execution).
Example 3:
void main()
{ int *p;
*p=20; // storing value 20 in unknown location, because ‘p’ not pointing to any variable.
----
}
Here ‘p’ has not been initialized with any valid address, so by default it contains garbage (unknown) address.
The expression *p=20 puts 20 in unknown location in the RAM, this is said to be illegal access and leads to
program crash.
Pointer conversion
In C programming, sometimes, we need to access one type of data from another type of pointer, where
pointer conversion is needed. Here pointer needed to be type-casted as per target pointing value. The
following example explains how ‘long int’ value can be accessed through ‘int*’ pointer.
void main()
p k
{ long int k=100;
&k
int *p;
2 bytes + 2bytes
p=&k;
printf("\n output 1 = %ld", *p);
printf("\n output 2 = %ld ", *(long int*)p);
} Type casting from int* to long int*
Output:
C-Family 160 pointers

output 1 = garbage
output 2 = 100
As we know, the expression *p access only first 2 bytes of k memory as p is int* pointer. For accessing total
value of k then p should be type-casted to long int*. This is shown in second printf() statement.

Printing address of a variable


Sometimes, we need to check the address of a variable while debugging a program, whether pointer is
pointing properly or not? To print address, use format string either %u or %p;
%u is unsigned-int format
%p is hexa-decimal format
void main()
{ int k=10, *p;
p=&k;
printf(“\n address of k =%u”, &k);
printf(“\n address of k =%u”, p);
printf(“\n address of k =%p”, &k);
printf(“\n address of k =%p”, p);
}
address of k = 65524
address of k = 65524
address of k = fff4
address of k = fff4

NULL pointer value


Is there any way to say that, the pointer is currently not pointing to any location? Yes we have, it is NULL
value of a pointer. We can initialize or assign a pointer with NULL value when it is not pointing any memory
location. The symbol ‘NULL’ defined in ‘stdio.h’ file with value zero, at compile time, the symbol NULL
replaces by zero wherever is used in the program. The usage of NULL is as follows
#include<stdio.h> // this file must be included
void main()
{ int *p=NULL; // int *p=0;
float *q;
---- P
NULL
----
2020
if(p==NULL) -----
{ --- ----

---
}
q=NULL;
---
}
C-Family 161 pointers

void* pointer (generic pointer)


It is a pointer of no-type, it can hold any type of address, but cannot be de-referenced without explicit type
casting, because, the compiler cannot determine what type of address holding by the pointer. The following
example explains how the ‘void*’ pointer can be used in the programming.
void main()
{ int k=10;
float f=20.45;
void *p;
p=&k;
printf( “\n value of k = %d”, *p); //error
printf( “\n value of k = %d”, *(int*)p); // converting ‘p’ to “int*”
p=&f;
printf( “\n value of f = %f”, *p); //error
printf( “\n value of f = %f”, *(float*)p); // converting ‘q’ to “float*”
}
In void* pointer, any type of address can be assigned to, so it is unaware what type of address currently it is
being held. As a result, the expression *p gives an error at first printf(). The ‘p’ cannot determine how many
bytes to be accessed at pointing location. If p is ‘int*’ pointer then it blindly access pointing memory as int,
and if p is ‘float*’ pointer then it blindly access pointing memory as float. Then how void* pointer can
determine? (so we need type costing)

Passing address to function


Passing address to a function is same as passing value to a function, but the receiving parameter must be a
pointer of same kind. Using pointer parameter, we can read/write/modify the argument’s value from called
function. Passing address to a function mechanism is often called call-by-reference.
void test( int *p);
void main() Main() function

{ int k=10; K
10 20
printf("\n before call = %d" , k);
2020
test(&k);
printf("\n after call = %d ", k);
}
void test( int *p) // int *p=&k; test() funciton

{ p
2020
*p=20;
4040
}
before call = 10
after call = 20
 When the test() function calls in main(), the ‘&k’ passes and assigns to parameter p,
thereby using p, we can read/write/modify the value of k from the test() function.
 The expression *p=20 assigns 20 to k.
 this calling mechanism is known as call-by-reference
C-Family 162 pointers

Arrays VS pointers
Pointers and arrays are closely related, the array expressions can be taken as pointer expressions, for
example X[i] can be written as *(X+i). The C developers provided these excellent facilities to handle arrays
using pointers. The compiler itself manages arrays as pointers.
In arrays, the array name itself without any index works as constant pointer variable, which gives the
address of first element. If X*+ is an array, then the expression ‘X’ gives address of first element ( &X[0] ).

The array expression X[i] can be taken in pointer notation as *(X+i)


So the expression X[i] is said to be array-notation and *(X+i) is said to be pointer-notation
thus &X[0]  &*(X+0)  X , therefore X  &X*0+; so the expression ‘X’ gives array-base-address.
Hence, the expression ‘array name’ without any index gives the address of first element which is
often called base-address of array.

For example: int X[5];


float Y[5];
X[0] X[1] X[2] X[3] X[4] Y[0] Y[1] y[2] Y[3] Y[4]
10 20 30 40 50 100 200 300 400 500
2000 2002 2004 2006 2008 4000 4004 4008 4012 4016

The expression X[0]  *(X+0)  *X


&X[0]  &*(X+0)  (X+0)  X  2000 (base address of x[] array)
Now the x[] array’s expressions can be taken as
X[0]  *(X+0)  *X  *2000  10
X[1]  *(X+1)  *(2000+1)  *(2002) 20 ( integer-address increments by 2)
X[2]  *(X+2)  *(2000+2)  *(2004) 30
Similarly X[i]  *(X+i)  *(2000+i)
but compiler implicitly takes X[i] as *(X+ i*sizeof(int))  *(X+i*2)

The float array y[] as


Y[0]  *(Y+0)  *Y  *4000  100
Y[1]  *(Y+1)  *(4000+1)  *(4004) 200 (float address increments by 4)
Y[2]  *(Y+2)  *(4000+2)  *(4008) 300
Similarly Y[i]  *(Y+i)  *(4000+i)
but compiler implicitly takes Y[i] as *(Y+i*sizeof(float))  *(Y+i*4)

Here X , Y acts as int* and float* pointers, when the index value is added to it, they increments depends
upon its base type. The int* increments by 2, float* increments by 4 ….etc, because to get next element in
the array, pointer has to be incremented in such way.
C-Family 163 pointers

Making a pointer to an array


Making a pointer to an array means, making a pointer to points to any one element in the array, because, a
single pointer cannot points to total array, it can points to only one element at a time. By incre/decr or by
adding index value to the pointer, the remaining elements are accessed. Let us see one example,
int x[5] = {10, 20 , 30, 40, 50};
int *p;
p=x; // p=&x[0];
Let us see, how the pointer ‘p’ is pointing to an array

P X[0] X[1] X[2] X[3] X[4]


2000 10 20 30 40 50
4000 2000 2002 2004 2006 2008

So the expressions *(p+0)  p[0]  *p accesses the x[0] // since *(p+0)  p[0]
*(p+0)  *(2000+0)  *2000  10

*(p+1)  p[1] accesses the x[1] // since *(p+1)  p[1]


*(p+1)  *(2000+1)  *2002  20

*(p+2)  p[2] accesses the x[2]


*(p+2)  *(2000+2)  *2004  30
The above figure can be imagined with the pointer “p” as
P[0] P[1] P[2] P[3] P[4]
P *p *(p+1) *(p+2) *(p+3) *(p+4)
2000 10 20 30 40 50
4000 X[0] X[1] X[2] X[3] X[4]

As per above figure, array expressions can be imagined as


*p  *(p+0)  p[0]  x[0]; Now x[0] == p[0]
*(p+1)  p[1]  x[1]; Now x[1] == p[1]
*(p+2)  p[2]  x[2]; Now x[2] == p[2]
Therefore x[i] == p[i]

Example2: if the pointer ‘p’ is pointing to a[2] then the expressions are as follows
int x[5] = {12,13,14,15,16};
p = &x[2]; P[-2] P[-1] P[0] P[1] P[2]
*(p-2) *(p-1) *(p) *(p+1) *(p+2)
P X[0] X[1] X[2] X[3] X[4]
2004 12 13 14 15 15
4000 2000 2002 2004 2006 2008

The expression *p  p[0], accesses the x[2]


The expression *(p-1)  p[-1], accesses the x[1]
The expression *(p-2)  p[-2], accesses the x[0]
The expression *(p+1)  p[1], accesses the x[3]
The expression *(p+2)  p[2], accesses the x[4]

Now the expression *(p+i) can be written in array form as p[i].


This is equal to x[i]. Thus, arrays and pointers are closely related .
C-Family 164 pointers

Demo program for printing array elements using pointer


void main()
{ int x[5] = {10, 20 , 30, 40, 50};
int *p;
p=x; // p=&x[0];
for(i=0; i<5; i++)
printf(“%d “, *(p+i) );
for(i=0; i<5; i++)
printf(“%d “, p*i+ ); // since p[i]  *(p+i)
for(i=0; i<5; i++)
{ printf(“%d “, *p );
p++; // increments by 2
} }
 The above three loops print the same output.
 Technically the first two loops are same and give same output. i.e., *(p+i)p[i]a[i]
 In the last for loop, the p advances to next element after every p++ operation, observe following figure

X[0] X[1] X[2] X[3] X[4]


10 20 30 40 50
2000 2002 2004 2006 2008

P After p++
2000 2002
4000 4000

Example for printing address of each element in the array


void main()
{ int x[5] = {1,2,3,4,5};
int *p;
p=x; // p=&x[0];
printf(“\n address of all locations are \n”);
for(i=0; i<5; i++)
printf(“\n %u - %u “, &x*i+, x+i);
for(i=0; i<5; i++)
printf(“\n %u - %u “, &p*i+, p+i);
}
Output: 2000-2000 2002-2002 2004-2004 2006-2006 2008-2008
Output: 2000-2000 2002-2002 2004-2004 2006-2006 2008-2008
C-Family 165 pointers

Passing one dimensional array to function


void main()
*P *(P+1) *(P+2) *(P+3) *(P+4)
{ int x[5]={1,2,3,4,5}; 1 2 3 4 5
display(x); // display(&x[0]); x[0] x[1] x[2] x[3] x[4]

}
void display(int *p / int p[] )
{ int i;
for( i=0; i<5; i++)
printf(“%d “, p*i+ OR *(p+i) ); p
OR &x[0]

for( i=0; i<5; i++, p++)


printf(“%d “, *p);
}
In the above program, when display() function is called, the argument ‘&x*0+’ is passed and stored into
pointer ‘p’. This is nothing but passing integer address to a function. The parameter ‘p’ can be declared in
two ways like int *p / int p[]. (these two declarations are same)

The first declaration ‘int *p’ makes some confusion whether the pointer ‘p’ is pointing to single-integer or
array-of-integers, so one cannot be determined immediately. Therefore, C providers gave 2 nd declaration.
But by seeing 2nd declaration int p[], one might think that ‘p’ is an empty-array, but actually it is also same as
int *p. This declaration gives a clear idea that, ‘p’ is receiving an array-address instead single integer address.

While developing big size applications, there exist many functions and all are messed up in the program.
The called-function may not be found at bottom of calling-function, it may exist in some other file, that is
why they recommend this array-like-pointer declaration “int p*+”. It gives clear idea that, p is pointer to an
array instead of single-value.

Let us have one example, filling values to array at called-function.


void main()
{ int a[3];
fill(a);
printf(“\n after filling, the values are \n”);
printf(‘%d %d %d“, a*0], a[1], a[2] ); // output: 10 16 9
}
void fill( int p[] or int *p )
{ p[0]=10;
p[1]=16;
p[2]=9;
}
Example2: following function takes array-address and number of elements as arguments, returns the big.
int findBig( int p[] , int n )
{ int i, big;
big=p[0];
for( i=1; i<n; i++)
{ if(big < p[i])
big=p[i];
}
C-Family 166 pointers

return(big);
}
void main()
{ int a[20], n, i, k;
printf(“enter number of input values to array :”);
scanf(“%d”, &n);
printf(“enter %d values to array:”,n);
for( i=0; i<n; i++)
scanf(“%d”, &a*i+);
k = findBig(a, n);
printf(“\n the biggest element = %d”, k );
}
input: enter number of input values to array: 5
enter 5 values: 45 17 88 44 3
output: 88

The ability to access calling-function’s array elements at the called-function using its base-address
provides convenience for moving multiple data items back and forth between functions shows the
excellence of pointers in C.

Pointer to pointer (multiple indirections)


A pointer which points to another pointer variable is known as “pointer to pointer”. In other words, if one
pointer is pointing to some memory location and that memory location in turn contained an address and it is
pointing to some other location is known as pointer-to-pointer. For example, to store the address of int
variable, the int* pointer is required, similarly, to store the address of int* variable, the int** pointer is
required.
This multiple indirections can be carried onto whatever extent desired, but more than two indirections are
rarely used. (In fact, excessive indirection is difficult to follow and prone to conceptual errors. Generally,
such pointers are not required in the programming).
These types of pointers are often used to handle multi-dimensional arrays.
Example for more than one indirection
void main()
{ int k=10;
int *p; // single indirection
int **q; // double indirection
int ***r; // triple indirection
p=&k; q=&p; r=&q;
printf(“\n output = %d %d %d “, k, *p, **q, ***r);
}
r q p K
6000 4000 2000 10
8000 6000 4000 2000

int*** int** int* Int

The expression ‘*r’ accesses the ‘q’, the ‘**r’ accesses ‘p’, the ‘***r’ accesses the ‘k’ value.

*r  q **r  *q  p ***r  **q  *p  k


C-Family 167 pointers

Array of pointers
In computer science, array of pointers are used vastly in the programming. I recommend practice more on
this kind of applications. Arrays, which can hold the collection of addresses is known as array of pointers.
For example, we can declare array of pointers as int *p[3] instead of int *p1,*p2,*p3.
Using this feature, we often handle 2D array data such as matrices, tables, with flexible and compact code.
“float *p*3]. Here p[0], p[1], p[2] are pointers of type ‘float*’ each. (array of float pointers)

Demo program for array of pointers P[0] P[1] p[2]


void main() &a &b &c
4000 4002 4004
{ float a=10.4, b=45.64, c=56.45;
float *p[3];
a b c
p[0]=&a; p[1]=&b; p[2]=&c;
10.4 45.64 56.45
printf(“ %f %f %f”, *p*0+, *p*1+, *p*2+);
}
output: 10.4 45.64 56.45
Let us see one more example
void main()
{ int *p[3], a[5]={1,2,3,4,5}, b[5]={6,7,8,9,10}, c[5]={11,12,13,14,15};
p[0]=a; p[1]=b; p[2]=c; // p[0]=&a[0]; p[1]=&b[0]; p[2]=&c[0];
for( i=0; i<3; i++)
{ for(j=0; j<5; j++) P[0] P[1] p[2]
2000 400 6000
printf(“%d “, *(p*i++j) ); 8000 8002 8004
printf(“\n”);
} 1 2 3 4 5
} 2000

output: 1 2 3 4 5 6 7 8 9 10
6 7 8 9 10 4000
11 12 13 14 15
11 12 13 14 15 16
6000
C-Family 168 pointers

Call by value vs Call by reference


In call by value method, the values of arguments are passed and stored into parameter. That is, a copy of
argument’s data is created in parameters at the called-function. Now, the data of arguments are said to be
original copy and parameters are said to be duplicate copy. So, if any changes made in parameters that
doesn’t affect the arguments. For example calling pow(), sqrt(), printf(), …etc. these functions follows the
call by value method.

In call by reference method, the address of arguments are passed and stored into corresponding pointer-
parameters. Now, using these parameters, we can read/write/modify the argument values.
For example, calling swap(), getDate() function, …etc. Let us see an example

Call by value does not work Call by reference works


void main() void main()
{ a b { a b
10 20 10 20
int a=10, b=20; int a=10, b=20;
printf(“\n before swapping = %d %d”, a, b); printf(“\n before swapping = %d %d”, a ,b);
swap( a , b); swap( &a, &b);
printf(“\n after swapping= %d %d”, a, b); printf(“\n after swapping= %d %d”, a,b);
} }
void swap( int x , int y) void swap( int *x , int *y)
{ int t; x y { int t;
t=x; 20 20 t=*x; x y
&a &b
x=y; *x=*y;
y=t; *y=t;
} }
Before swapping = 10 20 Before swapping = 10 20
after swapping = 10 20 after swapping = 20 10
The (a, b) values (10, 20) passed and stored into (x,y) The swap function pointers(x, y) are pointing to main
so if any changes made in (x, y) that does not affects function’s (a, b). So the expressions (*x, *y) indirectly
the values of (a, b) swaps the values of (a, b) .

As we know, using ‘return’ statement, we can return only one value from a function, because most of the
time we return only one value, therefore syntax provided in that way. So to return more values, pointers are
alternative. We can return indirectly through pointers. The above swap() function indirectly returns the
swapped values to main() function through pointers.
Let us see one example
Following function takes radius as argument and returns area & perimeter of a circle.
void find( float radius, float *p, float *q)
{ *p= 3.14 * radius *radius; // assigning indirectly to ‘area’ in main() fn.
*q=2*3.14*radius; // assigning indirectly to ‘circum’ in main() fn.
}
void main()
{ float radius, area, circum;
printf(“enter radius of circle :”);
scanf(“%f”, &radius);
find( radius, &area, &circum);
printf(“ area = %f”, area);
printf(“\ncircumference = %f”, circum);
}
C-Family 169 pointers

Here find() function is taking radius as input and calculating area & circum. These two values indirectly
assigning to main() function’s area & circum variables through p&q variables.

P q
&area &circum

area circum
34.56 10.45

Returning sum & product of 1+2+3…+N, 1*2*3…*N using function.


This example explains how the function find() returns the sum & product of 1 to N to the main() function.
This function returns sum and product indirectly through pointers.
Here ‘find()’ function takes arguments N along with address of variables which receives returning values.
void main()
{ int N=12, sum, product;
find(N, &sum, &product );
printf(“\n sum = %d , product = %d “, sum, product );
}
void find( int N, int *x, int *y)
{ int i, s=0 ,p=1; // here the local variables, ‘i’ for looping, ‘s’ for sum, ‘p’ for product.
for(i=1; i<=N; i++)
{ s=s+i;
p=p*i;
}
// following assignments, returns s, p values to sum, product in main() fn through pointers x , y.
*x=s; // sum=s; this is called returning indirectly
*y=p; // product=p;
}

Following function returns big & small in array of 10 values.


Write a function called findBigSmall(), which takes array base address & number of values in the array and to
return the big & small of them. Fill the body of following fn.
void main()
{ int a[10]={11, 34, 88, 49, 15, 66, 45, 23, 32, 17 }; // 10 values
int b,s;
findBigSmall( a, 10, &b, &s);
printf(“\n big = %d, small = %d”, b, s);
}
void findBigSmall( int a[] , int n , int *pBig , int *pSmall )
{ ------
------
}
C-Family 170 pointers

Advantages of pointers
1. Call by reference
 We can return more values from a function
 Passing array to function is possible only through call-by-reference
 If data is big like strings, structure, file then call by reference saves the time and space.
2. Dynamic memory allocation is possible only with the help of pointers.
3. Direct interaction with hardware and O/S is possible.
4. Pointers are the alternative to implement dynamic data structures.
5. Pointers make the program flexible, compact and fast execution
6. Through pointers it is easy to handle the data.

More about pointers


1. Some common ways of pointer pointing to
 Pointer to single variable
 Pointer to one-dimensional array
 Pointer to pointer
 Pointer to two-dimensional array
 Pointer to three-dimensional array…etc
 Pointer to function
 Pointer to structure
 Array of pointers

2. All pointers occupy equal number of bytes to hold address


int* pointer occupies 2 bytes
int** pointer also occupies 2 bytes
float* pointer occupies 2 bytes
char* pointer also occupies 2 bytes

3. The type difference between one to another pointer helps to determine the data type of target location
which the pointer pointing to
int* pointer points to int memory
float* pointer points to float memory
Similarly all pointers occupy in that way.

4. Incrementing/decrementing the pointer changes to one to another type


int* pointer increments by 2
float* pointer increments by 4

5. Some arithmetic and relational operations can be applied on pointers


 Adding or subtracting integral value to address is allowed like p+1, p-1, p+10 …etc
 Multiplying or dividing integral value to address gives no meaning
 Adding or multiplying or dividing two addresses has no meaning
 Subtracting two addresses has a meaning (If two addresses belong to one array)
For example, &x[6]-&x[2] givens the number of elements between locations.
 Comparison of two addresses is allowed
Note: If any operation has meaning on pointers then compiler allows such operation.
C-Family 171 pointers

Pointer to a function
Pointer not only points to a data, but also can points to a code. That is, a pointer can be made to points to a
function. So that using pointer, we can make function calls also. In C, every function is loaded in separate
memory location as it appears in C program. This location address is the entry point of a function, ie, it is the
first instruction address of a function. Using this address, we can shift the control from caller-function to the
called-function.
This approach seems to be unnecessary in general programming. Because in C, all functions are global, any
function can be called from anywhere in the program. However, it is possible to pass addresses of different
functions in different times to a function thereby making function-calls more flexible and abstract.
Syntax to declare a pointer to function
return-value-type (*pointer-variable-name) ( list-of-parameters-type);

Let us see some examples


① int (*p)(int,int)  here the pointer ‘p’ can pointing to a function of type ‘int fn-name(int,int )’
② void (*p)( )  here the pointer ‘p’ can pointing to a function of type ‘void fn-name( );
③ float (*p) (float, float,float)  it can pointing to a function of type ‘float fn-name(float, float, float);

To get the address of a function, use the function name without parenthesis and arguments that gives
starting address of a function. The following program gives a demo.
void test(); // function-declaration
void main()
{ void (*p)(); // pointer to function, which takes no arguments and returns no value.
p=test; // assigning tes() function address to ‘p’
p(); // calling test() function through ‘p’
(*p)(); // this is another style of calling the test() fn, old style.
}
void test()
{ printf(“\n Hello World”);
}

void (*p)(): this declaration is a pointer to function, this tells that ‘p’ is a pointer, which pointing to a
function, and that function takes no arguments and returns no value.

Example for calling function on user choice

int add(int x , int y) int multiply(int x , int y) int diviide(int x , int y)


{ { {
return x+y; return x*y; return x/y;
} } }
void main()
{ int n,v1,v2,result,ch;
int (*p)(int,int); //this is pointer to a function, which takes 2-int arguments and returns int value
printf("enter two values :");
scanf("%d%d", &v1,&v2);
printf("\n 1. Add \n 2. Multiply \n 3.divide 0. Exit");
printf(“\n enter choice :”);
scanf("%d", &ch);
C-Family 172 pointers

switch(ch)
{ case 1: p=add; break;
case 2: p=multiply; break;
case 3: p=divide; break;
case 0: exit(0);
}
result = p(v1,v2); // calling the function on user selected choice
printf("output = %d", result);
}

Demo program for passing function address to function

void y() void x ( void (*p)() ) void main()


{ { {
printf("hello"); p(); // calling y() fn through ‘p’ x(y); // passing y() fn ddress to x() fn
} } }
C-Family 173 Sortings

Sorting and Searching


The word sorting refers, arranging the data into either in ascending or descending order. The data may be an
integers, real numbers, strings, etc. In computer science, the task of sorting is major process in everyday life.
Therefore, there are several efficient techniques were invented, so programmer may relax from how to code
to sort elements efficiently. If data is in sorted order then searching will be easy, the search operation takes
less than log2N time.
1. Bubble sort.
2. Selection sort.
3. Insertion sort.
We have several other alternative techniques available (not covered in this book)

Bubble sort
In bubble sort, the adjacent pair of elements is compared one with next element, and placed into sorted
order by swapping disorder elements. ie, it compares a[i] with a[i+1], if a[i]>a[i+1] then swapping takes
place. In this way bubble sort works. Each pair we feel like bubble while comparing elements, therefore it
was called as bubble sort. The process will be as follows

Step1: In every iteration of loop, it compares a[i] with a[i+1], if any a[i]>a[i+1] then swapping takes place. It
compares and swaps from first element to last element. After this process, the biggest element will be
moved to last position and it is said to be sorted.

Step2: In second iteration of loop, compares and swaps for first N-1 elements as said in step1,
because, the last element already sorted in previous step. In this step, the second big will be moved to N-1th
position and it is said to be sorted. In this way, the bubble sort works.

Suppose, the values are 90 10 70 30 20 and in every cycle of loop is as follows


Before 1st iteration 90 10 70 30 20
Before 2nd iteration 10 90 70 30 20
Before 3rd iteration 10 70 90 30 20
Before 4th iteration 10 70 30 90 20
after 4th iteration 10 70 30 20 90 (90 sorted here)

Before 1st iteration 10 70 30 20 90


nd
Before 2 iteration 10 70 30 20 90
d
Before 3r iteration 10 30 70 20 90
rd
after 3 iteration 10 30 20 70 90 (70 sorted here)
These two passes sorts the last two elements in the array, in this way all elements are sorted
int bubbleSort( int a[] , int n )
{ int i, j, temp;
for(i=n-1; i>0; i--)
for(j=0; j<i; j++)
if( a[j] > a[j+1] )
{ temp=a[j];
a[j]=a[j+1];
a[j+1]=temp; // swapping elements
}
}
C-Family 174 Sortings

The main() function to test the bubble sort


void main()
{ int a[ ]={12 , 45 , 22 , 34 , 15 , 67, 19}, i; // 7 elements initialized
printf(“\n before sorting the elements are :”);
for( i=0; i<7; i++)
printf(“%d “, a*i+ );
bubbleSort(a,7);
printf(“\n after sorting the elements are :”);
for( i=0; i<7; i++)
printf(“%d “, a*i+ );
}
output: before sorting the elements are: 12 , 45 , 22 , 34 , 15 , 67, 19
after sorting the elements are: 12 , 15 , 19 , 22 , 34 , 45 , 67
Analysis of bubble sort
to sort 1st element (big), the inner loop takes n-1 comparisons
to sort 2nd element (second big), the inner loop takes n-2 comparisons
thus all iterations take
n-1 comparisons in 1st iteration.
n-2 comparisons in 2nd iteration.
---
2 comparisons in n-2th iteration.
1 comparison in n-1th iteration.
then total number of comparisons taken by if(a[j]>a[j+1]) is
n-1+n-2+.....+2+1  n *( n-1)/2 n2/2 (approximately)
but swapping takes extra time. If a[j]>a[j+1] is true then swapping occurs.
Then total no. of swapping is n2/2.
But each swapping takes 3 operations, then the total no. of operations are 3*n2/2.
Consider all the time, condition a[j]>a[j+1] may not be true then average swaps are (3*n2/2)/2  3*n2/4
Total no. of operation required for bubble sort= no. of comparisons + no. of swapping
t(n) = n2/2 + 3*n2/4 => 5*n2/4
t(n) = n2 (approximately)
So bubble sort takes n2 operations (instructions to be executed).

Bubble sort 2'nd method


Sometimes, the input array may be almost in sorted order except one or two elements. In this case, the
above algorithm takes unnecessary comparison in all iterations. For example, let us take 5 elements 12 18
39 55 40. Here by swapping last two elements, the total array gets sorted. So after completion of 1st
iteration of outer loop, the total array gets sorted and successive iterations would not be required. Using
following algorithm we can achieve this solution, here it stops the outer-loop when no swapping takes place
in inner-loop. However, this algorithm is suitable when we know the input data is almost in sorted order.
void BubbleSort2( int a[] , int n )
{ int flag;
for(i=n; i>0; i--)
{ flag=0;
for(j=0; j<i; j++)
{ if( a[j] > a[j+1] )
C-Family 175 Sortings

{ temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; // swapping


flag=1;
}
}
if(flag==0) break; //if no swapping occurred, then terminate loop.
}
}

Selection sort
In selection sort, first it finds the smallest element in the array, and exchanges it with the first position
element. Next it finds the second smallest element and exchanges it with the second position element.
In this way selection sort works. Let us take 5 elements: 90, 30, 70, 10, 20
After every pass of outer loop, the elements is as follows

st
Before 1 iteration 90 30 70 10 20

nd
Before 2 iteration 10 30 70 90 20

rd
Before 3 iteration 10 20 70 90 30

th
Before 4 iteration 10 20 30 90 70

After 4th iteration 10 20 30 70 90


void selectionSort( int a[ ] , int n )
{ int i, j, pos;
for(i=0; i<n; i++)
th
{ pos=i; // assume i'th element is i small, so take its position to ‘pos’
for(j=i+1; j<n; j++) // loop to find i’th small
{ if( a[pos] > a[j] )
pos=j; // if a*j+ smaller than assumed, then take its position to ‘pos’
}
th th
swap(&a[i],&a[pos]); // finally i small index in ‘pos’ , so swapping with i position element
}
}
Time complexity
 In the inner loop, the total no. of comparisons in all iteration takes as
n-1 comparisons in 1st iteration
n-2 comparisons in 2nd iteration
---
2 comparisons in n-2'th iteration
1 comparisons in n-1'th iteration
Then total no. of comparisons taken by if(a[pos] > a[j]) are
n-1+n-2+n-3+...+3+2+1(n-1*n)/2this is proportional to n2/2.

 But extra operations are required for finding smallest position.


That is, if a[pos]>a[j] condition is true then”pos=j” assignment takes place
So total no. of assignments are n2/2.
C-Family 176 Sortings

Consider all the time the condition a[pos] > a[j] may not be true ,then if we take average assignments
then it is n2/4.
 swapping elements in every outer-loop takes ‘n’ operations.
But swapping takes three operations, so it takes 3*n.

 Now total no. of operations =total comparisons + total assignments + total swapping
= n2/2 + n2/4 + 3 * n  this is proportional to n2

Difference between Bubble sort and Selection sort


In this two sorting techniques, the selection sort is always better than bubble, because in selection sort, the
no.of swapping are only N. Theoretically it cannot be proved.
2
No.of operations in both sorting takes n . But selection sort is the chocie for sorting files with huge records
and small keys(primary keys). For such application, the cost# moving the data dominates the cost of making
comparisons, and no algorithm can sort a file with substantially less data movement than selection sort.
Let us say file contain 1000 records, and each record * contains 20 fields then frequent swapping in the inner
loop of bubble sort takes lot of time. for example say, each field size is 45 bytes then 20*45 bytes of data has
to exchange in each record.
Where as in Selection sort, we are finding smallest record position and finally exchanging it with first
position. In this way the total no. of swapping is 'N', that is, swapping records occurs only N times. where as
in bubble, the average swapping occurs N2/4 times.
So Selection sort is always better than to Bubble.
*
Record : records is nothing but a collection of fields. for example customer record in a bank: Account holder name
account no account type sex age address balance
#
Cost: cost means time, here the time is calculated in terms of cost.

Insertion sort
Insertion sort inserts elements in proper places among those already in sorted order (these are sorted by
previous iterations of loop). It shifts all previous bigger elements to right band side, so that we get a gap to
insert new element in its proper position.
How insertion sort works?
Let us take first ‘k-1’ elements in the array (sub array) and assume these are already in sorted order (sorted
by previous iterations of loop). Now take kth element, compare it with previous position elements and shift
all bigger elements one by one to right hand side so that we get a gap, where insert kth element. These
inserted positions may not be final positions, as they have to be moved again to make a room for further
smaller elements, which may be encountered later.
Let us observe following elements:
10 12 16 18 19 34 14 30 35 38 55 58 40 60

For easy understating, let us take two elements 14 & 40 have to be sorted. Now take 14 and compare with
previous elements one by one and move all bigger elements (34, 19, 19, 18, 16) to right side, so that we get
a gap at 16 element place, where insert 14. In this way, insertion sort works. But this process starts from
2nd element.

Note: While comparing and moving preceding elements to right side, if any element is found to be smaller,
stop the process. Because, all the remaining preceding elements are also smaller as they already sorted by
previous cycles, now insert the picked element in the vacant room.
C-Family 177 Sortings

Step by step procedure to sort elements (algorithm)


Step1: Pickup a[1], compare it with previous element a[0]. If a[0] > a[1], then shift a[0] to right side and
insert a[1] in place of a[0].
Step2: Now first two elements themselves in sorted order, pickup a[2], compare it with previous elements
a[1] & a[0], if bigger than a[2], then shift it to right side and then insert a[2] in the gap.
Step3. Repeat this process for all remaining elements.

void insertion Sort ( int a[], int n)


{ int temp;
for(i=1; i<n; i++)
{ temp=a[i]; // saving picked element in temp
for(j=i-1; j>=0; j--) // loop for comparing previous elements
{
if(a[j] > temp) // if previous element is big then
a[j]=a[j+1]; //move it to right
else
break; // if previous element is small then stop the loop
}
a[j+1]=temp; // insert element in rightful (gap) place
}
}
Analysis of insertion sort
Best case: If input data already in sorted order then insertion sort takes only O(N) time only, because the
inner loop each time terminates immediately by break. So the total No. of operations time is O(N).
Average case: If input data is randomly distributed then insertion sort takes approximately N2/2.
(The inner loop terminates in the middle by break).
Total no. of comparisons are n2/2, if we take average then it is n2/4 (because loop may stopped in middle)
so It uses about N2/4 comparisons and N2/4 moves on the average.
So total no.of operations is N2/4 + N2/4  N2/2.
Worst case: If input data is in reverse order (descending order) then insertion sort takes N2 operations.
Because the inner loop will not be terminated in the middle
Then no.of comparisons are N2/2 + no. of moves of data are N2/2. T(N) = O(N2).
Finally, the running time of insertion sort depends on the total number of inversions (reverse order of
elements) in the file. But this takes less time than Bubble and Selection sort.

Comparison with other sorting techniques


Insertion sort is the best, when compared with selection and bubble sorts, because, in the average case
insertion sort takes only N2/2 units of time. It is difficult to prove theoretically, but practically insertion sort is
the best. But bubble and selection takes n2 units of time, if input is in any order.

In Other Cases: When the records are large size in file, then amount of time to move the data one place to
another place takes a lot of time, in this case selection sort is better than insertion sort, because selection
sort takes only N swaps.
Suppose in case of keys are strings then comparison of strings takes a lot of time than moving data one place
to another place. In selection sort no. of comparison greater than insertion sort, so in this case, insertion
sort is the best even though records are large size. (Courtesy book: algorithms by Robert Sedgwick)
C-Family 178 Sortings

Searching techniques
Searching is the process of finding required key element in the group of elements.
We haves several techniques in computer science, the two basic techniques are
1. Sequential or linear search
2. Binary or two-way search

Sequential or linear search


Sequential means one after one, in this search, the elements are compared one by one in the array, if
anywhere, the search-key value is found, it returns the index position of such element, otherwise returns -1.
Here array elements may or may not be in sorted order. For example, searching for 89 in the following
array, it will find at 5th index-position (6th element) in the array sequence
int linearSearch( int a[], int n, int key)
{ int i;
for(i=0; i<n; i++)
23 34 56 32 78 89 53
{ if( a[i]==key ) A[0] A[1] A[2] A[3] A[4] A[5] A[6]
return i;
}
return -1; 89
} key

void main()
{ int a[200], n, i;
printf(“enter number of input values to array :”);
scanf(“%d”, &n);
printf(“enter %d values to array:”,n);
for( i=0; i<n; i++)
scanf(“%d”, &a*i+);
printf(“\n enter element to search :”);
scanf(“%d”, &key);
k=linearSearch(a, n, key);
if(k ==-1) printf(“\n not found”);
else printf(“\n element found at %d position”, k+1);
}

Binary search
The linear search is used when input file is small or elements are not in sorted order, it takes 0(n) time.
If elements are in sorted order, the binary search is the best choice, it takes <log2(n) time.
Step1: In binary search, the array is divided into three parts at middle position, the left sub-array, middle
element, right sub-array.
Step2: If middle-element==searchKey, it returns index of middle-element and stops the process.
Step3: If middle-element < key, it continues search in left-sub-array as said in step-1.
Step4: If middle-element > key, it continues search in right-sub-array as said in step-1.
step5: Repeat step1 to step4 until left/right sub-array partition becomes<1 element.
C-Family 179 Sortings

Time Complexity of binary-search,


Let array has N elements, and assume the N is almost equal to 2K ( N ≈ 2k )
At cycle1, the array size is N  (2K )
At cycle2, the array size is N/2  (2K-1 )  because at cycle2, we search in left/right sub-array.
At cycle3, the array size is N/4  (2K-2 )
After cycle K, the array size is 1  20
so it takes totally ‘K’ cycles, so total comparisons are: 1+1+1+ …k times (K comparisons)
But we have to express total comparison in ‘N’ value (not in K), by applying log in both sizes
N ≈ 2k  k=Log2(N) , so finally binary search takes Log2N comparisons in worst-case.

key
57

Low high
12 16 28 33 38 43 48 50 57 79
A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9]

key
57

Low high
43 48 50 57 79
A[5] A[6] A[7] A[8] A[9]

key
57

Low high
A[8] A[9]
57 79

Source code for binary search


void main() int binarySearch( int a[], int N, int key)
{ int a[200], n, i; { int mid, low, high;
printf(“enter number of values to array :”); // the lower limit of array is 0, and higher limit is N-1
scanf(“%d”, &n); low=0; high=N-1;
printf(“enter %d values to array:”,n); while( low<=high) // repeat until partition size <= 1
for( i=0; i<n; i++) { mid=(low+high)/2;
scanf(“%d”, &a*i+); if( key==a[mid] )
bubbleSort( a , n ); // sort values before searching return mid;
printf(“\n enter element to search :”); else if( key < a[mid] )
scanf(“%d”, &key); high=mid-1; // search in left sub array
k=binarySearch(a, n, key); else
if(k ==-1) low=mid+1; // search in right sub array
printf(“\n element not found”); }
else return -1;
printf(“\n element found at %d position”, k+1 ); }
}
C-Family 180 storage classes

Scope, Accessibility & Storage Classes


Scope of variable
before knowing about storage classes, first we should discuss about scope and accessibility. Scope is the
region, where the variable is available and accessible. In C program, scope is of two types: local, global. The
entire program belongs to global scope, whereas a smaller region bounded by a pair of braces {} is known as
local scope.

Local scope: In C program, we can declare variables anywhere in the program, but they must be defined
just immediate of block-open. This block may belong to if-else, while-loop, for-loop, or function. Such
variables scope belongs to that block and cannot be accessed outside. These are often called local/private
variables. See the following program.
Example1: void main()
{
{
int k=100;
}
{
printf(“\n the value of k = %d”, k); // error
}
}
At compile time, we get an error called un-defined symbol ‘k’ at printf(), because the ‘k’ belongs to first
inner block and cannot be accessed in 2nd inner block.
Example2: void main()
{ // say it is outer block
int x;
{ // it is inner block
int y;
x=100;
y=200;
}
printf(“\n the value of x = %d, y=%d”, x, y); // error at ‘y’.
}
At compile time, we get error “undefined symbol y” at printf(), because the inner-block variable can’t be
accessed in outer block ( out of scope)

Example3: void main()


{ int k=10;
show();
}
void show()
{
printf(“%d “ , k); // undefined symbol ‘k’
}
Here the variable ‘k’ declared in main() fn, it cannot be accessed in show() fn, as it is local to main() fn.
C-Family 181 storage classes

Overriding of variables
If any two variables are declared in inner and outer blocks with the same name, then two copies will be
created in the program, the outer-block variable is overridden by the inner-block variable when the control
presents in the inner-block. That is, if the control is in inner-block, then the preference is given to inner-block
variable.
void main()
{ int k=10;
{ int k=20;
{ int k=30;
printf(“ k = %d “, k);
}
printf(“ k = %d “, k);
}
printf(“ k = %d “, k);
}
Output: k=30 k=20 k=10

Storage classes
For big applications, the code is certainly split into several functions and these functions may be distributed
into several files. During the execution, the control jumps from one function to another function. In such
case, some variables are required to access across different places in the application. According to presence
of control in one part, some variables are needed to be visible and some are invisible, this can be achieved
by storage classes.
A variable that defined in the program possesses some characteristics such as data type and storage class.
Data type tells the size and type of the value, whereas storage class tells the behavior of a variable, such as
initial-value, scope, life-span and storage-place. Scope means region in which the variable can access. We‘ve
already discussed it. The initial value is zero/garbage. The life span specifies when the variable comes into
existence and when it goes off (when it is created & when it is destroyed).
We have 4 storage classes 1.auto(automatic), 2.register, 3.static, 4.global.
For example: auto int x,y,z; // now the storage class of x, y, z is auto
register long int a,b,c; // the storage class of a, b, c is register
static float p,q,; // the storage class of p, q is static

The auto & register are temporary variables, whereas static & global are permanent variables.
The program’s memory divides into code & data area, the code area contains instructions whereas data area
contains variables, string-constants, etc. The data area is again classified into stack & heap area. The stack is
the place where temporary variables are stored & managed, and in the heap area, the permanent variables
are managed. (The stack & heap are predefined Data Structures in OS level).

the program’s data area is again divides and loads into memory as
Global Static String Auto /*Register Function
variables variables constants… variables variables */ return-address
Heap Area (permanent variable’s area ) Stack Area (temporary variable’s area)

The temporary variables create in stack area, whereas permanent create in heap area.
By default, stack variables contain garbage values, whereas heap variables contain zeros.
C-Family 182 storage classes

For example: auto int x; // ‘x’ contain garbage value


static int y; // ‘y’ contain zero value

Auto (automatic)
example: auto int x, y, z; //this is equal to int x, y, z;

If any variable is declared inside a block, by default, it is auto storage class. So the keyword ‘auto’ is optional
for all local variables. Of course, from the beginning of this book, we have been using ‘auto’ variables.
Initial value: garbage is the initial value. (If not initialized with any value)
Scope: this variable can access only within the block in which it is declared, ie, we cannot access outside
(but using pointers, we can access indirectly from outside of block)
Life: it is also belongs to a block as long as the control presence in that block. ie, when control enters into
a block, all auto variables gets created (life starts) and when control leaves the block, all such variables
gets destroyed (life ends).
void main()
{ test(); // calling 3 times
test();
test();
}
void test()
{ auto int k=10; // memory space of k is created here, when the function starts
printf(“ %d “, k);
k++; // no use of incrementing before dying ( just for demo this is given)
} // memory space of k will be destroyed here, before returning from function
output: 10 10 10
The variable ‘k’ will be created & destroyed 3 times upon calling test() function 3 times. When the control
enters into the test() function body, the ‘k’ will be created & initialized with 10 and when the control leaves
the function, the ‘k’ will be destroyed. Hence the output is 10 10 10.
Of course, it is meaningless to survive the ‘k’ in the memory after finishing of function task. Therefore, all
auto variables will be destroyed before closing the function. But rarely some variables are needed to be
survived, where the static class is the choice.

Static
The static is created just before start of program (before main() fn starts) and survived till end of program,
used to access/share previous call of function values for next subsequent calls. Unlike auto, the static is
used to preserve the values even after closing the function. The static persist the values among several calls
of function. It will not be recreated & reinitialized in every call of function. Only once the variable is created
and exists until the total program is terminated. Scope belongs to local as auto, but initial value is zero.

void main() void test()


{ test(); { static int k=10;
test(); printf(“ %d “, k);
test(); k++;
} }
output: 10 11 12
The instruction static int k=10 executes only once when the program loads into memory(just before main()
fn starts) whereas, the instruction printf(“ %d “, k); k++; executes 3 times for 3 function calls.
C-Family 183 storage classes

Example2
void main()
{ int i;
for(i=0; i<10; i++)
{ auto int k1=10;
static int k2=10;
printf(“\n %d %d”, k1, k2);
k1++;
k2++;
}
}
output: 10 10
10 11
10 12 …
Note: variables can be declared anywhere in the program but they must be immediate of block open(first
line of block open). These blocks may belong to any control structures such as while-loop, for-loop, etc.

Register
Register is a small memory unit available in the processor (ALU) itself, before doing any arithmetic operation,
the values are copied from RAM to registers and then given operation takes place, because RAM does not
support bit by bit operations to do respective sum and also technically not possible. We know that, only 3 to
5 registers available in processor and always 1 or 2 are busy. So other unused registers can be used for our
variables, so that, they can have faster access. It saves the time to load & unload variables between RAM &
register. This is very much suitable for frequently used variables like loop variables.
Only temporary integral types (char, int, long) are allowed as registers. The floating point types, arrays,
pointers, static types are not allowed. Anyway, the keyword register is not a command, is just a request to
the compiler, because, if registers are not available then space allocates in the RAM. The other behavior
like scope, life, initial value is same as auto type.
Example: register int a, b ,c , d, e;
register float x, y, z; // error, float are not allowed

In above declaration, all (a, b, c, d, e) may not be allocated in the registers, because, we have limited number
of registers. The x, y, z cannot be taken as register as they are float type.

Registers in Circuits of
RAM Processor Processor ALU
Byte1 Byte2 Byte3 …. AX Addition circuit
BX Subtraction circuit
CX Multiplication circuit
DX ……
C-Family 184 storage classes

Global
As we know, one function’s local variable can’t be accessed in another function, but sometimes, some
variables need to be accessed throughout the program (in several functions) then it should be declared
global scope(outside of all blocks). Global scope is the region that doesn’t belongs to any specific function or
block, it belongs to entire program. Global variable preferably declared at the beginning of program or in a
separate file. These variables life span is until the total program exit(same as static). The word global is not a
keyword and hence it is not required while declaration of variable.
int k; //now the ‘k’ is global and default value is zero
void main()
{ printf(“ k = %d”, k);
test();
printf(“, k = %d”, k);
}
void test()
{ k++;
}
Output: k=0, k=1
the variable ‘k’ is now global and can be accessed (shared) in both functions.
The static & global variables life-scan is same but scope is different.

Extern (proto-type)
If program is very big, obviously its code may distribute into several files and each file may contain several
functions. Here, each file can be compiled independently and produced object file, later all produced object
files can be linked together. In this compilation process, we get some problems. If one file uses global
variable but it is declared in another file then we get undefined-symbol errors. To avoid this type of errors,
we need to specify the proto-type of global variable using keyword extern.

Program file1: “dis.c” Program file2: “main.c”


extern int num; // not declaration, it is a proto-type int num=14; //declaration of variable
void display() void main()
{ printf(“ experience =%d”, num); { display();
} }

After compiling the 1st and 2nd program files separately, the object code for those files will be created with
the file names “dis.obj” and “main.obj”. Suppose, if we are using Turbo C, then the command line usage of
the compiler will be as follows
tcc –IC:\tc\include –c dis.c
tcc –IC:\tc\include –c main.c
Here “–I” specifies the include path of library functions, and “-c” is for only compilation.
Suppose if we are using C on UNIX system, then the method for using the compiler ‘cc’ is
cc –c dis.c //-c is for only compilation and not creating machine code file
cc –c main.c
the above two commands will create the object files “dis.obj” and “main.obj” respectively. (in Unix it is dis.o
and main.o) Now link these object files using the linker command. (Generally, the compiler itself can handle
the linking job). The command line usage of the TCC will be as shown in the below example:
TCC –Lc:\tc\lib main.obj dis.obj
C-Family 185 storage classes

here –L specifies the library files path. To do the same with UNIX’s CC
CC main.o dis.o final.exe
The above command will create the executable binary file with name “final.exe”
This extern keyword can also be used with function proto-types. This is especially when we want to access a
function that is defined in other files or external pre-compiled modules. For example
Program file1: “dis.c” Program file2: “main.c”

void display() extern void display(); // declaration of function


{
void main()
printf(“ experience =%d”, num);
{
}
display();
}

File scope (this is out of your syllabus)


File scope variables are local to the file, they cannot be accessed outside of file. Usually, file scope variables
are declared at the beginning of file, so that, they can be accessed all functions within the file. These
variables are declared using static keyword. (Do not confuse with global variables & static variables)

Program file1: “dis.c” Program file2: “main.c”


extern void display();
extern int exp; // not declaration , it is a proto-type
static int exp=14; //global to this file only

void display()
void main()
{
{
printf(“ experience =%d”, exp);
display();
}
}

If we compile these two files separately, we don’t get any error, but at linking time, we get an error called
“undefined symbol exp” in display() function. Because the variable “exp” is local to “main.c” file, since it is
declared as static, therefore it is not accessible other than this file.
C-Family 186 pre-processor directives

Preprocessor Directives
The preprocessor, as its name implies, is a program, which performs some kind of text manipulations just
before compilation begins. It provides some facilities like automating repeated constants, simplifies complex
math equations by giving shortcuts, providing conditional compilation, combining two or more files…etc.
Actually, the compiler does not have these features in built; this is an additional tool kit, which helps the
programmer.

In real life programming, it is mandatory to symbolize the repeating constants, so that they can be easily
remember and modify. For example: #define PIE 3.14; Wherever the pie value 3.14 is required, we can
use PIE symbol, so it is easy to remember and modify, similarly we can simplify repeated expressions in a
short form, for example: #define sum(x) (3*x*x+4*x+5)

Generally, we break down a big application into several functions and we write in several files, later these
files are combined using #include directive. This directive combines two or more files into a single file.
All preprocessor directives start with #(hash) symbol, and we can use these statements anywhere in the
program. the following statements are used #define , #include , #error , #line , #if , #else , #endif , #elif ,
#ifdef , #ifndef , #undef

Remember, the pre-processor directive manipulates the source code file before compilation begins; it
replaces every directive with its replacement string and such file is given to the compiler. So, the compiler
does not know about #define, #include statements. The following gives idea how the pre-processor and
compiler works.

#include<stdio.h> void main()


#define PIE 3.14 { ------
void main() Source program after
{ ------ pre-processing Machine code file
Pre-processor compiler
source program ----
before pre-processing ----
------ ----
} }

Defining macro as symbolic constant


For example, we are writing a big application, where we need to use pie value 22/7 (3.14) in many times,
after completion of code, if this value need to be changed 3.14 to 3.15 then it takes lot of time to modify in
all places. If we missed to modify one or two places then it gives wrong output. In such situations we think
for a solution, it would be good, if it modified in one place, will affect to the total program. For that #define
is the alternative.
#define as macro directive:
the syntax is: #define macro–name replacement-expression

This macro directive defines a macro-name for a given replacement-expression. The replacement-expression
is substituted in every occurrence of macro-name in the source file. The replacement-expression can be
anything like constant, expression, string, etc. Let us observe the following examples.
Example1: Following program calculates the area & perimeter of circle for a given radius.
#define PIE 3.14 // do not give semicolon at end
void main()
{ float area, perimeter, radius;
printf (“enter the radius:”);
C-Family 187 pre-processor directives

scanf (“%f”, &radius);


area = PIE *radius*radius;
printf (“area of the circle is %f\n”, area);
perimeter = 2*PIE*radius;
print f(“perimeter of the circle is %f\n”, perimeter);
}
Example2: Let us see how macro-name replaced with its replacement-expression
#define ONE 1 After pre-processing, the program is
#define TWO ONE+ONE void main()
#define THREE TWO+ONE {
#define PF printf printf(“\n %d “,1);
void main() printf(“\n %d “,1+1);
{ printf(“\n %d “,1+1+1);
PF(“\n %d “,ONE); }
PF(“\n %d “, TWO); Observe that, macro statements vanished
PF(\n %d “,THREE); by the preprocessor, so the compiler does
} not know about these directives

Note: if any word found to be capital letters in the C/C++ programming, it definitely a macro-name, it is the
convention for the C/C++ programmers, so that, one can easily identify macros easily. So, I strongly
recommend follow this rule who ever use macros. It is usually best to put all #define declarations at the
start of the program or in a separate header file rather than placing all over the program.

Defining macro like function


The #define directive has another powerful feature, which can be used as simple function in the program.
Generally, it is used for simple mathematical equations, complex expressions and for simple functions. The
macro function can have parameters and these are substituted at the time of pre-processing.
Syntax: #define macro-name(parameters) replacement-expression-with-parameters
Example: defining roots of quadratic equation

#define root1(a,b,c) ((-b+sqrt(b*b-4*a*c))/(2*a)


#define root2(a,b,c) ((-b-sqrt(b*b-4*a*c))/(2*a)
Let us see one more example
#define sum(x,y) (x+y) #define sum(x,y) (x+y)
void main() void main()
{ {
printf(“\n %d”, sum(4,5) ); Code after printf(“\n %d”, (4+5) );
printf(“\n %d”, sum(4,5)*sum(1,2 ) ); pre-processing printf(“\n %d”, (4+5)*(1+2) );
} }

Advantages of macro over function


 Macros does not make any function calls, instead it paste the replacement-expression in every use of
macro. Hence we can avoid over-head of function calls. As we know, the function call consumes extra
space and time for jumping & returning the control, creating & destroying of local variable’s space...etc.
For simple functions, this time dominates the task of function. In this case, it is better to convert into
macro, so that, we can save time & space. Simple function means having one to two lines of code.

 No need of specifying data types for the parameters, hence, we can use same macro with different data
items. For example, the above macro sum(x, y) works with all data types like sum(4.5, 5.4) of float type.
C-Family 188 pre-processor directives

Disadvantages with macros


 If macro replacement-expression is bigger, containing more lines of code and used many times then the
size of machine code file will be increased, because, in every usage of macro the replacement-expression
will be pasted. In this case, normal function is the choice.
 There is no syntax error checking for macros, so it blindly pasts the replacement-expression.
For example
#define sum(x) (x$x)
void main()
{ printf(“ output = %d”, sum(5)); // here macro pasts as (5$5)
}
Here by mistake, the user has given the ‘$’ instead of ‘+’, but macro blinds pastes without checking any
error. As a result, the compiler shows an error at printf() statement.
Let us see another example,
#define sum(x) x+x; // this semicolon creates a problem
void main()
{ int k;
k=sum(4)*sum(5); // the compiler shows error at this line
printf(“%d “, k);
}
Here the expression k=sum(4)*sum(5); replaces as k=4+4;*5+5;; // so this semicolon creates a problem.

#include directive
It is used to join the contents of one file into another file, we have 3 syntaxes
syntax1: #include “file name”
syntax2: #include ”path + filename”
syntax3: #include <file name>
The first syntax is used, when the include file is in current working directory.
The second syntax is used, when the include file is in some other directory.
The third one, when the include file is in C-software directory.
For example:
here the file “main.c” contained main-program, “sub.c” file contained sub-program and the sub-file should
be included as

Sub file “sub.c” File name “main.c” File name “main.c”


Code after int fact( int n)
int fact( int n) #include “sub.c” pre-processing { int f=1;
{ void main() while( n>1)
long int f=1; { f=f*n--;
while( n>1) printf(“%d”, fact(5)); After pre-processing, return(f);
f=f*n--; } the sub.c file’s code }
return(f); is pasted in main.c as
} void main()
{
printf(“%d”, fact(5) );
}
this file is given to compiler
These two files will be clubbed into single and then given to the compiler (as shown above). In this way, we
can attach as many files as we want in the program. The sub file (include file) can have many functions but
required (called) function only be attached to the executable file. In this manner, the C-header files contain
proto type of all functions and we must include for avoiding errors in the program.
C-Family 189 pre-processor directives

Conditional Compilation
It is possible to compile selected portions of your program’s source code. This process is called conditional
compilation and it is used widely by commercial software houses that provide and maintain many
customized versions of one program.
As we know, these days, all commercial software designed keeping in mind all the aspects of related
organizations in nature. For example, one bank’s software can be utilized in another bank with a few
modifications. We cannot determine and finalize all the details of an application at the time of program
development, for example, regarding of OS, hardware, services,…etc. Therefore, while developing software,
the programmer must predict all possibilities that occurs later stages, thereby, it is needed to write the code
for all possibilities so that we can add, remove, or modify the code according to the organizations required
by the customer(client) before installation of software. In this way, the generic program can be changed
according before delivering software with help of preprocessor. Let us see one example

#define COUNTRY 1 // 1-India, 2-US, 3-France, 4-England,…

#if COUNTRY==1
char curr*+=”Rupees”;
#elif CUNTRY==2
char curr*+=”Dollor”;
#else
char curr*+=”No currency defined”;
#endif

void main()
{ printf(“our currency = %s”, curr);
}
By changing country code in first line, the corresponding currency name is applied to the ‘curr[]’

#ifdef, #ifndef and #undef


These is another method of conditional compilation, used to check whether a given symbol is already
defined with #define or not. Based on this decision, we can add/subtract some code while compiling.
The Syntax is as follows
#ifdef maco-name
statement1
statement2

#endif

example1 example2
#define SIZE 100
#ifndef SIZE
#ifndef SIZE #define SIZE 200
#define SIZE 200 #endif
#endif
void main()
void main() {
{ printf(“\n the size = %d”, SIZE);
printf(“\n the size = %d”, SIZE); }
}
Output: the size = 100 Output: the size = 200
Example 3: Let us see one more practical example
C-Family 190 pre-processor directives

File name “main.c” Sub file “factorial.c”


#include “factorial.c” long int fact( int n)
#include “factorial.c” {
void main() long int f=1;
{ while( n>1)
printf(“factorial = %ld”, fact(5)); f=f*n--;
} return(f);
}

In the above program, unfortunately the “factorial.c” file is included two times. At compile time, the
preprocessor includes two copies of “factorial.c” file code in the program. As a result, we get an error at
compile time. To avoid this type of errors, it is better to attach the macro check condition. This is as …
Sub file “factorial.c”
#ifndef FACT
#define FACT 1
long int fact( int n)
{
long int f=1;
while( n>1)
f=f*n--;
return(f);
}
#endif

In the above code, at 1st time of inclusion of file, the symbol FACT is not yet defined, therefore the file
“factorial.c” includes to the “main.c” file, and same time the FACT defines to 1.
In 2nd time inclusion, the FACT has already been defined; therefore it will be skipped by the #ifndef directive.

#undef
This directive removes a previously defined definition of the macro-name, for example
void main()
{ after void main()
#define X 20 preprocessing {
printf(“%d “, X); printf(“%d “, 20);
#undef X printf(“%d “, X);
}
printf(“%d “, X);
} Error :undefined symbol “X”

#error
Suppose programmer wants to show an error message if specific macro was not defined previously in the
program. In those cases, we may use this #error to produce an error and to stop the compilation. This #error
stops the compilation based on given condition. For example
#ifdef PIE
#define Area(r) (PIE*r*r)
#define Perimeter(r) ( 2*PIE*r)
#else
#error “the symbol PIE was not defined”
#endif
If we compile the above program, we get an error message, because the symbol “PIE” has not been defined
in the program.
C-Family 191 2D-Arrays

Two Dimensional arrays


Often there is a need to store and access two or three dimensional array data structures especially while
dealing with matrices, tables, string, files... We can declare & access as many dimensions as we need in the
programming.
Syntax: data-type array-name [size1][size2][size3]….;
For example: int x[3][5]; // two dimensional array
int x[3][4][5]; // three dimensional array
int x[3][4][5][6]; // four dimensional array

2D arrays: int x[3][5]; Here the value 3 represents row-size, 5 represents column-size.
Then the 2D array is as follows
Columns
R x[0][0] x[0][1] x[0][2] x[0][3] x[0][4]
o
w x[1][0] x[1][1] x[1][2] x[1][3] x[1][4]
s
x[2][0] x[2][1] x[2][2] x[2][3] x[2][4]

Scanning 2x4 matrix data and displaying on the screen


void main()
{ int x[2][4], i, j;
// scanning data to 2D array
for(i=0; i<2; i++)
{ for(j=0; j<4; j++)
{ printf(“enter value of x*%d+*%d+ :”, i, j);
scanf(“%d”, &x*i+*j+ );
}
}
// printing 2D array data
for(i=0; i<2; i++)
{ for(j=0; j<4; j++)
printf(“%d ”, x*i+*j+ ); // printing each element
printf(“\n”); // inserting new line after each row
}
}
Nested loops are required for scanning & printing 2D array data. Outer loop is for rows and inner loop is for
columns. Here ‘i’ loop is to scan 2-rows, whereas ‘j’ is to scan 4-columns in each row.
If input numbers are 25, 61, 92, 53, 45, 67, 90, 55, then let us see how the program asks the user and stores
into given array

enter value of x[0][0] : 25


enter value of x[0][1] : 61 25 61 92 53
enter value of x[0][2] : 92 45 67 90 55
enter value of x[0][3] : 53
enter value of x[2][0] : 45
enter value of x[2][1] : 67
enter value of x[2][2] : 90
enter value of x[2][3] : 55
C-Family 192 2D-Arrays

Initialization of two dimensional arrays


We can initialize in two ways, first one is like 1D-array, second one is by enclosing each row with { }.
Second method is clear and easy to understand. This method is recommended when the initializing values
are more.
int a[2][3]={ 51, 35, 67, 45, 23, 21 };
int a[2][3]={ {51, 35, 67}, {45, 23, 21} };
int a[2][3]={ 51, 35, 67 }; // only first row is initialized, and remaining is zero.
int a[ ][3]={ 51, 35, 67, 45, 23, 21 }; // the row-size is 2, automatically calculated by compiler based on values.
int a[ ][3]={ {51, 35, 67}, {45, 23, 21}, {44,55,67} }; // here the row-size is 3

In the last two declarations, the row size automatically calculates by the compiler. Here, the row-size equal
to (number-of-elements)/(column-size). The column size is mandatory while declaration of array.
inta[2][]={ {1,2,3}, {4,5,6} } // error, the column size must be required

Adding elements of 3x3 matrices and printing on the screen


This program adds two matrices of 3x3 size and prints the result. Consider the source matrices A,B already
initialized with some assumed values.

void main()
{ int a[2][3]={ {1,2,3}, {4,5,6}, {7,8,9} };
int b[2][3]={ {9,8,7}, {6,5,4}, {3,2,1} };
int i, j;
for( i=0; i<3; i++)
1 2 3 9 8 7
{ for( j=0; j<3; j++)
4 5 6 6 5 4
c[i][j]=a[i][j]+b[i][j]; 7 8 9 3 2 1
} A[ ][ ] B[ ][ ]
// displaying result of the matrix
for( i=0; i<3; i++) output matrix c[][] is:
{ for( j=0; j<3; j++) 10 10 10
printf(“ %d “, c*i+*j+); 10 10 10
10 10 10
printf(“\n”);
}
}

Adding two matrices of given input size


This demo program adds two matrices with a given input values instead of initialized values unlike above
program. Here the size of matrices (order of matrix) and its data chosen by the user at run time. Therefore,
these values should be accepted from keyboard.
void main()
{ int a[10][10], b[10][10], c[10][10] , r1, r2, c1, c2, i, j;
printf(“\n enter sizes of 1st matrix :”);
scanf(“%d%d”, &r1, &c1);
printf(“\n enter sizes of 2nd matrix :”);
scanf(“%d%d”, &r2, &c2);
if( r1 != r2 || c1 != c2)
{ printf(“sizes not equal, cannot be added”);
exit(0);
}
C-Family 193 2D-Arrays

printf(“\n enter the elements of 1st matrix”); Input:


st
for(i=0; i<r1; i++) Enter the size of 1 matrix : 2 3
st
enter the elements of 1 matrix
{ for(j=0; j<c1; j++) enter element of a[0][0] : 7
{ printf(“ enter element of a*%d+*%d+ :”, i, j); enter element of a[0][1] : 3
scanf(“%d”, &a*i+*j+); enter element of a[0][2] : 2
} enter element of a[1][0] : 4
} enter element of a[1][1] : 6
enter element of a[1][2] : 2
printf(“\n enter the elements of 2nd matrix”);
for(i=0; i<r2; i++) nd
Enter the size of 2 matrix : 2 3
nd
{ for(j=0;j<c2;j++) enter the elements of 2 matrix
{ printf(“ enter element of b*%d+*%d+ :”, i, j); enter element of a[0][0] : 2
scanf(“%d”, &b*i+*j+); enter element of a[0][1] : 4
enter element of a[0][2] : 5
} enter element of a[1][0] : 6
} enter element of a[1][1] : 8
// adding two matrices enter element of a[1][2] : 1
for( i=0; i<r1; i++)
for( j=0; j<c1; j++) output: 9 7 7
c[i][j]=a[i][j]+b[i][j]; 10 14 3
printf(“\n output matrix is \n:”);
for(i=0; i<r1; i++)
{ for(j=0;j<c1;j++)
printf(“ %d ”,c* i+*j+);
printf(“\n”);
}
}

Finding biggest of each row & column of 2D array data (R X C size matrix)

Input: Output:
23 55 66 7 row1 big = 66
31 12 61 17 row2 big = 61
5 14 98 47 row3 big = 98
2 24 8 97 row4 big = 97

void main()
{ int a[10][20], r, c, i, j;
printf(“enter row and column size of input matrix :”);
scanf(“%d%d”, &r, &c);
for(i=0; i<r; i++)
{ for(j=0; j<c; j++)
{ printf(“ enter element of *%d+*%d+ :”, i, j);
scanf(“%d”, &a*i+*j+);
}
}
printf(“\n each row output \n”);
C-Family 194 2D-Arrays

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


st
{ big=a[i][0]; // let us assume 1 column element is big
for(j=1; j<c; j++)
{ if( big < a[i][j] ) // comparing big with rest of elements in the row
big=a[i][j];
}
printf(“\n biggest of row %d = %d ”, i+1, big);
}
printf(“\n each column output \n”);
for(j=0; j<c; j++)
st
{ big=a[0][j]; // let us assume 1 row element is big
for(i=1; i<r; i++)
{ if( big < a[i][j] ) // comparing big with rest of elements in the column
big=a[i][j];
}
printf(“\n biggest of column %d = %d ”, j+1, big);
}
}

Transposing MxN matrix


Transposing is nothing but changing values from rows to columns and columns to rows

#define M 3 ip:
1 2 3 4
#define N 4
5 6 7 8
void main() 9 10 11 12
{ int A[M][N] = { {1, 2, 3, 4},
{5, 6, 7, 8}, op: 1 5 9
2 6 10
{9, 10, 11, 12},
3 7 11
}; 4 8 12
int B[M][N], i, j;
// transposing elements from A[][] to B[][]
for(i=0; i<M; i++)
for(j=0; j<N; j++)
B[i][j] = A[j][i];
printf("Result matrix is \n");
for(i = 0; i < N; i++)
{ for(j=0; j< M; j++)
printf("%d ", B[i][j] );
printf("\n");
}
}

Multiplying two matrices and displaying the result.


Consider the source matrices A, B with the input sizes r1*c1 and r2*c2.
Before multiplying, the program checks the order of matrices; the size c1 must be equal to r2. If sizes are
not equal then shows an error message “cannot be multiplied” and closes the program.
The output matrix size will be m1xn2.
C-Family 195 2D-Arrays

void main()
{ int a[10][10], b[10][10], c[10][10];
int r1, r2, c1, c2, i, j, sum;
printf(“\n enter size of input matrix :”);
scanf(“%d%d”, &r1, &c1);
printf(“\n enter size of second matrix :”);
scanf(“%d%d”, &r2, &c2);
if( c1 != r2)
{ printf(“sizes not equal, cannot be multiplied”);
exit(0);
}
printf(“\n enter elements of first matrix :”);
st
for(i=0; i<r1; i++) // loop to multiply 1 matrix of each row
nd
{ for(j=0; j<c2; j++) // loop to multiply 2 matrix of each column
{ sum=0;
for(k=0;k<c1;k++) // loop to multiply to get element of output matrix
sum = sum + a[i][k] * b[k][j];
c[i][j]=sum;
}
}
printf(“\n output matrix is \n:”);
for(i=0; i<r1; i++)
{ for(j=0;j<c2;j++)
printf(“ %d ”,c*i+*j+ );
printf(“\n”);
}
}
Observe the multiplication stages carefully, it contained 3 loops, 1st loop is for maintaining the row index of
1st matrix, and 2nd loop is for column index of 2nd matrix. The 3rd loop is to keep the track of sum of products
of row wise of 1st matrix with the columns wise of 2nd matrix. Finally this sum is assigned to the target
matrix of relevant position.

Accepting marks details of ‘N’ students and printing result


This demo program accepts ‘N’ number of student details and prints the result.
Suppose if each student has 4 subjects then result will be displayed using following conditions.
If student obtained <40 in any subject, then print “failed”, otherwise
If student obtained avg>=80 then print “passed in A-Grade”
If student obtained avg 80 to 60 then print “passed in B-Grade”
If student obtained avg<60 then print “passed in C-Grade”
input: enter number of students: 3
60 49 40 50
10 20 30 40
70 50 90 80
C-Family 196 2D-Arrays

output: idno marks1 marks2 marks3 marks4 total average result


===============================================================
1 60 49 40 50 199 49 C-Grade
2 10 20 30 40 100 25 Failed
3 70 50 90 80 290 72 B-Grade

void main()
{ int a[100][4]; // let the maximum number of student are 100, and subjects are 4.
int i, j, total[100], avg[100], n;
char result[100][20];
printf(“enter number of students :”);
scanf(“%d”, &n);
for(i=0; i<n; i++)
{ printf(“enter student %d marks of sub1, sub2, sub3, sub4 :”);
scanf(“%d%d%d%d”, &a*i+*0+, &a[i][1], &a[i][2], &a[i][3]);
}
for(i=0; i<n; i++) // calculating total, avg and the result.
{ for(j=0; j<4; j++)
total[i]=a[i][j]+a[i][j]+a[i][j]+a[i][j]);
avg[i]=total[i]/4;
if( a[i][0]<40 || a[i][1]<40 || a[i][2]<40 || a[i][3]<40 )
strcpy( result*i+, “Failed”);
else if ( avg[i] >= 80 )
strcpy( result*i+, “A-Grade”);
else if ( avg[i] >= 60 )
strcpy( result*i+, “B-Grade”);
else
strcpy( result*i+, “C-Grade”);
}
// printing result
printf(“ student idno marks1 marks2 marks3 marks4 total avg result “);
printf(“\n===================================================”);
for(i=0; i<n; i++)
printf(“\n %d %d %d %d %d %d %s“, a*i+*0+,a*i+*1+,a*i+*2+,a*i+*3+ );
}
C-Family 197 2D-Arrays

2D arrays and pointers


Before knowing how to make a pointer to a multi-dimensional array, let us know, how a multi-dimensional
array is stored in the memory? And how elements are accessed in different ways?
The two dimensional array data is also stored like single dimensional array, because the RAM is constituted
as order collection of bytes. It is not like table, or matrix or in other form, it is like an array of continuous
bytes. So the 2D and other dimensional arrays also occupy as 1D-array in the memory, this is as …

For example: int x[3][5] = { {1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15} };

1st row 2nd row 3rd row

X[0][0] X[0][1] X[0][2] X[0][3] X[0][4] X[1][0] X[1][1] X[1][2] X[1][3] X[1][4] X[2][0] X[2][1] X[2][2] X[2][3] X[2][4]

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2000 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 2028

In one dimensional arrays, the expression x[i] can be written in pointer form as *(x+i)
lly, In two dimensional arrays, the x[i][j] can be written in pointer form as *(x[i]+j) or *(*(x+i)+j)
But implicitly the expression x[i][j] is converted as *(x+i*column-size+j). This equation is called row-major
order formula. This method used by compiler implicitly to access elements in the 2D-array, because, the row
elements are expanded in column-wise. (Some other languages use column-major order formula)
Let us see how elements are accessed in 2D array

x[i][j]  *(x+i*column-size+j).
x[0][0] *(x+0*5+0)  *(2000+0)  *2000 1
x[0][1] *(x+0*5+1)  *(2000+1)  *2002  2 // integer address increments by 2
x[1][0]  *(x+1*5+0)  *(2000+5)  *20010  6
x[1][1] *(x+1*5+1)  *(2000+6)  *2012  7
x[2][0]  *(x+2*5+0) *(2000+10)  *2020  11
x[2][1] *(x+2*5+1)  *(2000+11)  *2022 12

Here the expression ‘x’ gives array base address.


That is, the expression x&x[0][0]; // &x[0][0] &*(x+0*5+0)  x2000

&X[0][0] X gives array base-address  2000

In one dimensional arrays, the expression x[i]  *(x+i);


In two dimensional arrays, the expression x[i]  (x+i*column-size)  gives ith row address.

x[0] (x+0*5)  x2000  gives 1st row address


x[1] (x+1*5)  x+52010  gives 2nd row address
x[2] (x+2*5)  x+10  2020  gives 3rd row address

Here special types of pointers are used to access the 2D array elements. For example
int (*p)[3];  pointer to 2d-array where the column size is 3. The row size can be anything.
int (*p)[3][4];  pointer to 3d-array where the row-column sizes are 3-4, table size can be anything.

Let us see one example


C-Family 198 2D-Arrays

void main()
{ int a[2][3]={{1,2,3}, {4,5,6},{7,8,9} };
int (*p)[3]; // pointer ‘p’ to 2d-array with the columns size 3.
p=a; // p=&a[0][0]; making pointer to 2D array
for(i=0; i<2; i++)
{ for(j=0; j<3; j++)
printf(“%d”, p*i+*j+); // p[i][j]  expands to  *(p+i*3+j)
printf(“\n”);”
}
}
Passing 2D array to function
it is just like passing 1D array to functIon, here array base address is passed and accessed through pointer.
void main()
{ int a[3][4]={ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
display(a); // display( &a[0][0]);
}
void display( int (*p)[4] or int p[][4] )
{ inti,j;
for(i=0; i<3; i++)
{ for(j=0; j<4; j++)
printf(“%d ”, p*i+*j+ ); // p[i][j]  *(p+i*4+j)
printf(“\n”);”
}
}
The second declaration for the parameter p[][4] is also a valid and this type of declaration is allowed only for
the parameters while receiving 2D array. This is also implicitly a pointer of type “int (*p)*4+”.

Passing row by row values of 2D array to a function


void main()
{ int a[3][4]={ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
for(i=0; i<3; i++)
display(a[i]); // display (&a[i][0])  passing row address like 1D array address
}
void display( int *p or int p[] ) // here ‘p’ pointer to 1D array(row)
{ int i;
for(i=0; i<4; i++)
printf(“%d ”, p*i+ ); // p[i]  *(p+i)
printf(“\n”);”
}
output: 1 2 3 4
5 6 7 8
9 10 11 12
Here each row address passed as 1D array to the function, for each call of display() function prints one row
on the screen. It is called 3 times for 3 rows.
C-Family 199 2D-Arrays

Adding two matrices using functions (custom sized input values)


void main()
{ int x[10][10], y[10][10], z[10][10] , r1, r2, c1, c2, r3, c3;
scanMatrix( x, &r1, &c1 );
scanMatrix( y, &r2, &c2 );
k=addMatrix( z, &r3, &c3, x, r1, c1, y, r2, c2);
if(k==0)
printf(“addition is not possible, size not matched”);
else
printMatrix( z, r3, c3);
}
void scanMatrix( int p[][10], int *pr, int *pc)
{ int i,j;
printf(“\n enter the size of matrix :”);
scanf(“%d%d”, pr, pc );
for(i=0; i<*pr; i++)
{ for(j=0; j<*pc; j++)
{ printf(“ enter element of *%d+*%d+ :”, i, j);
scanf(“%d”, &p*i+*j+);
}
}
}
int addMatrix( int z[][10], int *pr, int *pc, int x[][10], int r1,int c1, int y[][10], int r2, int c2)
{ int i,j;
if( r1 != r2 || c1 != c2)
return 0; // addition failed
// adding two matrices
for( i=0; i<r1; i++)
for( j=0; j<c1; j++)
z[i][j]=x[i][j]+y[i][j];
*pr=r1; *pc=c1;
return 1; // addition success
}
void printMatrix( int a[][10], int r, int c)
{ int i,j;
printf(“\n output matrix is \n:”);
for(i=0; i<r; i++)
{ for(j=0;j<c;j++)
printf(“ %d ”, a[i][j]);
printf(“\n”);
}
}
C-Family 200 Characters & Strings

Character Handling
In programming, it is often need to handle single character data items such as employee sex, account type in
the bank, marks grade of a student, color of an object, etc. These characters may be an alphabet, digit, or
any other symbol, which is to be handled as a single character item in the program.

Character variable: The characters are stored in the form of ASCII values in the computer, and all
character’s ascii values lie in between 1 to 255, so to store such ascii codes, the suitable type is ‘char’. If we
take int or long int, the memory gets unused(wasted). The char occupies 1 byte and it is suitable for values in
the range of 0 to 255. ASCII  American standard code for information interchange.
Syntax to declare character variables is: char variable1, variable2,…variableN;
example: char sex, accountType, colorType;

Initialization of char variable:


char sex=’M’; // male
char accountType=’S’; // savings account
char color=’Y’; // yellow
we can declare char sex=’M’ as char sex=77;  both declarations are same, since ‘M’ ascii code is 77, but
this declaration is informal, because difficult to remember/recognize ascii codes, so symbolic representation
is always best.

Character constant: If any single character enclosed within a pair of single quotes is known as char
constant. Unlike integer or float constants, the char constants must be enclosed within a pair of single
quotes.(not double quotes)
for example ‘a’, ‘A’, ‘9’, ‘+’ …etc are valid character constants.
‘abc’, ‘123’, ‘+12’, “A”, “5” … are not valid character constants.
(19, 34, 10, -10, 45 are integer constants.)

The value of character constant is nothing but their ASCII code, at compile time, the compiler replaces these
single quoted characters with their ASCII codes, For example, ASCII value of ‘A’ is 65, ‘B’ is 66. Remember,
the data type of these constant is ‘char’. The following table shows ASCII codes of all characters set
Characters ASCII values
A to Z 65 to 90
a to z 97 to 122
0 to 9 48 to 57
‘ ‘ (blank space) 32
‘\n’ ( enter key) 13
In computer’s memory, the characters are stored in terms of their ASCII values but not in its picture form as
visible on the screen. Remember that, these ASCII values stores in its binary form as computer understand it.
ASCII values are standard serial numbers given to each alphabet, digit, and all symbols in the keyboard. This
standard is called American Standard Code for Information Interchange proposed by international
computer associations. Here the word “information interchange” means, exchanging data from one device
to another or one computer to another in terms of ASCII values.

Hence every symbol internally represents in binary format and when it is to be displayed on the screen, it
converts into symbolic picture form (picture in pixel form). Internally, special software continuously
performs this graphical conversion job while displaying contents on the monitor. The hardware
manufacturers provide this kind of software.
C-Family 201 Characters & Strings

Displaying all ASCII symbols


This program displays ASCII values of A-Z, a-z, 0-9, etc
vodi main()
{ char ch;
// printing all upper case alphabets
for( ch=’A’; ch<=’Z’; ch++) // for( ch=65; ch<=90; ch++ )
printf(“\n %c = %d”, ch, ch);
// printing all lower case alphabets
for( ch=’a’; ch<=’z’; k++) // for( ch=97; ch<=122; ch++ )
printf(“\n %c = %d”, ch, ch);
// printing all digits
for(ch=’1’; ch<=’9’; ch++) // for( ch=48; c<=57; ch++)
printf(“\n %c = %d”, ch, ch);
}
In the printf() statement, ‘%c’ is used to print character in picture format, whereas ‘%d’ is used to print its
ASCII code. In the above program, the expression ‘ch++’ is a valid operation; even though the variable ‘ch’ is
‘char-type’. We can do all arithmetic and other operations on characters just as integers. The unsinged-char
type variable can hold integral value between 0 to +255 range value. For example: char age=18.

Character library functions for I/O


scanf(), getchar(), getch(), getche()
printf(), putchar(), putch().
We know that, printf() & scanf() are generic i/o functions used to print & scan any type of data. Whereas
other functions like getchar(), getch(), putchar(), putch() are specialized to handle only characters data.
These are light weight function to handle characters data.

getchar(): this is similar to scanf() function, it accepts a single character from standard input stream (
program’s stream) not directly from keyboard stream. Stream or buffer is a small capacity memory, works as
mediator between device & app, used to store data temporarily for a while before reading/writing in it.
Whatever you entered in the keyboard, that input values are inserted into keyboard buffer, later our
program(scanf) reads the input values from the buffer. Thus stream works as mediator between device &
application(our program).

getchar()
scanf()
our progoram’s keyboard stream
Keyboard
stream memory memory(buffer)
getch()
getche()

for example: char ch;


ch=getchar(); // equal to scanf(“%c”, &ch);

getch(): Accepts a single character directly from keyboard stream, without echoing(displaying) on the
screen. Unlike getchar(), it doesn’t wait for enter-key for input confirmation. That is, all io functions waits for
enter-key at the end of input. When user press the enter-key, then io functions starts scanning input and
stores into variables. But getch(), getche() does not wait for enter-key for confirmation of input.
Note: The getch(), putch(), getche() are non-standard function, so it may not be available in all versions of C.
It works only on DOS based C-Software like Turbo-C.
C-Family 202 Characters & Strings

getche(): it is just as getch(), but it shows the input character on the screen.
putchar(): this is similar to printf() function for showing single character on the screen.
putch():it sends the input character directly to the monitor stream.

Printing opposite case of a given character alphabet


This program accepts a single character alphabet from keyboard and prints opposite case.
Upper case alphabets ascii code : A-Z  65 to 90
Lower case alphabets ascii code : a-z  97 to 122
Difference between lower & upper is  32
void main()
{ char ch;
printf(“enter any alphabet :”);
ch=getchar(); // scanf(“%c”, &ch);
if( ch>=’A’ &&ch<=’Z’)
ch=ch+32;
else if( ch>=’a’ &&ch<=’z’)
ch=ch-32;
printf(“opposite alphabet is : %c”, ch);
}
input:A input: a
output:a output:A

Library functions for Character manipulations


isalpha(): This function checks whether a given character is alphabet or not? , and returns the Boolean value.
If alphabet then returns 1, otherwise 0.
isdigit(): checks the given character is digit or not? Returns boolean value
islower(): checks the given character is lower case alphabet or not?
isupper(): checks the given character is upper case alphabet or not?
tolower(): this function coverts an upper case alphabet to lower case
toupper(): this function coverts an lower case alphabet to upper case
void main()
{ char ch=’A’;
if( isupper(ch) ) printf(“\n upper case alphabet”); √
else printf(“\n lower case alphabet”); x
ch=’a’;
if( isupper(ch) ) printf(“\n upper case alphabet”); x
else printf(“\n lower case alphabet”); √
ch=’9’;
if( isdigit(ch) ) printf(“\n digit”); √
else printf(“not a digit”); x
ch=’a’;
ch=toupper(ch);
printf(“output is %d “, ch);  ‘A’
}
C-Family 203 Characters & Strings

Printing opposite case of a given character alphabet


This program accepts a single character alphabet from keyboard and prints opposite case.
(We have already done this program, here library function are used to check and convert)
Upper case alphabets ascii code are: void main()
A-Z  65 to 90 { char ch;
printf(“enter any alphabet :”
Lower case alphabets ascii code are: ch=getchar(); // equal to scanf(“%c”, &ch);
a-z  97 to 122 if( isupper(ch) )
ch=tolower(ch);
Difference between lower & upper  32 else if( islower(ch) )
input: A input: e ch=toupper(ch);
output: a output: E printf(“opposite alphabet is : %c”, ch);
}

Printing ASCII/SCAN code of a given input symbol


Note: This program works only on DOS based compilers like Turbo c/c++
The keys in the keyboard divided into two types, normal keys, and special keys.
The normal keys are alphabets, digits, operators, punctuation symbols, etc.
The special keys are F1,F2, ….F12, up-arrow, down-arrow, pgup, pgdown, home, end, control and alt keys.
The normal keys produces only ascii-codes, whereas special keys produces two values as zero + scan code.
If first input value is zero then user entered a special-key, so we have to scan again for 2nd value.
void main()
{ char ch1,ch2;
printf(“enter any key in the keyboard :”);
ch1=getch();
if( ch1 == 0) // user entered special key
{ ch2=getch(); // reading 2nd value.
printf(“\n ascii code = %d, scan code = %d”, ch1, ch2);
}
else
prnitf(“\n ascii code = %d”, ch1);
}
input: A input: up-arrow
output: ascii code = 65 output: ascii code = 0, scan code = 72

Printing following patterns

ABCDEF void main() A


ABCDE { inti,j; AB void main()
ABCD for( i=0; i<6; i++) ABC { inti,j;
ABC { for( j=0; j<6-i; j++) ABCD for( i=0; i<6; i++)
AB printf(“%c”, ‘A’+j); ABCDE { for( j=0; j<=i; j++)
A printf(“\n”); ABCDEF printf(“%c”, ‘A’+j);
} printf(“\n”);
} }
}
C-Family 204 Strings

Strings
String is a collection of characters arranged sequentially one after the other in the memory, used to
represent names of persons, items, countries, cities and sometimes to represent messages. Generally, any
non-computable data manipulates as strings. That is, on strings data, we don’t do any arithmetical operation
such as addition, subtraction, multiplication, division. To handle strings, there is no direct data type in C,
instead we have to access them as normal array of characters. However, C provides some basic facilities to
handle strings easily, such as representation of string constants, initialization of string, implicit generation of
references to the string and also provided several standard library functions to manipulate strings.
The strings such as “India”, “China”, “C-Family”, “123”, “A123”, etc.

The null character and its importance


Strings are extensively used in almost all real life applications. These string characters are stored sequentially
in the memory. We know that, the string lengths differ from one to another string. So there should be an
indication to identify the end of string. For this reason, the null character (‘\0’) is inserted at the end of every
string. Almost all C library functions are designed by considering this null character as a string terminator.
String library functions automatically adds null-char at end of string, for example scanf(),gets(), strcpy(),
strcat(), etc. Sometimes programmers need to insert null-char explicitly while handling character by
character in the string. Some programmers use zero in place of null character, because, the null character
value is zero.(‘\0’ 0)

Note: The ascii values of chars lie in between 1-255, so the value 0 is taken as null character value as a string
terminator. But in the program, it is better to write ‘\0’ instead of 0(zero) to represent in symbolic way.

String constants
A set of zero or more characters represented within a pair of double quotes is known as string constant.
All characters in a string are stored sequentially in contiguous memory locations in the form of their ASCII
values. These can be accessed just as any normal array of elements. Therefore, whatever operations can be
applied on arrays, they can also be applied on strings. For example, passing string to function, accessing
string through pointer, etc.
Example for string constants: “India”, “C-family”, “ ”, “9440-030405”, “A123”, “123”, etc.
The string “INDIA” occupies 6 bytes in the memory (5bytes for INDIA+1byte for null-char).
The compiler automatically appends a null character at the end of string constants.

For example, the string “INDIA” in the memory as ‘I’ ‘N’ ‘D’ ‘I’ ‘A’ ‘\0’

But actually, in the memory, it is in the form of Binary code as


“India” in ASCII codes ‘I’ ‘N’ ‘D’ ‘I’ ‘A’ ‘\0’ 73 78 68 73 65 0
“India” in Binary codes 01001001 01001110 0100100 01001001 0100001 0

Similarly the string “1234” is stored in 5 bytes as:


‘1’ ‘2’ ‘3’ ‘4’ ‘\0’ 49 50 51 52 0 110001 110010 110011 110100 00000

The integer constant 1234 stored in two bytes of memory in its binary format as: 00000100-11010010
Do not confuse string constant with integer constant.
123 is said to be integer constant, whereas “123” is string constant.
C-Family 205 Strings

How string constants are stored in the memory


At compile time, the program’s code and data split into two separate entities and stored separately in
executable file. This file loads as it is into memory before executing it. This is as

Code this code area contains


Area instructions of program

String constants
Heap
Data Global variables
Area
Area Static variables
Stack Local variables
Area Function return address

The data area is again divided into two parts, heap area & stack area. In heap area, a permanent data items
like string constants, global and static variables are managed. Whereas, in stack area, the temporary local
variables and function return addresses are manipulated. (Refer the chapter storage-classes)
All string constants in a program are moved to data-area, whereas in the code-area their starting addresses
are substituted. Let us see following example

Observe how the string constant’s address Code Area of program


substitutes in the program void main()
{
if(2000==4000)
void main() printf(6000);
{ else
if(“Hello”==”World”) printf(8000);
printf(“Strings equal”); }
else Data area of program
printf(“Strings not equal”);
} “Hello” “World” “ Strings are “String are
equal” not equal”
2000 4000 6000 8000

String variable
we know that, variable is a space, used to store and access a value. Similarly, to store and access characters
of a string, one is required “char [+” array.
For example: char arr[20]; // It can hold a string with the maximum length 19 chars and 1 byte for null.

Initialization of strings: like normal arrays, we can initialize character arrays with the strings in
different ways. This is as given below example.
char a*9+=”C-Family”; // here null character automatically appends at end by the compiler
char a*+=”C-Family”; // the size of array calculates by the compiler, which is equal to length of “c-family”+1
char a[9+=, ‘C’, ’-‘, ’F’, ’a’, ’m’, ’i’, ’l’, ’y’, ‘\0’-; // we can initialize with char by char
char a*+=, ‘C’, ’-‘, ’F’, ’a’, ’m’, ’i’, ’l’, ’y’, ‘\0’-; // size not given, automatically calculated by compiler, it is 9
char a[]={67,45,70,97,109,105,108,121,0}; // we can also initialize with ASCCII values of “c-family”

The last declaration with ASCII values is somewhat confusion and not suggestible, it is just given for fun.
The First two declarations are more convenient & easy to understand.
C-Family 206 Strings

char a*5+=”C-Family”; // compiler raises an error, because, the array size is not enough for the string;
char a*20+=”hello”; // remaining 14 locations gets unused(empty)

Accessing individual characters in a string is same as accessing elements in the array. The index of the
character should be specified as array subscript.
For example: char a*+=”C-Family”;
The expression ‘a*0+’ accesses the first character ‘c’,
‘a*1+’ accesses the second character ‘-’
‘a*2+’ accesses the second character ‘F’, …
in this way, we can access any element in the array

Console i/o functions on Strings


Input functions: scanf(), gets()
Output functions: printf(), puts()
gets() and puts() have simple syntax and specialized for string data. The scanf() and printf() are generic i/o
functions, they support all built-in data types such as int, float, long. Here format string %s is used to read
the string data.

① scanf(“%s”, ..) : this reads a string char by char until a new-line or a blank-space is found,
whichever comes earlier. If input is “jack and jill”, then scanf() accepts only “jack”.

② scanf(“%*^\n+”, ..) : this reads a string char by char until new-line is found, that is, it accepts total string
with spaces like “jack and jill”. The gets() and this scanf(“%*^\n+”, ..) works in similar way. These input
functions automatically append null character at the end of string. For example

Scanning string with “scanf()” Scanning string with “gets()”


void main() void main()
{ char a[20]; { char a[20];
printf(“enter a string :”); printf(“enter a string :”);
scanf(“%s”, a); //scanf(“%s”, &a*0+ ); gets(a); or scanf(“%*^\n+”, a );
printf(“\n output = %s”, a); printf(“\n output = %s”, a);
} }
Input: Jack and Jill // scanf() treats as 3 strings Input: Jack and Jill //gets() or scanf() treats as one string
Output: Jack Output: Jack and Jill

The puts() and printf() works in similar way, all i/o functions take first byte address (base address of array) as
argument and prints the given string using pointer.

Printing ASCII values of a given person name


This demo program accepts a name of a person and prints ASCII value of all characters.
void main()
{ char a[100], i, n;
printf(“\n enter name of a person :”);
gets(a); // gets(&a[0]);
printf(“\n the list of ascii values are ”);
for(i=0; a*i+!=’\0’; i++) // loop to print all character’s ASCII values
printf(“%c = %d , ”, a*i+, a*i+ );
}
Input: enter name of a person: Sri Hari
Output: S=83, r=144, i=105, ‘ ‘=32 , H=72, a=97, r=144, i=105
C-Family 207 Strings

The i/o function gets() accepts “Sri Hari” char by char from keyboard and stores into given array in &a[0],
&a[1], &a[2],etc. The “%c” prints the character in symbolic form, whereas %d prints its ASCII code.
Here the for-loop repeats until null character is found.

Finding Length of string


void main()
{ char a[100], count=0;
printf(“\n enter any string :”);
gets(a);
for(i=0; a*i+!=’\0’; i++) // counting all characters until null is found
count++;
printf(“\n length = %d”, count);
}
Here the loop repeats until the null character is reached and same time the characters are counted using
‘count’ variable to find length of a string. Generally, we don’t consider null character is a part of the length.
Input: INDIA input: All fruits are not apples
output: length=5. Output: 25

Printing string in reverse form


ip: Apple
op: elppA
Logic: first it moves the loop variable ‘i’ to end of string, later prints char by char from last to first in a string.
void main() ‘A’ ‘p’ ‘p’ ‘l’ ‘e’ ‘\0’
{ char a[20], i; i
printf(“\n enter any string :”);
gets(a);
for(i=0; a*i+!=’\0’; i++) // loop continues until null is found
{ // empty loop, the loop stops when ‘i’ reaches to null character.
// the null character’s index(array-position) is equal to length of string.
}
for(i--; i>=0; i--) // printing string in reverse order (char by char)
printf(“%c”, a*i+);
}

Calculating number of words in a given multiword string


This program accepts a multi-word string and finds number of words, assume there may be more than one
space between two words but not other symbols like dot, coma, etc.

Input: A L L A P P L E S A R E R E D \0

void main()
{ char a[100]; int i, count;
printf(“\n enter a multi word string :”);
gets(a);
for(i=0; a*i+!=’\0’; i++)
{ if( a*i+==’ ‘) // if space is found then count as one word
{ count++;
while( a*i+1+==’ ‘) // if next char is also space, then skip by incrementing loop.
i++;
C-Family 208 Strings

}
}
printf(“\n number of words = %d”, count);
}
Let us observe the input string, contains more than one space between words. The inner while loop used to
skip extra spaces between words. When the index pointer ‘i’ moves to first space then count increments and
all succeeding space if any are skipped by the inner while loop.

Counting number of lower & upper case alphabets in a string.


This program accepts a string and counts the number of lower & upper case alphabets, numeric digits,
spaces and other characters.
void main()
{ char a[100]; int i, lower, upper, digit, space, others;
printf(“\n enter a string :”);
gets(a);
// initializing all counts to zero
lower=upper=digit=space=other=0;
for(i=0; a*i+!=’\0’; i++)
{ ch=a[i];
if( ch>=’A’ &&ch<=’Z’) // if( isupper(ch))
upper++;
else if( ch>=’a’ && ch<=’z’) // if( islower(ch))
lower++;
else if( ch>=’0’ && ch<=’9’) // if( isdigit(ch))
digit++;
else if( ch ==’ ’ )
space++;
else others++;
}
printf(“\n upper count = %d”, upper);
printf(“\n lower count = %d”, lower);
printf(“\n digits count = %d”, digits);
printf(“\n spaces count = %d”, space);
printf(“\n upper count = %d”, others);
}

Converting upper case alphabets to lower case and vice-versa in a string


This demo program accepts a string and converts lower case alphabets to upper case and vice-versa in a
given string.
Input: This Chair Has 4 Legs
Output: tHIS cHAIR hAS 4 lEGS
We know that, uppercase alphabet ASCII values are in the range 65-90 and lowercase in the range of 97-122.
The difference between these two cases is 32. Therefore, by adding or subtracting 32, we can get
corresponding opposite case.
C-Family 209 Strings

void main()
{ char a[100]; int i;
printf(“\n enter string :”);
gets(a);
for(i=0; a*i+!=’\0’; i++)
{ if( a*i+ >= ’a’ && a*i+ <= ’z’ ) // if( islower( a[i] ) a[i]=toupper(a[i]) ;
a[i]=a[i]-32;
else if( a*i+ >= ’A’ && a*i+ <= ’Z’ ) // if( isupper( a[i] ) a[i]=tolower(a[i]) ;
a[i]=a[i]+32;
}
printf(“ output string is %s:”, a);
}

Finding sum of digits in a given string


This program accepts a string from keyboard; the string can have digits in the input, finding sum of such
digits. For example, the string is “ABC567DEF9PQ12”, output is: 5+6+7+9+1+2 30
void main()
{ char a[100], i , sum;
printf(“enter a string :”);
scanf(“%s”, &a*0+ );
for( i=0; a*i+!=’\0’; i++)
{ if( a*i+>=’0’ && a*i+<= ‘9’ )
{ sum=sum+(a[i]-48); // sum=sum+(a[i]-‘0’);
}
}
printf(“\n sum = %d”, sum);
}
Ths ASCII value of ‘0’ is 48, ‘1’ is 49, ‘2’ is 50, etc; so to convert ascii value into numeric value, subtract 48;

Converting every first letter of word to upper case and remaining to lower case.
Ip: all apples are good, some are in white colors and some are in read color.
op: All Apples Are Good, Some Are In White Colors And Some Are In Read Color.
(Let the words in a string are separated with single space)
void main()
{ char a[100]; int i ;
printf(“enter string :”);
gets( a );
a[0]=toupper( a[0] ); // converting first character to upper case.
for(i=1; a*i+!=’\0’; i++)
{ if( a[i-1+==’ ‘ ) a[i]=toupper( a[i] ); // if previous char is space then word started
else a[i]=tolower( a[i] ); // if a[i] is not first letter of word then convert to lower
}
printf(“output string is %s ”, a);
}
C-Family 210 Strings

Accepting a text (multi line string) and printing on the screen.


This demo program accepts a multi-line string(text) in char by char from keyboard and prints on the screen.
Here char by char scanned until user pressed F6 as end of input. Because gets() or scanf() does not support
to scan more than one line from keyboard. Here every scanned character is stored into an array and later
prints on the screen.
void main()
{ char a[1000], ch; int i=0;
printf(“enter text at end of input, type F6 :”);
while(1)
{ ch=getchar(); // getchar() also accepts new line (enter key)
if(ch==-1) break; // the getchar() produces -1 , if input is F6.
a[i++]=ch; // storing into array
}
a*i+=’\0’; // inserting null character at end of text
printf(“\n output = %s”, a ); // printing text
}
Suppose input: “All apples are good,
all good are not apples,
some are so sweet
F6”
Output: All apples are good,
all good are not apples,
some are so sweet

Pointer to string
As we know, string can be in the form of variable or constant. In both cases, the strings are handled in
similar way. For example
char a[20+=”Hello”;
char *p=”World”;

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10] … a[19]
‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’ - - - - - - -

P  ‘W’ ‘o’ ‘r’ ‘l’ ‘d’ ‘\0’

As per first declaration, we can say that, the string is in the form of variable. In later part of the program, we
can replace this string “Hello” by some other string, but new string length must be <20 chars (array-size).

As per second declaration, we can say that, the string is in the form of constant. The space allocation for
string is exactly length+1(6 bytes), here first character address (&h) assigns to the pointer ‘p’. Now using ‘p’,
we can read the string “World”. In later part of the program we can replace this string “World” by some
other string, but the new string must be the same length or less. If more size then, it crosses memory limits
and causes program crash. Pointer initialization widely used when no changes happen in the strings like
company names, country name, codes, labels…etc.

Pointer to a string is just like a pointer to an array, either the string may be a variable or constant. In both
cases, the characters are accessed in similar way. If pointer ‘p’ is pointing to first character in a string, the
expression ‘*p’ accesses the first character, *(p+1) accesses the second character, etc. As we know, the
expressions *p, *(p+1), *(p+2)... can be written in array fashion as p[0], p[1], p[2],etc. For example
C-Family 211 Strings

char a*10+=”C-Family”;
char *p;
p=&a[0]; // p=a;
Now we can imagine pointer to a string as

p *p *(p+1) *(p+2) …
&a[0] ‘C’ ‘-‘ ‘F’ ‘a’ ‘m’ ‘i’ ‘l’ ‘y’ ‘\0’
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]

void main()
{ char a[ +=”C-Family”, *p;
p=a; // p=&a[0];
for(i=0; p*i+!=’\0’; i++)
printf(“%c”, *(p+i) );
for(i=0; p*i+!=’\0’; i++)
printf(“%c”, p*i+ );
for(i=0; *p=’\0’; i++)
{ printf(“%c”, *p );
p++; // increments to next char
}
}
The three loops print same output, the first two loops are same as they are accessing characters in a string
using pointer ‘p’ and ‘i’. Here the pointer will not be moved to end of string after completion of loop. But in
third loop, the pointer advances to next char after reading every single character. After completion of this
loop, the ‘p’ moves to end of string.

Passing string to a function


Already know that, how to pass an array to a function. Similarly, we can pass a string as an argument to a
function. Passing string to function is same as passing array to function. Here address of string is passed as
an argument and the receiving parameter must be “char*” type pointer.
This program demonstrates how to pass a string to the function
void main()
{ char a*20+= “Hello World”;
gets(a);
display(a); // display(&a[0]);
display(a+6); // display(&a[6]);
display(“C-Family"); // display(&C);
display("C-Family”+2);; // display(&F);
}
void display( char *p or char p[ ] ) // both declarations are same ( use only one)
{ int i;
for( i=0; p[i] !='\0'; i++)
printf ( %c", p[i] ); // printing char by char or use printf(“%s” , a);
}
output: Hello World
World
C-Family
Family
C-Family 212 Strings

The pointer parameter ‘p’ points to the string(s) in every call as given below

&a[0] ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘W’ ‘o’ ‘r’ ‘l’ ‘d’ ‘\0’
P a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]

&a[0] ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘W’ ‘o’ ‘r’ ‘l’ ‘d’ ‘\0’
P a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]

&C ‘C’ ‘-’ ‘F’ ‘a’ ‘m’ ‘i’ ‘l’ ‘y’ ‘\0’
P

&F ‘C’ ‘-’ ‘F’ ‘a’ ‘m’ ‘i’ ‘l’ ‘y’ ‘\0’
P

As we know, the parameter declaration “char *p” in pointer style is informal and sometimes confusion.
Most of the programmers prefer array-like-pointer declaration as “char p*+”. This is formal and it tells that ‘p’
is receiving string array address rather than single char address. The parameter declaration “char p*+” seems
to be an empty-array, actually, implicitly it is also a pointer of type “char *p”. This declaration provided for
easy understanding and nothing more

While manipulating strings, we often need to perform some common operations like copying a string,
concatenation of string, changing the case, comparing, reversing, finding sub-string, converting text
format to numeric, etc. As these operations are common in programming and we prefer to abstract (hide)
these tasks by writing separate functions for each operation. The string library functions named strlen(),
strcpy(), strcmp(), strrev(),etc are already exist to cooperate the programmer instead of writing from low
level. The following programs show, how string library functions are developed and used. Here some
sample user-defined functions are implemented to know how library function works internally.

Finding length of string using function


This function takes string as an argument and returns the length of it
int myStrlen( char *p )
{ int i;
for(i=0; p*i+!=’\0’; i++)
{ // empty loop, indirectly calculates length to ‘i’
}
return(i); // after loop, the value of ‘i’ contains length
}
void main()
{ char a*100+=”hello world”;
int k;
k=myStrlen(a); // myStrlen( &a[0] );
printf(“\n length1 = %d”, k);
k=myStrlen(“Computer”); // myStrlen( &C );
printf(“\n length2 = %d”, k);
}
Output: length1=11
length2=8
C-Family 213 Strings

Copying a string from one to another array


In programming, it is often need to copy a string from one to another location. For this, if one tries to copy a
string using assignment operator then compiler shows an error.
For example: char x*20+=”Hello World”;
char y[20];
y=x; // y=&x[0];
He we expect that, the string “Hello World” copies from x*+ to y*+, but compiler gives an error, because
unknowingly we are trying to assign the address of ‘&x[0]’ to ‘y’ (here ‘y’ is not a pointer, so it is an error).
The solution is, copying char-by-char from source to destination array.
y[0]=x[0]
y[1]=x[1]
y*2+=x*2+ …Using loop. Let us see, how following function copies it.
void myStrcpy( char y[], char x[] ) // y=x;
{ int i;
for(i=0; x*i+!=’\0’; i++)
y[i]=x[i];
y*i+=’\0’; // inserting null at end of string.
}
Main() fn to check the above function
void main()
{ char x*20+=”hello world”, y[20];
myStrcpy ( y, x );
printf(“\n After copying1, the string is = %s”, y);
myStrcpy( y, “C-Family”);
printf(“\n After copying2, the string is = %s”, y);
}
Output: After copying1, the string is = Hello World
After copying2, the string is = C-Family
// the above function can be written in pointer notation as
void myStrcpy( char *y , char *x )
{ while(*y++=*x++);
}
here the value *x assigns to *y, later checks the *y value, if it is null then loop terminates, otherwise, y++ &
x++ get incremented and loop continues till null is found.

Comparison of two strings


void main()
{ char x*20+=”Hello”, y*20+=”Hello”;
if( x==y) printf(“equal”); // if( &x[0] == &y[0] )
else printf(“not equal”);

if(“Hello”==“Hello”) printf(“equal”);
else printf(“not equal”);
}
Output: not equal
not equal
C-Family 214 Strings

Even though two array contents are same, the output will be ‘not equal’, because, unknowingly, we are
trying to compare base addresses of two arrays, the if(x==y) is nothing but if(x[0] == &y[0] ). As we know,
two arrays will not be located in the same location of RAM.

In second if-statement also, the base address of strings if(&H==&H) are compared and we get again “not
equal”. Because two string constants will not be located in the same location.
The solution is, compare char by char in two strings using loop, which is as given below
void myStrcmp( char x[], char y[] )
{ int i, j;
for( i=0; x*i+ != ’\0’; i++)
{ if( x[i] != y[i] )
break;
}
return x[i]-y[i]; // returning ascii difference
}
If both strings are equal then returns 0, otherwise returns +ve/–ve of first un-matched characters ASCII
difference of two strings. If return value is +ve, then string1>string2 in dictionary order(Alphabetical order)
or else string1<string2. For example, if two strings are:
“Hello” and “Hello” then returns (0);
“World” and “Words” then returns (‘l’-‘d’); // ascii difference is +ve
“Words” and “World” then returns (‘d’-‘l’); // ascii difference is -ve
The main() function to check the above function is
void main()
{ char x[50], y[50];
int k;
printf(“\n enter string 1:”);
gets(x);
printf(“\n enter string 2:”);
gets(y);
k=myStrcmp(x,y);
if( k==0) printf(“string1 == string2”);
else if( k<0) printf(“string1<string2”);
else printf(“string1 > string2”);
}

The above function myStrcmp() can be written in pointer notation as


int myStrcmp(char *x,char *y)
{ while(*x && *x==*y)
{ x++; y++;
}
return *x - *y;
}
C-Family 215 Strings

Concatenation of two strings


Sometimes, it is required to attach one string at the end of another string and this operation is often called
string concatenation.
Let x*+=”hello”, y*+=”world” after x=x+y, the ‘x[]’ will be “helloworld”
void myStrcat( char x[], char y[] )
{ int i , j;
for( i=0; x*i+!=’\0’; i++)
{ // empty loop, repeats until null character is found
}
for( j=0; y*j+!=’\0’; j++) // attaching second string at end of first string
x[i+j] = y[j];
x*i+j+=’\0’; // inserting null character at end of first string
}
void main()
{ char a*20+=”Hello”, b*20+=”World”;
myStrcat(a,b);
printf(“\n after concatenation of string1= %s”, a);
myStrcat( a, “ is Wonder”);
printf(“\n after concatenation of string2= %s”, a);
}
output: after concatenation of string1= HelloWorld
after concatenation of string2= HelloWorld is Wonder
This simplified form of this function using pointer is
void myStrcat( char *x, char *y )
{ while(*x) x++; // moving ‘x’ pointer to end of first string
while(*x++=*y++); // this loop copies all characters to ‘y’ including null
}
Here first, the expression ‘*x’ evaluates, if it is null then loop stops, otherwise, x++ is incremented to point
to next character in the string. In this way, *x is checked and x++ incremented until null is found.
In second loop, the expression *x++=*y++ evaluates in three times, in first time, the *y assigned to *x,
second time, the assigned character (*x) is checked whether it is null or not?, it is for loop condition.
If null then loop will be terminated. In third phase, the x & y are incremented.

Reversing a string
void myStrrev( char *a )
{ int i;
for(i=0; a*i+!=’\0’; i++)
{ // empty loop to calculate length, loop ends when ‘i’ reached to null char.
}
for( j=i-1, i=0; i<j; i++, j--) // ‘i’ points to first element, ‘j’ points to last element in the string.
{ t=a[i]; // swapping
i j
a[i]=a[j]; ‘A’ ‘B’ ‘C’ ‘D’ ‘E’ ‘F’ ‘G’ ‘H’ ‘I’ ‘J’
A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9]
a[j]=t;
}
}
C-Family 216 Strings

void main()
{ char a[100];
myStrrev( a );
printf(“\n string after reversing %s”, a );
}
ip: ABCDEFGHIJ
op: JIHGFEDCBA

String library functions


In previous examples, we have seen how to write & use string functions. Our C standard library contains a
wide range of well-developed string functions, which help us in minimizing the coding time and building
compact & reliable code without rewriting from the zero level. This library simplifies the logic of complex
programs without feeling any difficulty while handling strings. These function’s prototypes available in
“string.h” header file. So we can simply include and use the functions in our programs.
strlen()
This function takes string address as an argument and returns its length. It counts & returns the
number of characters in a given string without counting null character.
syntax is: intVariable=strlen( string );
proto-type is: int strlen( char * );
void main()
{ char a*30+=”Hello World”;
k=strlen(a);
printf(“\n string1 length = %d”, k);
k=strlen(“This is C-Family”);
printf(“\n string2 length = %d”, k);
}
Output: string1 length=11
string2 length=16
strcpy()
it copies a string from one location to another location and also appends null at end of string.
void main()
{ char a*30+=”Hello World”;
char b[30];
strcpy(b, a); // copies char by char including null.
printf(“\n after copying, the string1 is : %s”, b);
strcpy(b, “India”);
printf(“\n after copying, the string2 is : %s”, b);
strcpy(a, strcpy(b, ”Check It”) );
printf(“\n after copying, the string1&2 is : a=%s , b=%s”, a, b);
}
Output: After copying, the string1 is : Hello World
After copying, the string2 is : India
After copying, the string1&2 is : a=Check It , b=Check It
C-Family 217 Strings

strcat()
here ‘cat’ means concatenation, it attaches one string at the end of another string. That is, it concatenates
two strings like addition.
syntax: strcat( string1, string2 ); // string1=string1+string2;
proto-type: char* strcat( char*, char*);
void main()
{ char a*20+=”Hello”, b*20+=”World”;
strcat(a,b);
printf(“output1 = %s”, a);
strcat(a,”India”);
printf(“output2 = %s”, a);
}
Output: output1=HelloWorld
output2=HelloWorldIndia
strrev()
it reverses the given string
syntax: strrev(string);
proto type: char* strrev(char*);
void main()
{ char a*20+=”Hello”
strrev(a);
printf(“output1 = %s”, a);
strrev(a);
printf(“output2 = %s”, a);
}
output1: olleH
output2: Hello
strcmp()
compares two string whether they are equal or not? If both strings are equal then returns (0), otherwise
returns “first un-matched characters ASCII difference in +ve or –ve”.
If returned value is +ve, then string1>string2 in dictionary order (alphabetical order), or else string1<string2.
void main()
{ char a*30+=”Hello World”;
char b*30+=”Hello World”;
K=strcmp(a,b); // copies char by char including null.
if( k==0) printf(“both string are equal”);
else if(k<0) printf(“first string < second string”);
else printf(“first string > second string”);
k=strcmp(“xyz”, “abcdef”);
if( k==0) printf(“both string are equal”);
else if(k<0) printf(“first string < second string”);
else printf(“first string > second string”);
}
op: both string are equal
first string > second string
C-Family 218 Strings

strcmpi() or stricmp()
It compares two strings, which is same as strcmp(), but it ignores the upper/lower case of alphabets.
Syntax: int strcmpi(string1, string2);
void main()
{ if(strcmpi(“DELHI", "delhi")==0)
printf("Both are equal");
else printf("Not equal");
}
Outputs: Both are equal
strncmpi() or strnicmp()
It compares two strings up to some specified number of characters, and also ignores the case difference.
Syntax: int strncmpi( string1, string2, no-of-chars-to-compare);
void main()
{ if( strncmpi(“Garden", "gardening",3) == 0 )
printf("Both are equal");
else printf(“Not equal");
}
Output: Both are equal
strupr()
It converts all lower case alphabets into upper case in a given string.
Syntax: strupr( string);
void main()
{ char a[]="Pens and Pads";
strupr(a);
printf("%s", a);
}
Output: PENS AND PADS
strlwr()
It converts all upper case alphabets into lower case in a given string.
Syntax: strlwr( string);
void main()
{ char a[]="Jack n JILL";
strtwr( a);
printf("%s", a);
}
Output: jack n jill
strchr()
It searches for a given character in a string, it searches one by one from first position towards end of string.
It returns first occurrence of a specified character address if it is found. Otherwise it returns NULL value.
Syntax: char* strchr(string, char to search);
void main()
{ char *p;
p=strchr("Hello world", ‘w’); // returns “&w” in “hello world” string.
printf("%s", p);
}
C-Family 219 Strings

This printf() will prints the message "world" , because ‘p’ pointing rest of the string “world”

&a[6] ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘W’ ‘o’ ‘r’ ‘l’ ‘d’ ‘\0’
P a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10] a[11]

strstr()
it searches for a sub-string in a given main-string. It returns the first occurrence of sub-string address if it is
found. Otherwise, it returns NULL, if not found.
void main()
{ char *p;
p=strchr("I like you very much", “you”);
printf("%s", p);
}
This printf() will print the message "you very much"

&a[6] ‘I’ ‘ ’ ‘l’ ‘i’ ‘k’ ‘e’ ‘ ’ ‘y’ ‘o’ ‘u’ ‘ ’ ‘v’ ‘e’ ‘r’ ‘y’…
P a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10] a[11] a[12]

atoi()
It converts a numeric-string value into equivalent integer-value.
Syntax: int atoi(string);
Example: int k;
k= atoi("123")+atoi("234");
printf(" output = %d", k);
output will be: 357
atol()
Converts long int string value to equivalent long integer value
Syntax: long int atol(string);
Example: long int k;
k= atol("486384")-atol("112233");
printf(“output = %ld”, k);
output will be = 374151
atof()
Converts floating point text format value to double value.
Example: float f;
f=atof("3.1412")*5*5;
printf(“%f “, f);
output will be: 78.530000
itoa(),itoa(),ultoa()
These functions converts a given number (int/long int/unsigned long int)equivalent to string format based
on the given numbering system radix value.
These functions take three arguments, the numeric value, target string address in which the value to be
stored and radix value. Finally returns the target string address, so that function-call can be used as
argument/expression.
C-Family 220 Strings

syntax: char* itoa(int value, char *targetStringAddress, int radix);


example: char temp[50]; // to store output string
itoa(45, temp, 2); // converting 45 to binary system value
printf("output : %s", temp);
output : 101101
itoa(45, temp, 8); // converting 45 to octal system
printf("output : %s", temp);
output :37
sprintf()
It is like printf() function but with a little difference. The printf() puts the data on the screen, whereas
sprintf() puts the data in a given char-array. It converts argument value into a format string (text) and stores
into given array.
Syntax: sprintf( array, format-string, arguments );
Example: char a[100];
sprintf(a, "Idno=%d , name = %s , salary = %f”, 101, "Srihari", 50000.00);
Observe the following output, how it copies formatted-string to array a[]
printf(“%s”, a);  Idno=101, name=Srihari, salary=500000.00
sscanf()
It is also like normal scanf() function. But scans formatted-string from given array instead of keyboard.
Syntax: sscanf( array, format-string, &variable1 [, &variable2,..]);
Example: char a[] = "101 Srihari 50000";
sscanf(a, "%d %s %f “, &idno, &name, &salary );
printf(“ %d %s %f”, idno, name, salary);  101 Srihari 50000

List of N Strings (Strings in 2D array)


(Before coming to this topic, you better to revise a topic: pointer to 2D array, page number 196 in this book)
This chapter mainly concentrated on how to represent array of strings and operations such as inputting,
printing, sorting, searching, and finding sub-strings, etc.

To store a group of strings, we need a data structure like 2-dimensional array with N*M size, where N is
number of strings and M is maximum size of string length.

For example: char a[20][30];


in this array, we can store 20 strings each with a maximum length of 29 characters (1 for null).
Accessing of these strings is same as accessing of 2D arrays.

Initialization list of N strings


We can initialize a group of strings just as single string but use comma (,) operator to separate two or more
strings. Observe the following example:
char a[10][20]={ “APPLE”, “ORANGE”, “BANANA”, “ GUAVA”,…etc};
We can imagine, how the strings are stored in 2D array

‘A’ ‘P’ ‘L’ ‘L’ ‘E’ ‘\0’ …


‘O’ ‘R’ ‘A’ ‘N’ ‘G’ ‘E’ ‘\0’’
‘B’ ‘A’ ‘N’ ‘A’ ‘N’ ‘A’ ‘\0’
‘G’ ‘U’ ’A’ ‘V’ ‘A’ ‘\0’

C-Family 221 Strings

How to accept & print a list of strings?


Scanning a group of strings is just like scanning ‘N’ individual strings. The way is, scanning string after string
from keyboard using loop statement. If we use 2-dimensional array then we have to pass each row base
address of array to the scanf() function. The following program shows how to scan and print.
void main()
{ char a[20][30];
printf(“Enter number of strings :");
scanf("%d" &n);
for(i=0; i<n; i++)
, printf(“Enter string %d :", i+1);
flushall();
gets( a[i] ); // gets(&a[i][0]);  passing each row base address of array to the gets() function
}
for(i=0; i<n; i++)
puts( a[i] ); // puts(&a[i][0]);  passing each row address to puts() function
}
We know, the 2-dimensional array expressions a[i][j] converts into *(a+i*column-size+j);
Whereas, the expression a[i] converts into (a+i*column-size), which gives ith row address.
(refer pointer to 2D array topic, page 196)

This program finds the biggest string from N strings.


(Here biggest means alphabetically comes to last in dictionary order)
#include<stdio.h>
#include<string.h>
void main()
{ char a[20][30], *temp, n, i;
printf(enter number of strings :");
scanf("%d",&n);
for(i=0; i<n; i++)
{ printf(“enter string %d :", i+1);
fflush(stdin); // clears the keyboard buffer
gets(a[i]);
}
temp=a[0], // assume the first string as the biggest
for(i=1; i<n; i++)
{ if( strcmp(a[i], temp) > 0 )
temp=a[i];
}
printf("Biggest string = %s", temp);
}
In the above program, the first string is considered as bigger; therefore its base address is stored in 'temp'
pointer. Later all strings are compared with 'temp', if any bigger string is found in the rest of array, then its
address is copied to 'temp'. In this way, finally biggest string address will be stored in ‘temp'.
C-Family 222 Strings

Sorting of ‘N’ Strings


We can sort strings just like integers, but strings cannot be compared using > operator, because base
address are compared instead of strings. So the library function strcmp() is used to compare two strings.
Following program gives demo for sorting of N strings.
#include<string.h>
void main()
{ char a[20][30]; int n;
scan(a,&n); // scans n strings
sort(a,n); // using bubble sort
print(a,n); // printing all string
}
void scan(char a[ ][30] , int *pn)
{ int i;
printf(“enter number of strings :");
scanf("%d", pn);
for(i=0; i<*pn; i++)
, printf(“enter string %d :",i+1);
fflush(stdin); // clears keyboard buffer
th
gets( a[i] ); // inputting i string
}
}
void sort( char a[ ][30], int n ) // bubble sort
{ int i,j,k; char t[30];
for(i=n-1; i>0; i--)
for(j=0; j<i; j++)
{ if( strcmp(a[j],a[j+1] > 0 )
{ strcpy(t,a); // swapping the strings
strcpy(a,b);
strcpy(b,t);
}
}
}
void print(char a[][30], int n)
{ int i;
for(i=0; i<n; i++)
puts(a[i]);
}
C-Family 223 Strings

Initialization of strings to the pointer array


If string constants are fixed and do not require any modifications during program execution then it is better
to initialize to the pointer array rather than normal 2D array, because, it saves a lot of memory space and
also easily manageable such as swapping of strings, sorting of strings, inserting a new string b/w strings,
deleting existing string, etc. Here addresses are manipulated instead of its data.
For example: char *p[] = {"crore", "lakh", "thousand", "hundred"};
Here all these strings are stored in the data area of a program, and their addresses are assigned to the
pointers. Here memory occupied by each string is equivalent string length+null. This is as given below

P[0] P[1] p[2] P[3]


2020 2090 3012 5378

“crore” “lakh” “thousand” “hundred”


2020 2090 3012 5378

This program accepts a number and prints in English words


Input: 2345
Output: two thousand three hundred and four five
#include<stdio.h>
void main()
{ char *a[] = {"", "one","two","three","four","five","six","seven","eight","nine"};
char *b[] = {"","", "twenty", "thirty","foury","fifty","sixty", "seventy", "eighty","ninty"};
char *c[]={"crore", "lakh", "thousand", "hundred and",""};
long int d[]={10000000l,100000l,1000l,100,1}, n, quotient, i;
printf("enter any number :");
scanf("%ld",&n);
for(i=0; n>0 ;i++)
{ quotient=n/d[i];
if(quotient==0) continue;
if(quotient<20)
printf(" %s ", a[quotient] );
else
printf(" %s %s ", b[quotient/10], a[quotient%10] );
printf(" %s ", c[i] );
n=n%d[i];
}
}
Here the input number divides repeatedly with crore, lakh, thousand, hundred, etc
If quotient is zero then there is nothing to print on the screen so loop continues for next cycle.
Otherwise, prints equivalent words in English and takes remainder as next input for next cycle.
C-Family 224 Recursion

Recursion
Calling a function within the same function is called as recursion. It is the process of defining something in
terms of itself, and is sometimes also called as circular definition.
The syntax, the usage, and the execution of recursive function is just like any normal function. There is no
technical difference between recursive and normal function. However, for beginners, the logic of recursion
is somewhat difficult to understand and writing programs in it. The major confusion is, understanding the
logic regarding self-calling, self-returning, and how the arguments & local variables are managed in
recursive-calls. If you are familiar with functions, here by observing some simple examples we can follow the
logic easily. Here some examples explained with pictures to understand the basic concept of recursion.
Let us see the following simple examples, how recursive calls are made, before that, let us see some
mathematical analysis recursion.

1) f(n)=n+n/2+n/4+n/8+….+1
the recurrence relation is:
f(n)=n+f(n/2) if n>1
f(n)=1, if n==1

2) fact(n) = n*n-1*n-2*….3*2*1
the recurrence relation is:
fact(n)=n*fact(n-1), if n>1
fact(n)=1, if n==1

3) power(x,y) = x*x*x*x….y times


the recurrence relation is:
power(x,y) = x*power(x,y-1), if y>1
power(x,y) = 1, if y>0
=======================================================================================
First demo program

void main()
{ printf(“hello ”);
main(); // self-calling (recursive-call )
}

output: hello hello hello hello … until stack overflow (memory full)
Here the main() fn called recursively inside its body, therefore control re-enter into same body again and
again as it repeatedly called again and again(), it prints “hello” message many times, but in every recursive
call some memory is consumed by operating system to store function-return-address, after some calls, the
memory gets full and program gets crashed.

Let us see, how local variables behave inside recursive function.


C-Family 225 Recursion

void main()
{ int k=1;
if( k==5)
return;
printf(“%d ”, k );
k++;
main(); // self-calling (recursive-call)
}
Here we expect the output 1, 2, 3, 4, it is wrong. It shows 1, 1, 1, 1, 1, … until memory is full. For every
recursive call, one extra new variable ‘k’ is created and initialized with 1. So for every call of function, a
separate fresh copy of ‘k’ is created and initialized with 1. So output is 1, 1, 1, 1…..
Here the k value never reaches to 5, the incremented ‘k++’ at one call, will not be affected to next call of ‘k’,
so always prints 1,1,1,1….. until memory full.
Note: For our program variables, the operating system reserves some amount of space in RAM (stack
segment), when this memory gets full then OS shows stack-overflow error. Here for every recursive call, one
copy of ‘k’ is created, after some calls many k’s are created and makes the memory full.

Understanding Recursion (with above example)


When a recursive function is called itself, the programmer should be treated it as, he is calling another
function(copy) of same code as shown in the below figure. Of course, in the memory, same function
code will be executed with different data sets. (like k values)

For every recursive call, one set of local variables (in this example ‘k’) are created and available up to
that call is terminated. That is, when such call is terminated, all local variables are freed (deleted). The
recursive function executes just as any normal function in the system. Therefore, to share(use) local
variables over several calls, we have to pass them as an arguments between function calls.

Recursive function executes like a loop statement, as we know, every loop has a terminating condition,
in the same way, to stop the recursive calls, there must be termination condition and often called it as
base condition. Generally, it appears at the beginning of function (we will see in the examples).
This figure explains how recursive calls are made for above example code

Call-1 Call-2 Call-3 Call-4


void main() void main() void main() void main()
{ int k=1; { int k=1; { int k=1; { int k=1;
if( k==5) if( k==5) if( k==5) if( k==5)
return; return; return; return;
printf(“%d ”, k ); printf(“%d ”, k ); printf(“%d ”, k ); printf(“%d ”,k);
k++; k++; k++; k++;
main(); main(); main(); main();
} } } }

*Here in every recursive call, one fresh copy of ‘k’ is created initialized with 1, the incremented k++ will not
be affected to next call. So output is 1 1 1 1….

Taking ‘k’ as parameter instead of local variable, let us see following example
C-Family 226 Recursion

void main()
{ display(1); // passing argument 1
}

void display(int k)
{ if(k==5) // termination of recursion
return;
printf("%d ", k);
display(k+1); // recursive call
}
Output: 1 2 3 4
For every next call, we are passing k+1 value as argument, therefore at first-call k=1, at second-call k=2,…
At 5th call k=5, here terminates the recursion and returns the control. So output is 1,2,3,4.
When above ‘return’ statement gets executed in recursion, people think that, the control immediately
transfer back to main(), this is the big misunderstanding many people think like that, actually here the
control returns to previous-call in the series of calls. Here is the following example explains clearly.

*Printing 1 2 3 3 2 1 recursively
void main()
{ display(1); // passing argument 1
}
void display(int k)
{ if(k==4) return;
printf("%d ",k); // printing output before going to next-call
display(k+1);
printf("%d ",k); // printing output after coming back from next-call
}
Here the output '1 2 3' prints by first printf(“%d “, k), whereas second output '3 2 1' prints by second
printf(“%d “, k) statement. The first printf() executes just before next call is made. Whereas second printf()
executes just after returning from next-call.
This figure shows how the output 1 2 3 3 2 1 prints on the screen.
void main()
{ display(1);
}

1st call, here k=1 2nd call, here k=2 3rd call, here k=3 4th call, here k=4

void display( int k) void display( int k) void display( int k) void display( int k)
{ { { {
if(k==4) if(k==4) if(k==4) if(k==4)
return; return; return; return;
printf(“%d “, k); printf(“%d “, k); printf(“%d “, k); printf(“%d “, k);
display(k+1); display(k+1); display(k+1); display(k+1);
printf(“%d “, k); printf(“%d “, k); printf(“%d “, k); printf(“%d “, k);
} } } }
C-Family 227 Recursion

The last closing braces works as ‘return‘ statement in the function, like above shown picture.
Recursive function executes like a loop statement. As we know, every loop has a terminating condition,
in the same way, to stop the recursive calls, there must be termination condition and often called as
base condition. Generally, it appears at the beginning of function. Here in this example if(k==4) return;

Printing output N, N/2, N/4, N/8, N/16, ...1 using recursion


This function takes N as argument and prints output from N to 1.
ip: N=100
op: 100, 50, 25, 12, 6, 3, 1
void main()
{ int N;
scanf(“%d”, &N);
show(N);
}
void show(int N)
{ if( N==0) return;
printf(“%d “, N);
show(N/2); // sending half value to next call
}
Note: Most of the recursive programs covered in this chapter are simple and these can be done using any
loop control statements rather than recursion. For these problems, loop is simpler than recursion;
just to make easy understanding of recursion, these problems explained in recursion. The last two
problems can’t be solved using loops.

Printing output 1, ….. N/4, N/2, N using recursion (reverse output of above program)
This function takes N as argument and prints output from 1 to N.
ip: N=100
op: 1, 3, 6, 12, 25, 50, 100
void main()
{ int N;
scanf(“%d”, &N);
show(N);
}
void show(int N)
{ if( N==0) return;
show(N/2); // sending half value to next call
printf(“%d “, N); // printing while going back to previous-call
}
C-Family 228 Recursion

Printing 1 to N numbers using recursive function


ip: N=13
op: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13.
void main()
{ int N;
scanf(“%d”, &N);
show(N);
}

void show( int N )


{ if(N==0) return;
show( N-1);
printf(“%d “, N ); // the value N is printed while returning control to previous call
}
when ‘N’ reaches to 0, the recursive calls are stopped, and prints ‘N’ value from last-call to first-call while
returning control (back-tracking).

Printing Multiplication table using recursion


Output: 8*1=8
8*2=16
8*3=24
… 10 terms
void main()
{ printTable(8,1); // here ‘8’ is table number, ‘1’ is first term value.
}
void printTable( int n , int i )
{ if(i==11) return;
printf("\n %d*%d=%d", n, i, n*i);
printTable(n, i+1); // i+1 is the next term value
}

Printing Multiplication table upto desirable number of times


void main()
{ printTable(8,20); // here ‘8’ is table number, 20 is the number of terms to print.
}
void printTable( int n , int i )
{ if(i==0) return;
printTable(n, i-1);
printf("\n %d*%d=%d", n, i, n*i);
}
C-Family 229 Recursion

Printing output 1, 2, 4, 8, 16, …. <1000 using recursion


void main()
{ show(1); // ‘1’ is the first value of series
}
void show(int P)
{ if(P>1000) return;
printf(“%d “, P ); // p = 1, 2, 4, 8, 16 …
show(P*2);
}

Printing output 1, 2, 4, 8, 16, …. N times using recursion


void main()
{ int N=20; // no.of times to print
show(1, N); // ‘1’ is the first value of series and N is the number of times to print
}
void show(int P, int count)
{ if( count==0) return;
printf(“%d “, P); // p = 1, 2, 4, 8, 16… , count=20,19,18, …..3,2,1
show(P*2 , count-1);
}

Generate and print list of numbers from N to 1


Here N is input from keyboard and print list of numbers as long as the value of N becomes 1.
if N is even then next number of N is → N/2 (half)
if N is odd then next number of N is → 3N + 1
if input N is 13, then we have to print as: 13, 40, 20, 10, 5, 16, 8, 4, 2, 1
void main()
{ int N=13;
show(N);
}
void show(int N)
{ printf(“%d “, N);
if(N==1) return;
if( N%2==0)
show(N/2);
else
show( 3*N+1);
}
C-Family 230 Recursion

Finding factorial of a given number using recursive function


The recursive definition of a factorial can be written in mathematical form as
f(n)=n*f(n-1) i f n>1
f(n)=1 if n=0or1
f(5)=4*f(3)
4*3*f(2)
4*3*2*f(1)
4*3*2*1
24
int fact(int n)
{ if(n==1)
return 1; // base condition
return(n*fact(n-1)); // fact(n-1) is a recursive call
}
void main()
{ int k;
k=fact(4);
printf("%d ",k);
}

First call (n=4) Second call (n=3) Third call (n=2) Fourth call (n=1)

int fact(int n) int fact(int n) int fact(int n) int fact(int n)


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

// return(4*6) // return(3*2) // return(2*1) // return(1)

Finding factorial in iterative process (using loop) is the simple & easy compared to recursion. This is just
a demo program to explain the logic of how recursion executes.

The last call returns ‘1’ and is substituted in its previous-call, the previous-call again returns ‘2*1’ and is
substituted in its previous call. In this way, the final result 24 is returned to main() fn.

Find xy, where ‘x’ is base and ‘y’ is exponent


The recurrence relation is
fun(x,y) x*fun(x , y-1) if y>1
fun(x,y)  1 if y==0

int power(int x, int y)


{ if(y==0)
return 1;
return x*power(x, y-1);
}
void main()
{ int a=2,b=3,c;
c=power(a,b);
printf("\n %d^%d=%d",a,b,c);
}
C-Family 231 Recursion

Recursive function to find GCD. (Greatest Common Divisor)


This program finds the greatest common divisor of two numbers
Let the input values are x & y, where x<y. (The given below logic is also works if x>y)
The recursive definition can be written in mathematical form as
f(x,y)=f(y%x , x) if y%x != 0
f(x,y)=x. if y%x == 0

The logic is, continuously divide the y with x until remainder is zero. Here take y as dividend and x as
devisor. If y%x is zero then x will be the GCD and stop the process. If y%x is not zero then take x value to y
and y%x value to x for next cycle. Do this process until y%x==0.
For example, the input values are 12 and 18 then the function and their calls are as

x y x y stop
12 ) 18 ( 1 6 ) 12 ( 2
12 12
6 0

x=12, y=18 x=6, y=12

void main() int GCD( int x, int y ) int GCD( int x, int y )
{ { {
int k; if(y%x==0) if(y%x==0)
k=GCD(12 , 18); return x; return x;
printf(“\n gcd=%d”, k); return GCD(y%x , x); return GCD(y%x , x);
} } 6 }

k=6 return(6) return(6)

Find best code of following recursive functions, which finds sum of 1+2+3+…+N

void main() Void main()


{ int n=4, sum; { int n=4, sum;
sum=find(n, 0); sum=find(n);
printf(“sum=%d”, sum); printf(“sum=%d”, sum);
} }

int find(int n, int s) int find(int n)


{ if(n==0) { if(n==0)
return s; return 0;
s=s+n; return n+find(n-1);
return find(n-1,s); }
}
C-Family 232 Recursion

Printing Fibonacci numbers up to n terms


Recursive function to print Fibonacci series up to user desirable limits.
void fibo(int n)
{ int x=0, y=1, new; // here x, y, new are local variables to the function.
if(n==0) return; // stop condition
printf("%d ", x);
new=x+y; // generating next new term
x=y; // moving x,y to next terms
y=new;
fibo(n-1);
}
void main()
{ int n;
printf("enter how many no of terms to print:");
scanf("%d", &n);
fibo(n);
}
output: 0 0 0 0 0 0 0 0 0 0 0 0 0…… (Wrong output)
The above function produces wrong output. Because, for every recursive call, one fresh copy of local
variables x &y are created and initialized with 0 and 1. (We already discussed many times)
To solve this problem take x,y as parameters and pass previous-call updated value to next-call.
This is shown below
void fibo(int x, int y, int count)
{ if(count==0) return; // repeat until ‘count’ down to 0.
printf("%d ", x );
fibo(y, x+y, count-1);
}
void main()
{ int count;
printf("enter how many no of terms to print:");
scanf("%d", &count);
fibo(0, 1, count);
}

In this program, one can think that, only one copy of x, y is enough for all recursive calls
rather than creating fresh copy in every call. So to avoid these additional copies, we can
declare x, y as static/global. But there is a problem! Once static/global variable is created, it
will not be killed even after function ends; moreover they cannot be reinitialized for
int k=1;
upcoming calls. Let us have one more example with global variable
C-Family 233 Recursion

int k;
void main()
{ show(); // at this call, output is 1 2 3 4
show(); // at this call, no output
}
void show()
{ if(k==5) return;
printf(“%d “, k);
k++;
show();
}
op: 1 2 3 4
we expect output as 1 2 3 4 1 2 3 4 [as two times show() fn called from main()], as ‘k’ is global variable,
only one copy is created and shared to all calls. After printing 1 2 3 4 at first call in main(), the k attains 5 and
will not be re-initialized to 1. So for 2nd call at main(), no output is displayed.

Finding Nth Fibonacci number using recursion


Consider the first two terms are 0 & 1 and remaining terms generate by adding previous two values.
fibo(n) = fibo(n-1)+fibo(n-2). if n>2
fibo(n) = 0. If n==1
fibo(n) =1. If n==2
0 1 1 2 3 5 8 13 21 34 55 89 …
1 2 3 4 5 6 7 8 9 10 11 12 ..

Fibo(5)  fibo(4)+fibo(3)
 fibo(4-1)+fibo(4-2)+fibo(3-1)+fibo(3-2)
 fibo(3-1)+fibo(3-2) +fibo(2)+fibo(2)+fibo(1)
 fibo(2)+fibo(1)+fibo(2)+fibo(2)+fibo(1)
1+0+1+1+0  3
void main()
{ int n=5;
x=find(n);
printf(“ the Nth term = %d”, x);
}
int fibo( int n)
{ if(n<=2)
return(n-1);
return fib(n-1)+fibo(n-2);
}
Observe the following figure and try to understand how recursive calls are made.
C-Family 234 Recursion

int fibo( int n : 5 )


{ if(n<=2)
return(n-1);
return fibo(n-1)+fibo(n-2);
}

int fibo( int n : 4 ) int fibo( int n : 3 )


{ if(n<=2) { if(n<=2)
return(n-1); return(n-1);
return fibo(n-1)+fibo(n-2); return fibo(n-1)+fibo(n-2);
} }

int fibo( int n : 3) int fibo( int n : 2 ) int fibo( int n : 1 ) int fibo( int n : 1)
{ if(n<=2) { if(n<=2) { if(n<=2) { if(n<=2)
return(n-1); return(n-1); return(n-1); return(n-1);
return fibo(n-1)+fibo(n-2); return fibo(n-1)+fibo(n-2); return fibo(n-1)+fibo(n-2); return fibo(n-1)+fibo(n-2);
} } } }

int fibo( int n : 2 ) int fibo( int n : 1 )


{ if(n<=2) { if(n<=2)
return(n-1); return(n-1);
return fibo(n-1)+fibo(n-2); return fibo(n-1)+fibo(n-2);
} }

While terminating function calls, the following statements are gets executed

return (2+1)

return(1+1) return (1+0)

return(1+0) return(2-1) return (2-1) return (1-1)

return( 2-1) return(1-1)

Program to print all permutations of a given string


input: ABC
output: ABC
ACB
BAC
BCA
CAB
CBA
int main()
{ char a[]= "ABC";
permute(a, 0, strlen(a)-1 );
}
void permute(char a[ ] , int i, int len)
{ int j;
if(i==len)
C-Family 235 Recursion

{ puts(a);
return;
}
for(j=i; j<=len; j++)
{ k=a[i]; a[i]=a[j]; a[j]=k; // swapping a[i], a[j]
permute(a, i+1, len);
k=a[i]; a[i]=a[j]; a[j]=k; // swapping a[i], a[j]
}
}

Program to traverse entire chessboard with Knight (horse)


The following demo program is to traverse the entire chessboard with knight. Here Night visits every cell
only once and it follows the rules of its movement ie, it moves only in L shape. This function takes x, y
coordinates of first step of 8x8 board and displays order of movements in terms of step-number of every
cell. Following figure gives an idea
6
1
7 5 2
4
8.. 3

int steps[8][2]={{-2,-1}, {-2,+1}, {-1,+2},{+1,+2}, {+2,+1}, {+2,-1},{+1,-2},{-1,-2}};


// this values are to choose all 8 possible L shape steps from the current standing step
int a[8][8]; // chess board, where step movements are recorded.
#define bSIZE 5 // currently we are taking chess board size as 5
void main()
{ int x,y;
printf("enter first step x, y values :");
scanf("%d%d", &x, &y);
chess(x,y,1); // x,y are first step-step cell values, and 1 is first-step order
}
chess(int r, int c, int stepNo)
{ int i;
if(r<0 || r>bSIZE-1 || c<0 || c>bSIZE-1 || a[r][c]!=0) // if stepped out of chess board area
return; or already such cell is entered then go back
a[r][c]=stepNo; // making a cell as visited
gotoxy(10+c*4, 10+r*2); // printing in a particular position
printf("%4d", stepNo); // printing step number on the screen
delay(1000); // delaying program to watch steps carefully
if( kbhit()) exit(0); // if any key pressed program will be stopped
if( stepNo==bSIZE*bSIZE) exit(0); // if reaches all cells, then program stops
for(i=0; i<8; i++) // stepping into next cell by choosing 8 possibilities
chess( r+steps[i][0], c+steps[i][1], stepNo+1);
a[r][c]=0; // if next choosing position is not good then go back
gotoxy(10+c*4, 10+r*2); // removing step from screen
printf(" ");
delay(1000);
}
C-Family 236 Recursion

Advantages and Disadvantages of recursion


Every recursive algorithm can be converted into non-recursive with the help of loop control and sometimes
with stack. However, doing so, some programs may increase the complexity in code and prone to logical
errors, and even it is difficult to debug the iterative code. So coding recursive nature problems, recursion is
simpler than iterative process.
Recursive function slows the execution of program because of creation & destroying of local variables.
Additional storage space also required to store function return-address. But writing code in recursion is easy,
clear, and modify.
We know passing arguments from one to another function is common in modular programming. If any set of
arguments need to be passed to a recursive function, then same set of arguments have to be passed for
every call, even though they are unnecessary. In some cases, it is useful, however, in some other cases, it
seems to be unnecessary, ie, one copy is enough for all calls. There is no alternative to overcome this
problem. One might think that about usage of static or global variables, but once static variable creates, it
will exist till the end of entire program. Second time if the same function is called it will not be reinitialized
automatically. So using such variable is not suggestible.
Conclusion
If your recursive application is to be used frequently which is considerably making unnecessary copy of local
variables and if you are fit enough to write non-recursive code then it is most advisable to implement in non-
recursive as it would be faster and takes lesser space.

If an application is very complex, having rare usage, and taking less space for local variables, then it is better
to implement recursive rather than non-recursive. Recursive is simple and easy to code
It is the programmer’s choice, which method is to be used when and where. If execution time and space are
not constraints, then it is better to implement recursive application.
Implementation of recursion nature problem in non-recursive using loop and stack is an advanced concept.
That topic is beyond the scope of this book.
C-Family 237 Dynamic Memory Allocation

Memory Allocation Systems


Memory for variables can be created in two ways ① static allocation ② dynamic allocation

Static allocation system


If size or count of data items is known at coding time then static allocation is the good choice. The static allocation system is
managed by compiler by adding necessary machine code instructions in the program. The compiler adds extra instructions
in our program for allocation/de-allocation of memory for our variables. So programmer need not to bother about how
variable’s memory is created and destroyed in the program. Let us see following example

void test() void test()


{ {
int a, b, c[100],d ; Here compiler adds instructions to allocate
---- 206 bytes of memory for a, b, c[], d.
---- ----
----
----
----
----
Here also adds instructions to free such 206 bytes of
----
memory which is allocated above.
(before closing the test() function)
}
}

Here compiler creates 206 bytes of memory for int a, b, c[100], d. It adds instructions for allocation & de-
allocation of memory in our program [It creates memory in stack as stack.push(206) and stack.pop(206) ]
The static allocation system is much suitable when we know the size of data like employee-name(25 chars),
address(50 chars), pin-code(6), phone-number(12),…
Dynamic Memory Allocation system
in many real time systems, the count/size of data items are not known or cannot be expected until runtime.
Here dynamic system is the alternative to the programmer. Dynamic allocation refers to the allocation of
such memory during execution of program. Here programmer needs to allocate & de-allocate the memory
with the help of pointers.
This DMA system provides us to create, expand, reduce, or even destroy the memory at runtime. This
feature is very much useful for efficient memory management especially while handling huge collection of
data using ‘data structures’ for example arrays, lists, stacks, queues, trees, graphs, etc. To work with this
feature, C provides the following built-in functions
1. malloc() // include alloc.h or malloc.h file to use these functions
2. calloc()
3. realloc()
4. free()
malloc()
It allocates required size of memory and returns the starting byte address (called base address). This
allocated memory is said to be raw-memory and where we can store any type of data such as int, float, char,
etc. For this reason, malloc() returns an address which has no type. That is, it returns address as “void*”
type and it is often called generic address. Unfortunately, if memory is not available then malloc() or other
functions returns NULL value.
prototype: void* malloc(unsigned int);
syntax: pointer= malloc( no of bytes to be allocated);
example: p=malloc(10); // creates 10 bytes of memory and gives starting address to ‘p’
In the above example, the function malloc() allocates 10 bytes of memory in the RAM and returns the
starting byte address, which is then assigned to 'p'. Here one question arises! What type of pointer ‘p’
C-Family 238 Dynamic Memory Allocation

should be? This is fairly depends upon what type of data we are going to keep in this memory. Suppose if we
are going to store array of float values then pointer should be “float*” type. Remember that malloc() returns
just address which has no type, that is, it returns “void*” type address. So it should be type casted as per
our pointer type. (All malloc(), calloc() and realloc() function’s return-type is void* type)

Example: Allocating memory for ‘n’ integers


int n=5, *p;
Converting void* to int*
p= (int *)malloc( n*sizeof(int) );

The above allocated memory maps to the pointer ‘p’ is as follows:

P[0] P[1] P[2] P[3] P[4]


P *p *(p+1) *(p+2) *(p+3) *(p+4)
2000
4000 2000 2002 2004 2006 2008

How to access dynamic memory?


Accessing this memory is same as accessing elements in the array through pointer.
Observe the following expressions
*(p+0)  p[0] accesses the first location (first 2bytes)
*(p+1)  p[1] accesses the second location (second 2bytes)
*(p+2)  p[2] accesses the third location
*(p+i)  p[i] accesses the i+1th location.
The array and pointer relation already said in pointer chapter.
If your creating memory for floating point values, then float* type pointer is required.
For example creating memory for ‘N’ floats. Here ‘N’ is the input value

float *p; P *p *(p+1) *(p+2)….


scanf(“%d”, &N); 2000
4000 2000 2004 2008….
p=(float *)malloc(N*sizeof(float));

Demo program, accepting ‘N’ integers and printing


#include<alloc.h> ,
void main()
{ int n, i, *p;
printf(“enter no.of input values:”);
scanf(“%d”, &n);
p=(int*) malloc( sizeof(int)*n );
if(p==NULL)
{ printf(“\n error, memory not created");
return;
}
for(i=0; i<n; i++)
{ printf( "enter any value :");
scanf( “%d", &p[i] );
}
for(i=0; i<n; i++)
printf("%d “, p*i+ );
}
C-Family 239 Dynamic Memory Allocation

In the above, the array creates with the input size ‘n’, later access through the pointer ‘p’. Here the input
size(n  no.of input values) can be anything, thus it makes efficient usage of memory.

calloc()
It is also like malloc(), but after allocation of memory, it clears the garbage values by filling with zeros in all
bytes of memory.
pointer = calloc (no.of items, size of item );
It takes two arguments, first one is number of items to be allocated and second one is size of the item. For
example, allocating memory for 5 floats
float *p;
p = (float *) calloc(5, sizeof(float));

realloc()
It is used to resize (reduce or expand) the memory which is already allocated using malloc() or calloc() or
realloc(). It takes previously allocated memory address and adjusts to new size.

While expanding the size of old memory, if required amount of memory is not available at the adjacent
locations, then it allocates in new location and copies the old memory contents to newly allocated area and
then releases the old memory. If the memory is not available, then it returns null.
syntax: pointer = realloc( oldAddress, newSize);
For example
int *p,
p=(int*)malloc(10*sizeof(int));
----
p=(int*)realloc(p , 20*sizeof(int)); // expanding 10 integers to 20 integers
----
p=(int*)realloc(p , 5*sizeof(int)); // reducing 20 integers to 5 integers
----
Note: p=(int*)realloc(NULL, 10*sizeof(int)) // here oldAddress is null, so it creates fresh memory like malloc() function.
free()
It is used to release the memory which is no longer required by the program. This memory should not
belongs to static allocated system like “int a[10]”. This must be a dynamic memory which is allocated by
malloc() or other functions. It takes the base address of memory as an argument and frees it.
Prototype: void free(void *);
Syntax: free(address);
Example: int *p;
p=(int *)malloc(50*sizeof(int));
---
---
free(p);
Prone and cons of systems
Program’s data area divides into stack & heap area. In stack area, the temporary local variables and function
call-return addresses are stored, whereas in heap area, permanent variables are stored. For DMA system a
special block of memory is created in the RAM and managed as heap.
In static system, at coding time (before compilation), the size of array must be defined with constant value
and it cannot be changed at run time.
C-Family 240 Dynamic Memory Allocation

Allocation of static memory is faster than dynamic, because allocation of memory in the stack is faster than
heap. In static system, at compile time, the relative memory address is fixed for all variables, so it will be
faster. Whereas in DMA system, at run time, the memory is allocated by searching a suitable location and
also maintains a separate table for registering address which location is allocated and which is not, this
makes the program slow.

Program accepts N strings (country names) and prints them


This program accepts strings one by one until user entered termination string as “end”.
Later displays all such inputted strings on the screen.
#include<stdio.h>
#include<string.h>
#include<alloc.h>
void main()
{ char **p=NULL;
int count=0,i;
char a[50];
while(1)
{ printf("enter country name :");
fflush(stdin);
gets(a);
if(strcmpi(a, "end")==0) break;
p=(char**) realloc(p,sizeof(char*)*(count+1));
p[count]=(char*)malloc(sizeof(char) * (strlen(a)+1));
strcpy(p[count], a);
count++;
}
if(count==0)
{ printf("no country name entered");
return;
}
printf(“ U r entered \n”);
for(i=0; i<count; i++)
puts(p[i]);
}
If input strings are
p
India
China
USA… P[0] “India”
P[1]
end
P[2] “China”
For the above program, the memory P[3]
creates for the pointer as  P[4] “USA”

“Pakistan”

“Srilanka”
C-Family 241 Command Line Arguments

Command Line Arguments


Just like other functions, main() also receive the arguments and returns a value. Here few questions may
rise! From where does the main() function is called and passed the arguments? The main() function is called
from Operating System's command line by just typing the program name as shown below.

C:\tc\bin\>sum.exe // here “.exe” is optional


(Suppose if our C program’s file name is “sum.c” then its compiled version will be “sum.exe”)

When a program is run, the operating system loads .exe file into memory and invokes the startup function
main(). Here, we can assume the OS is the caller of main() function. Therefore, the arguments can be passed
to the main() by specifying a list of values at the command line as shown below.

C:\tc\bin\>sum 10 20 30
Unlike other functions, the arguments to main() passes in a different manner. They pass as array of string
constants. That means, even if you give an integer values, they pass as strings. In the above case also, the
arguments passed as "sum”, "10", "20", "30". (passes as array of addresses shown in below picture).

But main() receives them as two arguments, the first argument is integer, which specifies the count of
arguments which we passed including file-name. The second argument is, an array of addresses containing
strings. Thus main() function should be defined as

void main(int count , char *a []) a[0] a[1] a[2] a[3]


2020 2030 2050 2070
{ ---
--- “sum.exe” “ 10 ” “ 20 ” “ 30 ”
2020 2030 2050 2070
}
Here, 'count' holds the count of arguments whereas 'a[]' holds address of all string constants that are passed
to the program. The size of array is, number of values we passed to it. (This as above figure)

Example1 : this program adds all such integers which we passed through command line as above shown
Input: c:\tc\bin\>sum 10 20 30 40
Output: sum of numbers = 100
void main( int count, char *a[ ] )
{ int sum=0,i=0;
for(i=1; i<count; i++)
sum = sum+atoi(a[i]); //atoi() function converts numeric string to integer value
printf("\n sum of numbers = %d", sum);
}
Example2: The following program takes string as input from command line and displays length.
It also shows an error, if user enters less number of strings.
Input: C:\tc\bin\>sample C-Family
Output: length of C-Family = 8

void main( int count, char *a[] )


{ if( count==1)
{ printf(“insufficient arguments”);
return;
}
prinf(“the length of %s = %d”, a*1+, strlen(a*1+) );
}
C-Family 242 structures, unions , enums

User Defined Data Types


The data types can be classified into two types ①predefined types ②user defined types.
Predefined types are also called built-in or primitive types, whereas user types are custom types.

Primitive Data types: these are also called built-in or basic types, for example int, char, float, int*, etc;
these primitive types and their functionalities are already designed and developed in compiler level during
development of C software. Therefore, we can directly use them in programs.

User defined Data types: ‘C’ gives a freedom to the user (programmer) to define his own data types
according to requirement in the program. Therefore, these are called user-defined types. We have 3 types,
①structure ②union ③enumerator.

Generally, it is difficult to handle large collection of data using basic types. Using arrays, we can handle only
collection of homogeneous items of known size. However, to handle collection of heterogeneous items then
user-types are required. For example, consider an employee data containing id, name, address, salary, etc.
Handling such heterogeneous items individually is difficult and leads to complex task. If we group all these
items into single (as one record) then they can be handled easily. For this, fortunately, C is providing a
structures concept.
1) Structures
Structure is a collection-type user-defined data-type, used to pack several different items together as single
item. So we often state that, array is collection of homogenous items, whereas structure is a collection of
heterogeneous data items. Sometimes, the items in a structure can be same type.
The items in a structure are called data-members and we can have as many members as we want.
Syntax to declare a structure
struct tag-name
{ data_memberl;
data_member2;

data_memberN;
};
For example:
struct student
{ int idno;
char name[30];
int marks1, marks2,marks3;
};
This structure declaration defines a new data-type called “struct student”, using this, we can create
variables and its data can be managed.

This structure declaration works as a blue-print or template of our type and it does not occupy any space in
executable file. Just it gives layout idea to the compiler i.e, about tag-name, data type of members and space
required for each member. Now using this structure template, we can create variables and its data can be
managed. Here tag-name is the name given to the structure and it follow rules of variable naming.
The structure can be declared in local or global scope, depends upon requirement of program.
C-Family 243 structures, unions , enums

Syntax to declare structure variables: struct tagName variable1, variable2,…, variableN;

For example: struct student s1 , s2 ;


Data type Variables

The memory allocation for the s1 and s2 will be as


S1 S2
Member’s name  idno name marks1 marks2 marks3 idno name marks1 marks2 marks3
Bytes occupied  2 30 2 2 2 2 30 2 2 2

Note: the definition of a structure works as building-plan, whereas, its variables works as building.

Initialization of structure variables


Initialization of structure is same as initialization of array, here all values must be put in pair of braces{}
syntax: struct variable = {list of values};
example: struct student a={100,"Lokesh",45,78,47}, b=,101, ”Srihari”,44, 55,67-;

a b
100 Lokesh 45 78 47 101 Srihari 44 55 67

Accessing members in a structure


we have two operators
1. Selection operator, dot (.) // accessing through structure variable
2. Indirect selection operator, arrow () // accessing through structure pointer
a) Using selection operator
syntax: struct_variable . member_name
for example: the expression a.idno accesses the ‘idno’ in ‘a’
the expression a.name accesses the ‘name’ in ‘a’
the expression a.marks1 accesses the ‘marks1’ in ‘a’
printf(“%d %s %d %d %d”, a.idno, a.name, a.marks1, a.marks2, a.mark3 );

A
100 Lokesh 45 78 47
a.idno a.name a.mark1 a.marks2 a.marks3

b) Using indirect selection operator


if user-defined type is ‘struct student’, then its pointer type is ‘struct student*’
for example: struct student *p; // ‘p’ is a pointer variable to structure
p=&a; // making pointer ‘p’ to ‘a’
P a
100 Lokesh 45 78 47
pid pname pmarks1 pmarks2 pmarks3

now the expression ‘*p’ accesses the total memory of ’a’ [ so *p==a ]
the expression (*p).idno accesses the ‘idno’ in ‘a’
(*p).idno is equal to a.idno
(*p).idno is equal to p->idno // this ‘p->idno’ is a short form, this is called: p arrow idno )
(*p).name or p->name is equal to ‘a.name’
C-Family 244 structures, unions , enums

The arrow operator (->) introduced in second version of C language


this is a short-cut operator, used to access the members in a structure through pointer.
Remember: (*p).name is equal to p->name [ so *p can be imagined as p-> ]

Note: the expression (*p).name cannot be written as *p.name, because, the dot operator (.) has high
priority than pointer operator (*), so first, the compiler try to evaluate p.name and it shows an error.
Because ‘p’ does not have the data members of a structure, it contains address, whereas, the expression
(*p) is pointing to the memory of ‘a’ and it contained member’s data.

Filling and displaying student details through structure variables


Let student contained values like idno, name, and three subject marks as said in above example and printing
all details. (Here each member assigned with a value instead of initializing the whole structure )
struct student // this is global declaration of a structure
{ int idno;
char name[30];
int m1, m2, m3;
};
void main()
{ struct student s;
s.idno=100; // filling idno number with 100
s.name=”Srihari”
strcpy(s.name, “Srihari”); // filling name with “Srihari”
s.m1=66; s.m2=77; s.m3=88; // filling marks with 66,77,88
printf("\n details of student is:\n"); // printing details of student
printf("%d %s %d %d %d", s1.id, s1.name, s1.m1, s1.m2, s1.m3);
}
The following program accepts student details from keyboard and printing on the screen.
void main()
{ struct student s; //declaration of student variable
printf("\nEnter student details:"); // scanning details
printff \n enter id no :");
scanf("%d",&s.id);
printf("enter name:");
fflush(stdin);
gets(s.name);
printf(“enter marks 1 ,2,3 :");
scanf("%d%d%d",&s.m1, &s.m2,&s.m3);
printf("\nDetails of student:\n"); // printing details of student
printf("%d %s %d %d %d", s1.id, s1.name, s1.m1, s1.m2, s1.m3);
}
In this program, every member in a structure scanned separately using %d ,%s , %d ,%d ,%d.
Using scanf() & printf() functions, each value scanned separately as “int, char[], int, int, int” because, these
functions can read/write only built-in types data. The total structure cannot be read as a single value unless
a special function is written for it.
C-Family 245 structures, unions , enums

Let us see advantages of structures


If two student’s data need to be scanned without structures then see how the program is made complex and
unreadable.
void main()
{ // declaration of two student’s variables.
int idno1, idno2;
The declarations of 2 student’s data
char name1[30], name2[30]; seems to be difficult to understand
int m11, m12, m13, m21, m22, m23;
----
}
If we use structures then the code will be
void main()
{ // declaration of two student’s variables.
This seems to be so easier than the above.
struct student s1,s2; Thus structures provide a great convenience.
----
}

Filling and displaying student details through functions


Following two functions fill() & show() manipulates the student data.
The fill() function, fills the student details with the data: “100, Lokesh, 45, 78” and show() fn display it.
The fill() function followed call-by-reference, whereas, show() function followed call-by-value.
struct student
{ int id;
char name[30];
int m1, m2;
};
void main() S
{ struct student s;
fill(&s);
show(s); 100 Lokesh 45 78
} pid pname pm1 pm2
void fill(struct student *p)
{ p->idno=100;
strcpy( p->name, ”Lokesh“);
p->m1=45;
p->m2=78; p
}
void display( struct student k)
{
printf(“ %d %s %d %d ”, k.id, k.name, k.m1, k.m2);
} K
100 Lokesh 45 78
The function fill() followed call-by-reference method, p.id p.name p.m1 p.m2
here the pointer ‘p’ is pointing to structure ‘s’ as shown in
figure. The expressions p->id, p->name, p->m1 accesses the memory of structure ‘s’.
That is, the fill() function indirectly inserts the values into locations of ‘s’;
Whereas, the function show() followed call-by-value method. When it calls, all the members of ‘s’ are copied
into ‘k’, later displayed one by one.
C-Family 246 structures, unions , enums

Accepting two dates and find whether they are equal or not?
* trying with & without using functions
ip: 12 9 2010 ip: 12 9 2010
12 9 2010 13 9 2011
op: equal op: not equal

struct Date
{ int d, m, y;
};
void main()
{ struct Date a , b;
int k;
read( &a ); // scan date1 (day, month, year) using read() function.
read( &b ); // scan date2 (day, month, year)
k=compare( a , b ); // compares two dates and returns 1/0
if( k==1) printf(“equal”);
else printf(“not equal”);
}
void read( struct Date *p )
{ printf(“enter day month year:”);
scanf(“%d%d%d”, &p->d, &p->m, &p->y);
}
int compare( struct Date p , struct Date q )
{ if( p.d==q.d && p.m==q.m && p.y==q.y)
return 1;
else return 0;
}
the read() fn followed call-by-reference, because, the scanned values at read() fn need to be returned to
main() fn, therefore we have to store indirectly through pointers, whereas compare() fn follows call-by-
value, it is just comparing given two dates.

Accepting two times from keyboard and printing addition of two times
Let the two times are employee working time in two shifts, later add & print total time worked in two shifts.
ip: 12 50 58 (shift-1 worked duration : Hours=12, Min=50, Seconds=58 )
2 53 55 (shift-2 worked duration : H= 2, M=53, S=55 )
op: 15hr 44min 53sec (total duration worked in two shifts)

struct Time
{ int h, m, s ;
};
void main()
{ struct Time a, b, c;
a=read(); // this read() fn returns the scanned time ( it is opposite to above read() fn)
b=read()
c=add(a,b); // add two times like c=a+b
write(c); // print output time on the screen
}
C-Family 247 structures, unions , enums

struct Time read()


{ struct Time k;
printf(“enter time :”);
scanf(“%d%d%d”, &k.h, &k.m, &k.s);
return k; // returning scanned time
}
struct Time add(struct Time a, struct Time b)
{ long int k;
struct Time t;
k=(a.h+b.h)*3600 + (a.m+b.m)*60 + (a.s+b.s);
t.h=k/3600;
t.m=(k%3600)/60;
t.s=(k%3600)%60;
return t;
}
void write( struct Time k)
{ printf(“output time is : %d - %d - %d”, k.h, k.m, k.y);
}
Above program followed completely call-by-value method, but we can write same program using call-by-ref.
void main()
{ struct Time a, b, c;
read(&a);
read(&b);
add(&c, &a, &b);
write(&c);
}
void read( struct Time *p)
{ printf(“enter time :”);
scanf(“%d%d%d”, &p->h, &p->m, &p->s);
}
void add(struct Time *t, struct Time *p, struct Time *q)
{ long int k;
k=(p->h+q->h)*3600 + (p->m+q->m)*60 + (p->s+q->s);
t->h=k/3600;
t->m=(k%3600)/60;
t->s=(k%3600)%60;
}
void write( struct Time *p)
{
printf(“output time is : %d - %d - %d”, p->h, p->m, p->y);
}
Conclusion: here read() fn should be written in call-by-ref, but add() and write() can be either two.
if struct size<10bytes, then call-by-value is the choice where the members can be easily accessed.
if struct size>10bytes, then call-by-ref is the choice, because it is unnecessary creating 2nd copy at called
function for a big size data. Here in this case, for the two functions add() & write(), the call-by-value is the
best, because the size of structure is less than 10bytes..
C-Family 248 structures, unions , enums

Accepting two matrices data & printing addition of them


struct matrix
{ int a[10][10]; // array to hold matrix elements
int r,c; // r, c are order of matrix
};
void main()
{ struct matrix x, y, z;
int k;
accept(&x); // call-by-reference
accept(&y);
k=add(&z, x, y); // partly call-by-value and call-by-reference
if(k==0) printf("\n Matrix cannot be added ");
else display(z); // call by value
}
void accept( strut matrix *p)
{ int i,j;
printf("Enter no.of rows and columns :");
scanf("%d%d", &p->r, &p->c );
for(i=0; i < p->r; i++)
{ for( j=0; j< p->c ; j++)
{ printf("\n enter [%d][%d]:", i, j);
scanf("%d", &p->a[i][j]);
}
}
}
void display( struct matrix z)
{ int i,j;
for(i=0; i <z.r; i++)
{ for(j=0;j<z.c ; j++)
printf("%d ", z.a[i][j]);
printf("\n");
}
}
int add(struct matrix *p, struct matrix x, struct matrix y)
{ int i,j;
if(x.r != y.r || x.c != y.c)
return 0; // zero indicates addition failed
for(i=0; i <x.r; i++)
for( j=0;j<x.c;j++)
p-> a[i][j] = x.a[i][j] + y.a[i][j];
p->m=x.r;
p->n=x.c;
return 1; // return ‘1’ indicates addition succeeded
}
C-Family 249 structures, unions , enums

Array of structures
Array of structures is useful when several instances of details are to be handled in the program.
We can create array of structures just like any normal data types.
Syntax: struct tagName arrayName[size];

For example: struct Person


{ char name[20]; // name of person
int age // age of person
};
struct Person s[3]; // creates 3 array of structure variables.

The array of structures is as follows

s[0] s[1] s[2]


name age name age name age

Here every element “s*i+” is a structure item and accessing of each structure is just as accessing each item in
the array. Each individual structure member can be accessed as
Syntax: arrayName[index].memberName
The expression s[0].name  accesses the name in s[0]
The expression s[0].age  accesses the age in s[0]

The expression s[1].name  accesses the name in s[1]


The expression s[1].age  accesses the age in s[1]
Following program explains how to scan & print array of structure values.
void main()
{ struct Person s[5];
accept(s); // display( &s[0] ) passing base address of array
display(s);
}
void accept(struct person p[] or struct person *p)
{ int i;
for( i=0; i<3; i++)
{ printf(“enter name & age of a person :”);
fflsush(stdin);
gets(&p[i].name); // gets( (p+i)->name );
scanf(“%d”, &p*i+.age); // scanf(“%d”, &(p+i)->age );
}
(or)
for( i=0; i<3; i++)
{ printf(“enter name & age of a person :”);
fflsush(stdin);
gets(&p->name);
scanf(“%d”, &p->age);
p++; // increment by 22 (size of structure)
}
}
void display( struct person p[] or struct person *p)
{ int i;
for( i=0; i<3; i++)
{ printf(“\n %s %d “, p*i+.name, p*i+.age); //or printf(“\n %s %d “, (p+i)->name, (p+i)->age);
}
C-Family 250 structures, unions , enums

(or)
for( i=0; i<3; i++)
{ printf(“\n %s %d “, p->name, p->age);
p++; // increments by 22, to points to next structure
}
}
above two loops do same job in accept() & display() function, but second loop little faster than first loop.

Accepting N student details and printing with result.


struct student
{ int id;
char name[30];
int m1, m2, total, avg;
};
int i;
void main()
{ struct student s[3];
accept(s); // accept( &s[0] );
find(s); // find( &s[0] );
print(s); // print( &s[0] );
}
void accept( struct student s[] )
{ for(i=0; i<3; i++)
{ printf(“enter student idno name mark1 marks2:”);
scanf(“%d%s%d%d%d”, &s*i+.idno, &s[i].name, &s[i].m1, &s[i].m2);
}
}
void find( struct student s[] )
{ for(i=0; i<3; i++)
{ s[i].total=s[i].m1+s[i].m2;
s[i].avg=s[i].total/2;
}
}
void print(struct student s[])
{ for(i=0; i<3; i++)
printf(“\n %d %s %d %d %d %d”, s*i+.idno, s*i+.name, s*i+.m1, s*i+.m2, \
s[i].total, s[i].avg);
}
Adding two polynomials using array of structures
5x7+14x5+3x2+10x1+18
15x4+10x3+13x2+7
The two expressions are stored in array of structures as given below

p[0] p[1] p[2] p[3] P[4]


5 7 14 5 3 2 10 1 18 0
coeff exp coeff exp coeff exp coeff exp coeff exp

p[0] p[1] p[2] p[3]


15 4 10 3 13 2 7 0
Coeff exp coeff exp coeff exp coeff exp
C-Family 251 structures, unions , enums

#define maxSize 20
struct POLY
{ int exp;
int coeff;
};
void readPoly(struct POLY p[])
{ int prev=maxSize+1, i=0;
while(1)
{ printf("\nEnter coefficient (use 0 to exit) :");
scanf("%d",&p[i].coeff);
if(p[i].coeff==0) break;
printf("\nEnter exponent: ");
scanf("%d",&p[i].exp);
// the input exponents must be in sorted order like shown in above equation, otherwise shows input error
if( p[i].exp > prev)
{ printf("input error");
continue; // go back and read again
}
prev=p[i].exp;
i++;
}
}
void printPoly(struct POLY p[])
{ int i;
for(i=0; p[i].coeff!=0; i++)
printf("%d^%d + ", p[i].coeff, p[i].exp);
printf("\n ");
}
void addPoly( struct POLY p3[], struct POLY p1[], struct POLY p2[])
{ int i=0, j=0, k=0;
while (p1[i].coeff!=0 && p2[j].coeff !=0 )
{ if( p1[i].exp > p2[j].exp)
p3[k++] = p1[i++];
else if( p1[i].exp < p2[j].exp)
p3[k++] = p2[j++];
else
{ p3[k].exp = p1[i].exp;
p3[k++].coeff = p1[i++].coeff + p2[j++].coeff;
}
}
while(p1[i].coeff!=0 ) p3[k++] = p1[i++];
while(p2[j].coeff!=0) p3[k++] = p2[j++];
p3[k].coeff = 0;
}
void main()
{ struct POLY p1[maxSize], p2[maxSize], p3[maxSize];
printf("enter polynomial 1:");
readPoly(p1); // accepting first polynomial
printf("enter polynomial 2:");
readPoly(p2); // accepting second polynomial
addPoly(p3,p1,p2);
printf("\n The resultant poly after addition is\n");
printPoly(p3);
}
C-Family 252 structures, unions , enums

More about different declarations of structures


We can declare structure variables while defining the structure itself. However, if we define a structure in
global scope then all variables also becomes global.
struct Account
{ int accNo;
char name[30];
float balance;
} a1, a2, a3;  Here a1, a2, a3 are variable of type “struct Account”;

above example with Initialization of variables.


struct Account
{ int accNo;
char name[30];
float balance;
} a1={ 101, "James Bond", 2200.45}, a2=,102, "Goshling”, 3400.45};
Structure name can be ignored while declaration of structure
struct // tag name omitted
{ int accNo;
char name[30];
float balance;
} a1, a2, a3;
In this method, we cannot declare variables of same structure in the rest of the program, because “tag
name” is not available to refer the structure. Actually, this type of declaration is used for sub categories of
data. This is also known as nested structures.
struct Account
{ int accNo;
char name[30];
float balance;
struct // called nested structure
{ int day,month,year;
}openDate;
};

Nested structures
Structure in structure is said to be nested structure, we can nested as many times as we want, complexity
will not be increased even though nested many times. for example,
struct Student
{ int idno;
struct Date
{ int d,m,y;
} joinDate;
};
void main()
{ struct Student p;
p.idno=10; P
p.joinDate.d=10; idno joinDate
p.joinDate.m=12; d m y
p.joinDate.y=2020;
-----
}
C-Family 253 structures, unions , enums

typedef
“typdef” is a keyword,used to define new convenient names for existing types.
It works as alias name for existing types, but we don’t lose old name.
Syntax: typedef existing-name new-name;
For example
typedef float RS;
typedef float DOLLOR;
typedef int* INTP;
Let us see, how variables can be declared
RS amount1;
DOLLOR amount2;
Here amount1, and amount2 are nothing but float type variables and this is equal to
float amount1, amount2;

Similarly, structure types can be declared in two ways.


struct Date
{ int d,m,y
};
typdef struct Date DATE; //now DATE is a convenient name of struct Date;

The above structure can also be declared in simple way as


typedef
{ int d,m,y;
} DATE;

Advantages of a structure
It is rather easy to handle all items in structure as a single item than individual, which gives the following
advantages.
1. Assignment between structures is possible
the compiler supports for copying one structure to another structure just like any integer value.
Here all members in the structure are copied bit by bit.
struct empleoyee e1=,100, “Srihari”, 50000.00};
structu employee e2;
e2=e1; // all members of e1 is copied to e2

2. Passing & returning entire structure between functions is possible.


For example: display(e1); // passing all members of structure in single call
swap (&e1, &e2); // swapping members
3. Alteration of structure is simple
Adding new or deleting existing members is simple.
4. Avoiding misuse of data
Accessing members through structure-variable avoids misusing of data.
5. Reusability
we can reuse one structure while defining another new structure.
6. We can create array of structures
C-Family 254 structures, unions , enums

Unions
Union defines the generic data-type instead of specific type, where we can store any type of value such as
int/float/char/etc. Union is also similar to structure but all the members in the union share the common
memory area. Here space is created for only one member and remaining members share the same space,
therefore we can store & access only one member at a time. The size of union is equivalent to biggest data
member in it. The main purpose of union is to save the memory space, and also gives flexibility in coding.
item
union myType
{ char c; Byte1 Byte2 Byte3 Byte4
int i;
long int l; c
float f; i
f/l
};
union myType item;
The above union variable ‘item’ occupies 4bytes of memory. Among 4 members, the first member ‘c’ uses
only first byte. The second member ‘i’ uses first two-bytes. Similarly remaining f & l uses total 4bytes.
Demo program for how data is handled in union variables
union myType
{ int i, j, k;
};
void main()
{ union myType var;
var.i=10;
printf(“\n i=%d j=%d k=%d", var.i, var.j, var.k);
}
Output: i=10 j=10 k=10
In the above program, when ‘var.i’ is assigned a value 10, the other union members ‘var.j’ and ‘var.k’ also
gain the same value as they are sharing the common memory space.
void main()
{ union myType var;
var.i=10;
var.j=20;
var.k=30;
printf(“\n i=%d j=%d k=%d", var.i, var.j, var.k);
}
op: 30 30 30. Here var.j=20 overwrites the var.i=10, var.k=30 overwrites var.j=20;
Let us see one more example
union myType
{ long l;
float f;
};
void main()
{ union myType var;
var.f=200;
printf("\n l=%ld f=%f\n", var.l, var.f);
var.l=100; // overwrites var.f=200 value
printf("\n l=%ld f=%f\n", var.l, var.f);
}
Output: l=garbage f=200.000000
l=100 f=garbage
C-Family 255 structures, unions , enums

Let us see practical example, the print() function can print all types of data.
typedef struct
{ union
{ char cc;
int ii;
float ff;
}value;
char valueType;
}MyType;
void main()
{ MyType var;
var.value.cc='A';
var.valueType='c';
print(var);

var.value.ii=100;
var.valueType='i';
print(var);

var.value.ff=300.45;
var.valueType='f';
print(var);
}

void print(MyType var)


{ switch(var.valueType)
{ case 'c':
case 'C': printf("\n%c", var.value.cc); break;
case 'i':
case 'I': printf("\n%d", var.value.ii); break;
case 'f':
case 'F': printf("\n%.2f", var.value.ff); break;
}
}
C-Family 256 structures, unions , enums

Enumeration
Enumerator data type is used to symbolize a list of constants with names, so that, it makes the program easy
to read and modify. Enumerator maps the values to names there by we can handle the values with names.
enum tagName { name1, name2, name3, ... nameN } ;
For example
enum Colors{ red, green, blue }; // here red=0, green=1, blue=2
enum Boolean{ false, true }; // false=0, true=1
In this way, we can specify enumerated set with valid unique names.
At compile time, all these names are automatically assigned with integer values 0, 1, 2, 3 etc.

Explicit initialization of enumerators


At the time of declaration of enumeration, we can give explicit values to the names and these values can be
any integers. Even two names can have same value (duplicate values).
For example
enum cityNames { Vijayawada=10, Guntur=20, Vizag=30 };
enum cityNames { Vijayawada=20, Guntur=10, Vizag=30 };
enum cityNames { Chennai=1, Madras=1, Mumbai=2, Bombay=2, Vijayawda=3, Bezawada=3 };
enum month { jan=1, feb, mar, apr, may, june, july, aug, sept, oct, dec };
Here name "jan" assigned with 1 by the programmer, and remaining names are automatically assigned with
next succeeding numbers by the compiler. That is feb=2, mar=3, ... etc.
Let us see one program: this program displays no.of days in a given month.
enum month { jan=1, feb=2, mar, apr, may, june, july, aug, sept, oct, dec }
void main()
{ int mon;
printf(“enter month number:");
scanf(%d",&mon);
switch(mon)
{ case jan: printf(“ January month has 31 days"); break;
case feb: printf(" February month has 28 days"); break;
case mar: printf(" March month has 31 days"); break;
---
}
}
Here all month names are replaced by its constant value at compile time, so the enumerator set symbols are
evaluated of above program is
void main()
{ int mon;
printf(“enter month number:");
scanf(“%d",&mon);
switch(mon)
{ case 0: printf(“ January month has 31 days"); break;
case 1: printf(" February month has 28 days"); break;
case 2: printf(" March month has 31 days"); break;
---
}
}
C-Family 257 structures, unions , enums

Ambiguity error
There is one problem with enumeration, if any variable exist with same name in enumerator set in same
scope then we get error at compile time.
For example,
enum color { red, green, blue, white, yellow};
int red=0; /* ambiguity error with red, so either one must be removed */
void main()
{ int white=100; // preference is given to local white variable, instead of white in enumeration
printf("%d %d %d %d", green, blue, white, yellow};
}
output: 0 1 100 4

Enumeration variables
Using enumerator tag name, we can specify variables of its type. This makes the convenient and increases
the readability of the program. The enumerator variables are nothing but int-types. For example
enum tagname variable-1 ,variable-2, variable-3, ... ;
enum Color { Red=15, Green=26, Blue=13, White=5, Yellow=4, Grey=17 };
void main()
{ enum Color wallColor, floorColor;
wallColor=White;
floorColor=Grey;


}
C-Family 258 Data Files

File handling in C
In real life applications, some kind of input/output data need to be accessed frequently by many persons in
many times whenever it is required. Therefore, such data need to be placed permanently in the computer,
so that it can be accessed many times later.

For this purpose, secondary storage devices are used to store the data permanently in the form of files.
These files often called data files. Thus, data file can be defined as collection of data, stored permanently in
secondary storage device. Each file is identified by a valid name called file-name. The interaction with files is
treated as interaction with io devices in the computers. Therefore, all secondary memory devices treated as
io devices.

Let us consider a menu driven program to automate student marks in a college. Generally, we provide all
options that are required by the college management. Let the marks data scanned from keyboard and
stored permanently in a data file called "marks.dat", later, such marks are processed and stored the results
in a separate file called "result.dat" or displayed on the screen. This is depending upon the requirement of
problem. The interaction of application with io devices is as follows
Here in first figure, the application is interacting with keyboard as input device and file as output device.
In second figure, the both input and output devices are files.

Keyboard Program Input file: “marks.dat”


void main() Idno name marks1 marks2 marks3
Here scanning the input records { 100 srihari 98 77 77
one by one through keyboard ---- 101 srinivas 65 56 47
using scanf() statement. ---- 102 Laxmi 55 56 67
(scanned by the program) } 103 vanisri 56 67 75

Input file: “marks.dat” Program Output file: “result.dat”


Idno total avg pass/fail rank
Idno name m1 m2 m3
void main()
100 srihari 98 77 77 { 100 252 84 first 1
101 srinivas 65 56 47 ---- 101 168 56 second 4
102 Laxmi 55 56 67 ---- ---
103 vanisri 56 67 75 } ---

Output file: “result.dat” Program Monitor


Idno total avg pass/fail rank void main() Displaying record(s) on the screen.
100 252 84 first 1 {
101 168 56 second 4 ---- Printer
--- ---- Printing record(s) on the printer.
--- }

In computer science, the files can be classified into 2 types


1. Data files: for example, pdf files, jpg image files, mp3 sound files, mp4 video files, and program’s source
code files(like c, cpp, java files), etc.
2. Program files: for example, .exe, .com, .dll, etc; Contains machine code instructions (executable code).
now we are dealing with data files, the data files are two types text & binary.

1. Text Files (Text format files  here data is stored in the form of ascii values (string format))
2. Binary Files (Binary format files  data is stored as it is in program variables (raw format))
C-Family 259 Data Files

Text Files
In text files, everything is stored in the form of ascii values, even numeric data is converted into string
format with its ascii values of each digit and stored in file. For example, 'k' contained a value 2891, this
number is stored in text file as

‘2’ ‘8’ ‘9’ ‘1’ 50 56 57 49 00110010 00111000 00111001 00110001

Here 50, 56, 57,49 are ascii values of 2, 8, 9,1 respectively. Internally each digit ascii again stored in binary
form as above shown(as computer understands only binary values), in this way text data is stored and
retrieved from file. These files are only suitable for presentation of data, i.e, for displaying or printing
purposes only. For example, document files, help files, message files, public related files, source program
files, small data files, configuration files, etc are handled in text format. In general, these files are handled in
two ways, by writing a specific program to manage them, or by using ready-made text editors. Using text
editor, we can create, modify the text data. We have several text editors like notepad, word pad, ms-word,
etc.
At end of text files, the value 26 is inserted to indicate end-of-file mark and also the new-line character is
stored as "\r\n"(unix format). The library functions does this job while writing ‘\n’ to file, whereas while
reading back, it is considered as only one character (\n). (We don’t worry about this ‘\n’)

Binary files
In this kind of file organization, all the contents are stored as it is in program variables. Here no conversion is
made while storing and reading back unlike text files. Generally, binary files are extensively used for
maintaining similar type of data like employee records or bank accounts, insurance accounts, etc.
In binary i/o, as it is of storing & reading back takes place between the RAM & secondary memory, therefore
binary files is faster than text files. At end of text files, the value 26 is inserted to as end-of-file-mark,
whereas in binary files no such value is inserted, where end-of-file mark is known by the file-size.

In case of binary files, we cannot manipulate the data using text editors. For example, take student structure
idno|name|marksint|char[30]|int. if this data is dumped into file as it is, then it has to be read back as it
is.(2byte at a time for idno, 30byte at a time for name,..) So, text editors are unaware of this user-defined
structure, hence we cannot handle binary files using text-editors. (text editors read/write data only in the
form of ascii)
There should be separate software needed to handle binary tiles. For example ‘pdf’ file is a binary format file
and cannot be opened in text editor, special software like Adobe-Reader is used. Similarly, jpg files, image
files, sound files, movie files are managed using special software.
in C, files can be handled in two ways, 1. High level file handling, 2. Low level file handling.
C-Family 260 Data Files

High-level file IO
For high-level file handling, C provides more facilities like file streaming (buffering) with related library
functions. The library functions like reading/writing data from file, converting numeric into text format, and
text to numeric and redirection of output into other destinations like screen, printer, etc is also possible.
File stream: As we know, stream is a data structure, works as mediator between device and our
application. It is like a pipeline structure between motorwater tanktap at your home. Any stream has
built-in i/o functions with array of bytes of space in the RAM called buffer. (stream=buffer memory + io
functions).
Write() Array of bytes Read()

In other words, it is a temporary storage service to store & retrieve the data for a while in the program.
Loosely saying, it acts as a go-down between manufacturer and retail-shopper for stock maintenance, here
we keep items temporarily for a while. In computers, the well-known example is Youtube streaming, etc.

In computer, every device has own streaming like keyboard-stream, mouse-stream, monitor-stream, printer-
stream, etc. When you type something on the keyboard, the input characters are inserted in keyboard
stream-buffer, later our scanf()/gets() read from the stream-buffer. Thus stream works as mediator between
device & app. This file stream is available in C languages with the name FILE.
The total hard disk space logically divided into several blocks and each block size is around 1024bytes.
This is custom size, we can change this size to 2048/4092/…) The hard disk header-pin can read/write at a
time one block of data (not in bytes). As we know, the files are stored permanently in hard disk in the form
of blocks. Let each block size is 1024bytes on your disk and your file size is 3000bytes, then your file takes
3blocks to store on disk. Storing and reading files from hard disk is managed by the operating system.
Thus, before doing any operation on your file, first its contents (not total file) are placed in stream’buffer
and then operations takes place. That is, when we open a file, the first block of file contents is loaded into
the stream’buffer, and then io operations performed on it. Whenever another block is required, then
current block is replaced with next block. This process is called streaming and is done with the help of OS.
For this, the C providing a FILE structure variable to store the meta-data of file. The meta-data such as file-
name, file-type, open-mode, pointer to file-data(block), pointer to current read/write record, error-code,
block-number, and other O.S related details.
This predefined FILE structure provided in 'stdio.h' file as
typedef struct
{ int level; // fill empty level of buffer
unsigned flags; // file status flags
char fd; // file descriptor
unsigned char hold; // ungetc char if no buffer
int bsize; // buffer size
unsigned char *buffer; // data transfer buffer
unsigned char *curp; // current active pointer
unsigned istemp; // temporary file indicator
short token; // used for validity checking
} FILE;
This FILE structure details are related to operating system, this FILE details are used by the library functions
implicitly while taking i/o operations on file data, so we don’t need not learn & apply in the program. The
following figure explains how FILE structure filled with file data(meta-data) when it opened/loaded in RAM.
C-Family 261 Data Files

Pointer
to file
File stream ( file structure detailsmeta data)
File Pointer to Pointer to current Open mode File type Block Error
name file data read/write record (read/write) (text/binary) reference code

File data ( buffer )


Record1 Record2 Record3 Record4 Record 5 Record 6 …

Operations on files are mainly three


1. Opening a file
2. Applying read/write/modify operations on file data
3. Closing a file
Opening a file: The function fopen() is used to open a file, this function first creates a memory for buffer
and a FILE structure; later loads file meta-data & contents into buffer. Finally returns the structure address
to pointer (as shown above). If unable to open a file then it returns NULL.
Syntax: FILE* fopen(char *fileName, char *openMode);
The first argument is the name of file which we want to open, and second argument is opening mode.
For example: FILE *fp;
fp=fopen("marks.dat","rt"); // r: read-mode, t: text-file

We have different open modes in C, for example, r  read-mode, w write-mode, etc.


the following table gives details of it.
r  read mode: Opens an existing file for reading. (We cannot write/modify existing data).
If file not found while opening, then fopen() returns NULL.
w  write mode: Creates a new file for writing, if file already exists with same name, its content will be over
written. (old data erased)
a  append mode: Opens an existing file for adding new data at the end. If file does not exist with that name, then
it will create a new file and adds the data to it. ( add-at-end means append)
r+  all operations: Opens an existing file for updating (allows all operations like reading/writing/modifying).
If file not found then it returns NULL.
w+  write + modify: Creates a new file for writing. If file already exist with same name then its contents are erased.
if once new data is written then “w” mode does not allows to go back and modify it, but “w+” allows it.
a+  append + modify: Appends new data and also allows to modify new data( not old data)
we can append new contents at the end of file, as well as we can read-back/modify the just newly written data.
(Not old written contents). If file not exist then opens new file.

b/t  (Binary file/Text file):To specify that a given file be a text or binary file.

Closing a file: The function 'fclose()' closes an already opened file. After completion of read/write/modify
jobs on a file, it must be closed. This operation involves in updating file contents on disk (saving back to disk)
and also releases buffer & FILE structure’s space in the RAM. The syntax is
int fclose(FILE *filePointer); // It returns zero, if successfully closed a file, otherwise returns -1.

The I/O functions on files


fgetc(), fputc(), fgets(), fputs(), fscanf(), fprintf(): These functions are specialized to handle text files.
Using these functions, we can also perform formatted input/output on text files.
Formatted means, writing data using io flags such as %d %5d %-5d %.2f %s %30s etc;
C-Family 262 Data Files

fread(), fwrite(): These functions are specialized to handle binary files. Of course, we can also use for text
files, but formatted input/output does not support.
fputc(): It is used to write single character to a file. It takes two arguments, a character which is to be
written, and a pointer of FILE structure. Syntax: int fputc(character, FILE pointer);
fgetc(): It is used to read single character from a file and returns ASCII value of it.
syantax: ch=fgetc( file pointer );
fputs(): Writes a string to file
fgets(): Reads a string from file
fprintf(): It works like a printf(), but writes data to file
fscanf(): It also works like a scanf(), but reads data from file
fread(): This is used for binary files, but also works for text files
fwrite(): It is opposite to fread()
ftell(): returns current read/write position of the file pointer.
fseek(filePointer, 0, SEEK_END): moves the file pointer to end of file.
fseek(filePointer, -100, SEEK_END): moves the file pointer 100 bytes back from end position.
fseek(fp, 0, SEEK_SET): moves file pointer to beginning of file.
fseek(fp, 100, SEEK_SET): moves file pointer to 100bytes forward from beginning.
fseek(fp, 10, SEEK_ CUR): moves file pointer 10bytes forward from current position.
fseek(fp, -10, SEEK_ CUR): moves file pointer 10bytes backward from current position.
SEEK_END is a macro defines the end-of-file. Value is equal to 2.
SEEK_SET is a macro defines the begging-of-file. Value is equal to 0.
SEEK_CUR is a macro defines the current-position of file. Value is equal to 1.
EOF: it is a macro, represents end of file mark for the text files. (EOF value is equal to 26)
feof(): It is used to check whether a given file has reached the End Of File mark or not.
rename():changes the name of an existing file. syntax: rename(“oldName”, “newName”);
remove():deletes a file from disk. syntax: remove(“fileName”);
filelength(): it gives length of file (the number of bytes occupied by the file)

Writing integers to a file


This is a sample program, writing 10 , 20 , 30 , 40 , 50 to a text file.
#include<stdio.h>
void main()
{ FILE *fp; // pointer to file
int a=10, b=20, c=30, d=40, e=50; // taking input values.
fp=fopen("sample.txt", "wt"); // w=write mode, t=text file.
if(fp==NULL)
{ printf("file not opened");
return;
}
fprintf(fp, "%d %d %d %d %d", a, b, c, d, e); // writing all integers to file.
fclose(fp); // saves into disk
}

Output
file name: sample.txt
10 20 30 40 50
C-Family 263 Data Files

Reading integers from a file


This is opposite to above program, reading integer from file and showing on the screen.
#include<stdio.h>
void main()
{ FILE *fp;
int n , k;
fp=fopen("sample.txt", "rt");
if(fp==NULL)
{ printf("file not opened");
return;
}
while(1)
{ k=fscanf(fp, "%d", &n); // reading an integer from file, fscanf() returns -1 if EOF touched)
if(k==-1) break; // stopped when end of file is reached
printf("%d ", n); // displaying on the screen
}
fclose(fp);
}

Above program in binary i/o format


#include<stdio.h>
void main()
{ writeToFile();
readingBackFromFileAndPrint();
}
void writeToFile()
{ FILE *fp;
int a=10, b=20, c=30;
fp=fopen("sample.txt", "wb");
if(fp==NULL)
{ printf(“file not opened”);
return;
}
fwrite( &a, sizeof(int), 1, fp ); // for binary files, use only fwrite(), fread()
fwrite( &b, sizeof(int), 1, fp );
fwrite( &c, sizeof(int), 1, fp );
fclose(fp); // saves file contents on disk
}
void readingBackFromFileAndPrint()
{ int k , n; FILE *fp;
fp=fopen("sample.txt", "rb");
if(fp==NULL)
{ printf(“file not opened”);
return;
}
while(1)
{ k=fread(&n, sizeof(n), 1, fp);
if(k<=0) break; // fread() returns 0 when end of file is reached
printf("%d ", n ); // printing on screen:
}
fclose(fp); // will not save on disk, because opened in read-only mode, only clears from RAM.
}
C-Family 264 Data Files

Copy odd numbers from one file to another file


Let our text file “input.txt” contained some even&odd numbers, now read numbers one by one from file
and copy only odd numbers into another file called “output.txt”.
file name: “input.txt” File name:”output.txt”
12 17 20 13 29 30  17 13 29 35 43 27
32 35 40 43 27 20 21 29 31 39 11 3
21 29 31 39 11 12
10 8 2 3
void main()
{ FILE *fs, *ft; int n, k;
char sName[30], dName[30];
printf(“enter source & destination file names :”);
gets(sName);
gets(dName);
fs=fopen(sName,”rt”);
ft=fopen(dName,”wt”);
if( fs==NULL || ft==NULL)
{ printf(“file not opened”);
return;
}
while(1)
{ k=fread( &n, sizeof(n), 1, fs );
if(k<=0) break;
if(n%2==1) // if odd number then write to file
fwrite( &n, sizeof(n), 1, ft);
}
fclose(fs);
fclose(ft);
}

Write a program to copy one file content to another file


Note: the binary file organization works for both text/binary format files
void main()
{ FILE *fs, *ft; char ch;
char sName[30], dName[30];
printf(“enter source & destination file names :”);
gets(sName);
gets(dName);
fs=fopen( sName , ”rb”);
ft=fopen( dName , ”wb”);
while(1)
{ k=fread( &ch, sizeof(ch), 1, fs);
if(k<=0) break;
fwrite( &ch, sizeof(ch), 1, ft);
}
fclose(fs);
fclose(ft);
}
C-Family 265 Data Files

Program to write text to a file


This program accepts a text (char by char) from keyboard and store into a file called "sample.txt".
The written contents of file can be seen using any text editor like notepad.
#include<stdio.h> // to include FILE structure and its IO functions.
void main()
{ char ch;
FILE *fp; // pointer to a file
fp=fopen("sample.txt","wt"); // opening text file in write mode
if(fp==NULL)
{ printf(“unable to open the file ");
return;
}
printf("\n enter text (at end of input type F6) :”);
while(1)
{ ch=getchar(); or scanf(“%c”, &ch) //accepting char by char (text) from Keyboard
if(ch==EOF) break; // EOF is end of file mark, when F6 pressed
fputc(ch,fp); or fprintf(fp, “%c”, ch); // writing char to file
}
fclose(fp); // storing (saving) file contents into disk
}
Input: hello
how are you
how do you do
fine
thanks
^Z (press f6) (^Z is equal to EOF)
Output:
File name: “sample.txt”
hello
how are you
how do you do
fine
thanks

Program to count upper, lower, digits and others in a given file


This program counts number of upper case alphabets, lower case alphabets, digits, words and lines in a
given text file. It reads char by char from a given file and checks the each character and counts.
#include <stdio.h>
#include <ctype.h>
void main()
{ FILE *fp;
int upperCount,lowerCount, digitCount, lineCount,wordCount;
char fileName[30], ch;
puts("Enter the file name:");
gets(fileName);
fp=fopen(fileName,"rt");
if(fp== NULL)
{ printf("file not found");
exit(0);
C-Family 266 Data Files

}
upperCount=lowerCount=digitCount=lineCount=wordCount=0;
while(1)
{ ch=fgetc(fp); // reading single char from file
if(ch==EOF) break; // EOF  end of file indicator
if( isupper(ch) ) upperCount++;
else if( islower(ch) ) lowerCount++;
else if( isdigit(ch) ) digitCount++;
else if(ch==' ') wordCount++;
else if(ch=='\n')
{ wordCount++;
lineCount++;
}
}
fclose(fp);
printf("lower count = %d", lowerCount);
printf("upper count = %d", upperCount);
printf("digits count = %d", digitCount);
printf("words count = %d", wordCount);
printf(" lines count = %d", lineCount);
}

Handling student details ( binary files)


This program accepts student marks from keyboard and inserts each record into a file called “marks.dat”,
later read back and process the result and shows on the screen.
Note: this is demo program, for binary file IO system; here fread() & fwrite() functions are used
struct Student
{ int idno,m1,m2;
char name[30];
};

#include<stdio.h>
void main()
{ acceptMarks();
processAndShow();
}
void acceptMarks()
{ FILE *fp;
struct Student st;
fp=fopen("marks.dat","wb");
while(1)
{ printf("\n enter idno (0 to stop):");
scanf("%d",&st.idno);
if( st.idno==0) break; // 0 is end of input
printf("enter name:");
fflush(stdin);
gets(st.name);
printf("enter marks1:");
scanf("%d",&st.m1);
printf("enter marks2:");
C-Family 267 Data Files

scanf("%d",&st.m2);
fwrite( &st, sizeof(st), 1, fp); // for total, average garbage will be stored
}
fclose(fp);
}
void processAndShow()
{ FILE *fp;
struct Student st;
int k, total, avg;
char *result;
fp=fopen("marks.dat","rb");
printf("\n%6s %-20s %5s %5s %-20s", "idno", "name", "mark1", "mark2", "result");
printf("\n---------------------------------------------------------------------------");
while(1)
{ k=fread( &st, sizeof(st), 1,fp);
if(k<=0) break; // end of file reached then stop it.
total=(st.m1+st.m2);
avg=total/40;
if( st.m1<35 || st.m2<35 )
result="Failed";
else if(avg>=60)
result="First class";
else if(avg>=50)
result="Second class";
else result="Third class";
printf("\n %-6d %-20s %5d %5d %-20s", st.idno, st.name, st.m1, st.m2, result);
}
fclose(fp);
}

A menu driven program to handle employee records ( mini project work)


A menu driven program to handle employee records
This program manages employee information: it supports adding newly joined employee details, deleting
relieving employee record, modifying address or any other information of employee, printing particulars.
Employee details are stored in a separate file called "emp.dat".
This menu run program provides the user to select his choice of operation.
Menu Run
--------------------------------
1. Adding new employee
2. Deleting employee record
3. Modifying existing record
4.Printing employee details
0. Exit
Enter choice [1,2,3,4,0]:
#include<stdio.h>
typedef struct // structure of an employee
{ int empNo;
char name[30];
float salary;
}EMP;
void append(); void modify(); void delete(); void print(); // fn proto-types
C-Family 268 Data Files

void main()
{ int choice;
while(1) // loop to display menu continuously
{ printf("\n\n=============================================================");
printf("\n 1.append \n 2.delete \n 3.modify\n 4 print \n 0.exit");
printf("\n Enter choice [1,2,3,4,0]:");
scanf("%d", &choice);
switch(choice)
{ case 1: append(); break;
case 2: delete(); break;
case 3: modify(); break;
case 4: print(); break;
case 0: exit(0);
}
}
}
// ------------------------------------------------------------------------------------------------------------------------
// this append function appends a record in the file
void append()
{ FILE *fp; EMP e;
fp=fopen("emp.dat", "ab");
if(fp==NULL)
{ printf("\nUnable to open emp.dat file");
return;
}
printf("\n enter employee no:");
scanf("%d",&e.empNo);
printf("Enter employee name:");
fflush(stdin);
gets(e.name);
printf("enter salary :");
scanf("%f",&e.salary);
fwrite(&e,sizeof(e),1,fp);
fclose(fp);
printf("\n successfully record added");
}

// --------------------------------------------------------------------------------------------------------------------------
// deleting record, generally, it is not possible to delete a record in a file. Alternative is, copying all records
// into another temporary file except deleting record; later temporary file will be renamed with the original
// file name.
void delete()
{ FILE *fp,*ft; EMP e;
int eno, found=0, k;
fp=fopen("emp.dat", "rb");
ft=fopen("temp.dat", "wb");
if(fp==NULL || ft==NULL )
{ printf("\nunable to open file");
fclose(fp); fclose(ft); return;
}
printf("\nenter employee number to delete record :");
scanf("%d",&eno);
while(1)
{ k=fread(&e,sizeof(e),1,fp);
C-Family 269 Data Files

if(k==0)break;
if(eno==e.empNo)
found=1; // record is found
else
fwrite(&e,sizeof(e), 1 ,ft);
}
if(found==1) printf("\nRecord deleted success fully");
else printf("\nRecord Not found");
fclose(fp); fclose(ft);
remove("emp.dat");
rename("temp.dat","emp.dat");
}

// --------------------------------------------------------------------------------------------------------------------------------------
// Modifying data in a record. First, it searches for modifying record in a file, if record is not found then
// displays error message & returns. If found, then old-salary overwrites by new-salary of a record
void modify()
{ EMP e;
int found=0 , eno, k;
long int pos;
FILE *fp;
fp=fopen("emp.dat","rb+");
if(fp==NULL)
{ printf("\nfile not found ");
exit(0);
}
printf("\n enter employee number:");
scanf("%d",&eno);
while(1)
{ k=fread(&e,sizeof(e),1,fp);
if(k==0) break;
if(eno==e.empNo)
{ found=1; // record is found
break;
}
}
if(found==0)
{ printf("\n Record not found");
return;
}
pos=ftell(fp);
pos=pos-sizeof(e);
fseek(fp, pos, SEEK_SET); // move the file pointer one position back
printf("old salary : %.2f", e.salary);
printf("enter new salary:");
scanf("%f", &e.salary);
fwrite(&e,sizeof(e), 1 ,fp); // overwriting old record
fclose(fp);
printf("\n address suceessfully modified");
}

// --------------------------------------------------------------------------------------------------------------------------------------
C-Family 270 Data Files

// print function, prints all records


void print()
{ EMP e; int k, count=0;
FILE *fp;
fp=fopen("emp.dat", "rb");
if(fp==NULL)
{ printf("\nfile not found ");
return;
}
while(1)
{ k=fread(&e,sizeof(e), 1,fp);
if(k==0) break;
printf("\n employee number: %d",e.empNo);
printf("\n employee name : %s",e.name);
printf("\n Salary: %.2f", e.salary);
count++;
printf("\n--------------------------------");
}
printf("\n(%d) records found", count);
fclose(fp);
}

Low-level file I/O functions


In C language, we have another set of file I/O functions that are treated as low-level functions, because
these functions do not support formatted I/O. These functions make O/S system calls directly, hence faster.
File opening: Unlike the fopen() function, open function returns file descriptor (or handler), which is just
an integer that can uniquely identify the opened file.
Prototype: int open(char * filename, int mode, int permission );
Here mode should be specified with any combinations of the following items.
0_CREAT, 0_APPEND, 0_RD0NLY, 0_WR0NLY, 0_RDWR, 0_TRUNC etc.
These are macro symbolic constants, defined in “fcnti.h” header file
The 3rd argument is an optional argument, which may be required to get file-handling permission especially
in network environments.
This argument is specified with any one or combination of: SJREAD, SJWRITE
These definitions are available in 'sys/stat. h' header file;
fd=open("SAMP.DAT", 0_CREAT | 0_WR0NLY, SJWRITE );
File Closing: Prototype close(int fileDescriptor);
for example : close(fd); This function returns zero on success otherwise -1 :
Reading/Writing Data: int write(int fd, void*mem, int size), int read(int fd, void*mem, int size);

This book softcopy is available in pdfhost.io website, to download the file, search through keyword ‘cfamily’.
This pdf file(s) designed for 2-sided print-copy (Xerox hard copy).

You might also like