0% found this document useful (0 votes)
185 views

C Language Unit 1,2,3,4,5

The document provides information on computer basics, including: 1) A computer accepts data as input, processes it, produces output, and stores information for future use. It carries out functions like taking input, storing data, processing data, generating output, and controlling these steps. 2) Hardware refers to the physical components of a computer like circuit boards and processors. Software is a collection of instructions that tells a computer what to do and allows users to interact with it, like internet browsers and operating systems. 3) The structure of a C program involves requirements analysis, design, coding, testing, and maintenance phases where the problem is defined, solutions are generated and selected, the program is implemented and tested,

Uploaded by

Lovely Vasanth
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
185 views

C Language Unit 1,2,3,4,5

The document provides information on computer basics, including: 1) A computer accepts data as input, processes it, produces output, and stores information for future use. It carries out functions like taking input, storing data, processing data, generating output, and controlling these steps. 2) Hardware refers to the physical components of a computer like circuit boards and processors. Software is a collection of instructions that tells a computer what to do and allows users to interact with it, like internet browsers and operating systems. 3) The structure of a C program involves requirements analysis, design, coding, testing, and maintenance phases where the problem is defined, solutions are generated and selected, the program is implemented and tested,

Uploaded by

Lovely Vasanth
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 247

Unit-1

Computer Basics

Introduction to Computers :-

A computer is an electronic device, operating under the control of instructions stored in


its own memory that can accept data (input), process the data according to specified
rules, produce information (output), and store the information for future use

Functionalities of a computer:-

Any digital computer carries out five functions in gross terms:

Takes data as input.

Stores the data/instructions in its memory and use them when required.

Processes the data and converts it into useful information.

Generates the output

Controls all the above four steps.

HARDWARE AND SOFTWARE.

Hardware

refers to the physical components of a computer or a machine that we can see and
touch. It contains circuit board, ICs, or other electronics in a computer system. It is a
physical component that is used in different ways to build a computer or any other
machine. The Memory Devices, Processor, Central Processing Unit

, Mouse

, and the keyboard

1
all are the examples of the hardware in the computer system. On the other hand, the
screen on which you are viewing this page is the best example of the hardware, whether
you are viewing this page on the tablet, monitor, or smartphone. A computer system
would not be existing without any hardware and not able to run any software. An
example of an external hardware peripheral, a keyboard, is shown in the picture. It
allows users to give input to the computer.

Computer Software

Software

is a collection of procedures, instructions, documentation that tells a computer exactly


what to do or allows users to interact with a computer. Sometimes it is abbreviated as
S/W and SW, which is most important for a computer or other similar devices. Most of
the computers may be useless without software. For example, if a software
program, MS-Word

is not installed into your computer, you cannot make any document that can be
completed through MS-Word. Also, you cannot surf the Internet

or visit any website if your system has no Internet browser software. Additionally,
the browser

could not run on the computer without an operating system. The Google Chrome

, Photoshop, MS Word, Excel

, MySQL

and more are examples of software. The picture is shown below, is an example of
software, which is a picture of Google Chrome, which is an Internet software program.

Software is a collection of instructions run on the computer, whereas hardware is a


physical device used with or on the computer. On the other hand, the software cannot
be touch and held in your hand, whereas hardware can be touch and held in your hand.
Below is given a table that holds the differences between hardware and software.

2
The problem solving techniques

Problem solving is the act of defining a problem; determining the cause of the problem;
identifying, prioritizing, and selecting alternatives for a solution; and implementing a
solution.

 The problem-solving process


 Problem solving resources

Problem Solving Chart

THE PROBLEM-SOLVING PROCESS

In order to effectively manage and run a successful organization, leadership must guide
their employees and develop problem-solving techniques. Finding a suitable solution
for issues can be accomplished by following the basic four-step problem-solving
process and methodology outlined below.

Step Characteristics

1. Define the problem  Differentiate fact from opinion


 Specify underlying causes
 Consult each faction involved for information
 State the problem specifically
 Identify what standard or expectation is violated
 Determine in which process the problem lies
 Avoid trying to solve the problem without data

3
Step Characteristics

2. Generate alternative solutions  Postpone evaluating alternatives initially


 Include all involved individuals in the generating of
alternatives
 Specify alternatives consistent with organizational
goals
 Specify short- and long-term alternatives
 Brainstorm on others' ideas
 Seek alternatives that may solve the problem

3. Evaluate and select an  Evaluate alternatives relative to a target standard


alternative  Evaluate all alternatives without bias
 Evaluate alternatives relative to established goals
 Evaluate both proven and possible outcomes
 State the selected alternative explicitly

4. Implement and follow up on  Plan and implement a pilot test of the chosen
the solution alternative
 Gather feedback from all affected parties
 Seek acceptance or consensus by all those affected
 Establish ongoing measures and monitoring
 Evaluate long-term results based on final solution

Program Development steps in C

Ans:-The program development steps or phases that we follow a sequence of steps to


develop a program in any programming language.
Generally, the program development steps contains 6 phases, they are as follows

1. Requirements
2. Analysis
3. Design
4. Coding
5. Testing

4
6. Maintenance

1. Requirements:-

 we define the problem statement and we decide the boundaries of the problem.
 Information about the problem must be stated clearly and unambiguously.
 we need to understand the problem statement and gather the preliminary
requirements.
 Main objective of this phase is to eliminate unimportant aspects and identify the
root problem

2. Analysis:-

 All the factors like Input/output, processing requirement, memory requirements,


error handling, interfacing with other programs have to be taken into
consideration in this stage.
 It also determines the required format in which results should be displayed

3. Design:-

 The software developer makes use of tools like algorithms and flowcharts to
develop the design of the program.
o Algorithm
o Flowchart
 Algorith is the list of instructions in a perticular order to solve the problem
 Flowcharts are used to get the pictorial representation of the algorithm

4. Coding:-

 Once the design process is complete, converting algorithm to a program by


selecting any one of the high – level languages that is suitable for the problem.
 Coding is generally a very small part of the entire program development process
and also a less time consuming activity in reality.
 In this process we identify and eliminate all the syntax errors related to spelling,
missing commas, undefined labels etc.

5
 For effective coding some of the guide lines are to be follow:
o Use of meaningful names and labels of variables
o Simple and clear expressions
o Modularity with emphasis on making modules generalized
o Making use of comments and indenting the code properly
o Avoiding jumps in the program to transfer control

5.Testing:-

 The program is tested on a number of suitable test cases.


 A test plan of the program has to be done at the stage of the program design
itself.
 This ensures a thorough understanding of the specifications.
 Running the program several times using different sets of data verifies whether a
program works correctly for every situation provided in the algorithm.
 It is always useful to include the maximum and minimum values of all variables as
test data.

6..Maintenance:-

 Updating and correction of the program for changed conditions and field
experience is accounted for in maintenance.
 Maintenance becomes essential in following situations:
o Change in specification
o Change in equipment
Errors which are found during the actual execution of the program.

Structure of a C program

The structure of a C program means the specific structure to start the programming in
the C language. Without a proper structure, it becomes difficult to analyze the problem
and the solution. It also gives us a reference to write more complex programs.

Let's first discuss about C programming.

6
C programming

C language

combines the power of a low-level language and a high-level language. The low-level
languages are used for system programming, while the high-level languages are used
for application programming. It is because such languages are flexible and easy to use.
Hence, C language is a widely used computer language.

It supports various operators, constructors, data structures, and loop constructs. The
features of C programming make it possible to use the language for system
programming, development of interpreters, compilers, operating systems, graphics,
general utilities, etc. C is also used to write other applications, such as databases,
compilers, word processors, and spreadsheets

The essential features of a C program are as follows:

Pointers: it allows reference to a memory location by the name assigned to it in a


program.

Memory allocation: At the time of definition, memory is assigned to a variable name,


allowing dynamic allocation of the memory. It means that the program itself can request
the operating system to release memory for use at the execution time.

Recursion: When a function calls itself, it is known as recursion.

Bit-manipulation: It refers to the manipulation of data in its lowest form. It is also


known as bits. The computer stores the information in binary format (0 and 1).

Let's start with the importance of specifying the structure of a C program.

Importance of structure of a C program

Sometimes, when we begin with a new programming language, we are not aware about
the basic structure of a program. The sections of a program usually get shuffled and the
chance of omission of error rises. The structure of a language gives us a basic idea of
the order of the sections in a program. We get to know when and where to use a
particular statement, variable, function, curly braces, parentheses, etc. It also
increases our interest in that programming language.

7
Thus, the structure helps us analyze the format to write a program for the least errors. It
gives better clarity and the concept of a program.

Here, we will discuss the sections of a C program, some practical examples with
explanations, steps to compile and execute a C program.

History of C Language

History of C language is interesting to know. Here we are going to discuss a brief


history of the c language.

C programming language was developed in 1972 by Dennis Ritchie at bell laboratories


of AT&T (American Telephone & Telegraph), located in the U.S.A.

Dennis Ritchie is known as the founder of the c language.

It was developed to overcome the problems of previous languages such as B, BCPL,


etc.10

Initially, C language was developed to be used in UNIX operating system. It inherits


many features of previous languages such as B and BCPL.

Let's see the programming languages that were developed before C language.

C Identifiers

C identifiers represent the name in the C program, for example, variables, functions,
arrays, structures, unions, labels, etc. An identifier can be composed of letters such as
uppercase, lowercase letters, underscore, digits, but the starting letter should be either
an alphabet or an underscore. If the identifier is not used in the external linkage, then it
is called as an internal identifier. If the identifier is used in the external linkage, then it is
called as an external identifier.

We can say that an identifier is a collection of alphanumeric characters that begins


either with an alphabetical character or an underscore, which are used to represent
various programming elements such as variables, functions, arrays, structures, unions,
labels, etc. There are 52 alphabetical characters (uppercase and lowercase), underscore
character, and ten numerical digits (0-9) that represent the identifiers. There is a total of
63 alphanumerical characters that represent the identifiers.

Rules for constructing C identifiers

8
o The first character of an identifier should be either an alphabet or an underscore,
and then it can be followed by any of the character, digit, or underscore.
o It should not begin with any numerical digit.
o In identifiers, both uppercase and lowercase letters are distinct. Therefore, we can
say that identifiers are case sensitive.
o Commas or blank spaces cannot be specified within an identifier.
o Keywords cannot be represented as an identifier.
o The length of the identifiers should not be more than 31 characters.
o Identifiers should be written in such a way that it is meaningful, short, and easy to
read.

Example of valid identifiers

total, sum, average, _m _, sum_1, etc.

Example of invalid identifiers

1. 2sum (starts with a numerical digit)


2. int (reserved word)
3. char (reserved word)
4. m+n (special character, i.e., '+')

Types of identifiers

o Internal identifier
o External identifier

Internal Identifier

If the identifier is not used in the external linkage, then it is known as an internal
identifier. The internal identifiers can be local variables.

External Identifier

If the identifier is used in the external linkage, then it is known as an external identifier.
The external identifiers can be function names, global variables.

9
Differences between Keyword and Identifier

Keyword Identifier

Keyword is a pre-defined word. The identifier is a user-defined word

It must be written in a lowercase letter. It can be written in both lowercase and uppercase
letters.

Its meaning is pre-defined in the c Its meaning is not defined in the c compiler.
compiler.

It is a combination of alphabetical It is a combination of alphanumeric characters.


characters.

It does not contain the underscore It can contain the underscore character.
character.

Let's understand through an example.

1. int main()
2. {
3. int a=10;
4. int A=20;
5. printf("Value of a is : %d",a);
6. printf("\nValue of A is :%d",A);
7. return 0;
8. }

Output

Value of a is : 10
Value of A is :20

10
The above output shows that the values of both the variables, 'a' and 'A' are different.
Therefore, we conclude that the identifiers are case sensitive.

Data Types and Sizes

A data type specifies the type of data that a variable can store such as integer, floating,
character, etc.

There are the following data types in C language.

Types Data Types

Basic Data Type int, char, float, double

Derived Data Type array, pointer, structure, union

Enumeration Data Type enum

Void Data Type void

Basic Data Types

The basic data types are integer-based and floating-point based. C language supports
both signed and unsigned literals.

The memory size of the basic data types may change according to 32 or 64-bit
operating system.

Let's see the basic data types. Its size is given according to 32-bit architecture.

11
Data Types Memory Size Range

char 1 byte −128 to 127

signed char 1 byte −128 to 127

unsigned char 1 byte 0 to 255

short 2 byte −32,768 to 32,767

signed short 2 byte −32,768 to 32,767

unsigned short 2 byte 0 to 65,535

int 2 byte −32,768 to 32,767

signed int 2 byte −32,768 to 32,767

unsigned int 2 byte 0 to 65,535

short int 2 byte −32,768 to 32,767

signed short int 2 byte −32,768 to 32,767

unsigned short int 2 byte 0 to 65,535

long int 4 byte -2,147,483,648 to 2,147,483,647

signed long int 4 byte -2,147,483,648 to 2,147,483,647

unsigned long int 4 byte 0 to 4,294,967,295

float 4 byte

double 8 byte

long double 10 byte

Constants in C

A constant is a value or variable that can't be changed in the program, for example: 10,
20, 'a', 3.4, "c programming" etc.

12
There are different types of constants in C programming.

List of Constants in C

Constant Example

Decimal Constant 10, 20, 450 etc.

Real or Floating-point Constant 10.3, 20.2, 450.6 etc.

Octal Constant 021, 033, 046 etc.

Hexadecimal Constant 0x2a, 0x7b, 0xaa etc.

Character Constant 'a', 'b', 'x' etc.

String Constant "c", "c program", "c in javatpoint" etc.

2 ways to define constant in C

There are two ways to define constant in C programming

.const keyword

1. #define preprocessor

1) C const keyword

The const keyword is used to define constant in C programming.

Variables in C

A variable is a name of the memory location. It is used to store data. Its value can be
changed, and it can be reused many times.

13
It is a way to represent memory location through symbol so that it can be easily
identified.

Let's see the syntax to declare a variable:

1. type variable_list;

The example of declaring the variable is given below:

1. int a;
2. float b;
3. char c;

Here, a, b, c are variables. The int, float, char are the data types.

We can also provide values while declaring the variables as given below:

1. int a=10,b=20;//declaring 2 variable of integer type


2. float f=20.8;
3. char c='A';

Rules for defining variables

o A variable can have alphabets, digits, and underscore.


o A variable name can start with the alphabet, and underscore only. It can't start
with a digit.
o No whitespace is allowed within the variable name.
o A variable name must not be any reserved word or keyword, e.g. int, float, etc.

Valid variable names:

1. int a;
2. int _ab;
3. int a30;

Invalid variable names:

1. int 2;

14
2. int a b;
3. int long;

Types of Variables in C

There are many types of variables in c:

1. local variable
2. global variable
3. static variable
4. automatic variable
5. external variable

Local Variable

A variable that is declared inside the function or block is called a local variable.

It must be declared at the start of the block.

1. void function1(){
2. int x=10;//local variable
3. }

You must have to initialize the local variable before it is used.

Global Variable

A variable that is declared outside the function or block is called a global variable. Any
function can change the value of the global variable. It is available to all the functions.

It must be declared at the start of the block.

1. int value=20;//global variable


2. void function1(){
3. int x=10;//local variable
4. }

15
Static Variable

A variable that is declared with the static keyword is called static variable.

It retains its value between multiple function calls.

1. void function1(){
2. int x=10;//local variable
3. static int y=10;//static variable
4. x=x+1;
5. y=y+1;
6. printf("%d,%d",x,y);
7. }

If you call this function many times, the local variable will print the same value for
each function call, e.g, 11,11,11 and so on. But the static variable will print the
incremented value in each function call, e.g. 11, 12, 13 and so on.

Automatic Variable

All variables in C that are declared inside the block, are automatic variables by default.
We can explicitly declare an automatic variable using auto keyword.

1. void main(){
2. int x=10;//local variable (also automatic)
3. auto int y=20;//automatic variable
4. }

External Variable

We can share a variable in multiple C source files by using an external variable. To


declare an external variable, you need to use extern keyword.

myfile.h

1. extern int x=10;//external variable (also global)


program1.c

1. #include "myfile.h"
2. #include <stdio.h>

16
3. void printValue(){
4. printf("Global variable: %d", global_variable);
5. }
1. const float PI=3.14;

Now, the value of PI variable can't be changed.

1. #include<stdio.h>
2. int main(){
3. const float PI=3.14;
4. printf("The value of PI is: %f",PI);
5. return 0;
6. }

Output:

The value of PI is: 3.140000


Operators

An operator is simply a symbol that is used to perform operations. There can be many
types of operations like arithmetic, logical, bitwise, etc.

There are following types of operators to perform different types of operations in C


language.

o Arithmetic Operators
o Relational Operators
o Shift Operators
o Logical Operators
o Bitwise Operators
o Ternary or Conditional Operators
o Assignment Operator
o Misc Operator

Precedence of Operators in C

17
The precedence of operator species that which operator will be evaluated first and next.
The associativity specifies the operator direction to be evaluated; it may be left to right
or right to left.

Let's understand the precedence by the example given below:

1. int value=10+20*10;

The value variable will contain 210 because * (multiplicative operator) is evaluated
before + (additive operator).

The precedence and associativity of C operators is given below:

Category Operator Associativity

Postfix () [] -> . ++ - - Left to right

Unary + - ! ~ ++ - - (type)* & sizeof Right to left

Multiplicative */% Left to right

Additive +- Left to right

Shift << >> Left to right

Relational < <= > >= Left to right

Equality == != Left to right

Bitwise AND & Left to right

Bitwise XOR ^ Left to right

Bitwise OR | Left to right

Logical AND && Left to right

Logical OR || Left to right

Conditional ?: Right to left

Assignment = += -= *= /= %=>>= <<= &= ^= |= Right to left

18
Comma , Left to right

Type Casting
Type casting is a method that converts a data type into another data type in both ways
manually and automatically. The automatic conversion is done by the compiler and
manual conversion performed by the programmer.
Type casting are 2 Types:
1. Implicit
2. Explicit
Implicit:

i) Also known as ‘automatic type conversion’. ii) Done by the compiler on its own,
without any external trigger from the user. iii) Generally takes place when in an
expression more than one data type is present. iv) In such condition type conversion
(type promotion) takes place to avoid loss of data. v)All the data types of the variables
are upgraded to the data type of the variable with largest data type.

Explicit :

This process is also called type casting and it is user defined. Here the user can type cast
the result to make it of a particular data

Next Top

19
Expression

An expression is a formula in which operands are linked to each other by the use of
operators to compute a value.

Arithmetic expressions : An arithmetic expression is an expression that consists of


operands and arithmetic operators. An arithmetic expression computes a value of type
int, float or double.

Ex : 6*2/ (2+1 * 2/3 + 6) + 8 * (8/4) Relational expressions : o A relational expression is


an expression used to compare two operands. o It is a condition which is used to decide
whether the action should be taken or not.

Ex: x%2 = = 0

Logical expressions :

o A logical expression is an expression that computes either a zero or nonzero value. o It


is a complex test condition to take a decision.

Ex : ( x > 4 ) && ( x < 6 )

Conditional expressions :

o A logical expression is an expression that computes either a zero or nonzero value. o It


is a complex test condition to take a decision.

Syntax: exp1 ? exp2 : exp3

Ex: Int x=5, y=3;

(x<y)?(printf(“x is small”)):((printf(“x is big”));

Precedence and order of evaluation

The precedence and associativity of C operators affect the grouping and evaluation of
operands in expressions. An operator's precedence is meaningful only if other operators
with higher or lower precedence are present. Expressions with higher-precedence
operators are evaluated first. Precedence can also be described by the word "binding."
Operators with a higher precedence are said to have tighter binding.

20
The following table summarizes the precedence and associativity (the order in which the
operands are evaluated) of C operators, listing them in order of precedence from
highest to lowest. Where several operators appear together, they have equal
precedence and are evaluated according to their associativity. The operators in the table
are described in the sections beginning with Postfix Operators. The rest of this section
gives general information about precedence and associativity.

Precedence and associativity of C operators

Symbol 1 Type of operation Associativity

[ ] ( ) . -> Expression Left to right


++ -- (postfix)

sizeof & * + - ~ ! Unary Right to left


++ -- (prefix)

typecasts Unary Right to left

*/% Multiplicative Left to right

+- Additive Left to right

<< >> Bitwise shift Left to right

< > <= >= Relational Left to right

== != Equality Left to right

& Bitwise-AND Left to right

^ Bitwise-exclusive-OR Left to right

| Bitwise-inclusive-OR Left to right

&& Logical-AND Left to right

|| Logical-OR Left to right

?: Conditional-expression Right to left

21
Symbol 1 Type of operation Associativity

= *= /= %= Simple and compound assignment 2 Right to left


+= -= <<= >>= &=
^= |=

, Sequential evaluation Left to right

1
Operators are listed in descending order of precedence. If several operators appear on
the same line or in a group, they have equal precedence.

2
All simple and compound-assignment operators have equal precedence.

An expression can contain several operators with equal precedence. When several such
operators appear at the same level in an expression, evaluation proceeds according to
the associativity of the operator, either from right to left or from left to right. The
direction of evaluation does not affect the results of expressions that include more than
one multiplication (*), addition (+), or binary-bitwise (&, |, or ^) operator at the same
level. Order of operations is not defined by the language. The compiler is free to
evaluate such expressions in any order, if the compiler can guarantee a consistent result.

Only the sequential-evaluation (,), logical-AND (&&), logical-OR (||), conditional-


expression (? :), and function-call operators constitute sequence points, and therefore
guarantee a particular order of evaluation for their operands. The function-call operator
is the set of parentheses following the function identifier. The sequential-evaluation
operator (,) is guaranteed to evaluate its operands from left to right. (The comma
operator in a function call is not the same as the sequential-evaluation operator and
does not provide any such guarantee.) For more information, see Sequence points.

Logical operators also guarantee evaluation of their operands from left to right.
However, they evaluate the smallest number of operands needed to determine the
result of the expression. This is called "short-circuit" evaluation. Thus, some operands of
the expression may not be evaluated. For example, in the expression

x && y++

the second operand, y++, is evaluated only if x is true (nonzero). Thus, y is not
incremented if x is false (0).

22
Control Structures

C if else Statement

The if-else statement in C is used to perform the operations based on some specific
condition. The operations specified in if block are executed if and only if the given
condition is true.

There are the following variants of if statement in C language.

o If statement
o If-else statement
o If else-if ladder
o Nested if

If Statement

The if statement is used to check some given condition and perform some operations
depending upon the correctness of that condition. It is mostly used in the scenario
where we need to perform the different operations for the different conditions. The
syntax of the if statement is given below.

1. if(expression){
2. //code to be executed
3. }

Flowchart of if statement in C

Let's see a simple example of C language if statement.

1. #include<stdio.h>
2. int main(){
3. int number=0;
4. printf("Enter a number:");
5. scanf("%d",&number);
6. if(number%2==0){
7. printf("%d is even number",number);
8. }

23
9. return 0;
10. }

Output

Enter a number:4
4 is even number
enter a number:5

Program to find the largest number of the three.


1. #include <stdio.h>
2. int main()
3. {
4. int a, b, c;
5. printf("Enter three numbers?");
6. scanf("%d %d %d",&a,&b,&c);
7. if(a>b && a>c)
8. {
9. printf("%d is largest",a);
10. }
11. if(b>a && b > c)
12. {
13. printf("%d is largest",b);
14. }
15. if(c>a && c>b)
16. {
17. printf("%d is largest",c);
18. }
19. if(a == b && a == c)
20. {
21. printf("All are equal");
22. }
23. }

Output

Enter three numbers?

24
12 23 34
34 is largest

If-else Statement

The if-else statement is used to perform two operations for a single condition. The if-
else statement is an extension to the if statement using which, we can perform two
different operations, i.e., one is for the correctness of that condition, and the other is for
the incorrectness of the condition. Here, we must notice that if and else block cannot be
executed simiulteneously. Using if-else statement is always preferable since it always
invokes an otherwise case with every if condition. The syntax of the if-else statement is
given below.

if(expression){

1. //code to be executed if condition is true


2. }else{
3. //code to be executed if condition is false
4. }

Flowchart of the if-else statement in C

25
Let's see the simple example to check whether a number is even or odd using if-else
statement in C language.

1. #include<stdio.h>
2. int main(){
3. int number=0;
4. printf("enter a number:");
5. scanf("%d",&number);
6. if(number%2==0){
7. printf("%d is even number",number);
8. }
9. else{
10. printf("%d is odd number",number);
11. }
12. return 0;
13. }

Output

enter a number:4
4 is even number
enter a number:5
5 is odd number

Program to check whether a person is eligible to vote or not.


1. #include <stdio.h>
2. int main()
3. {
4. int age;
5. printf("Enter your age?");
6. scanf("%d",&age);
7. if(age>=18)
8. {
9. printf("You are eligible to vote...");
10. }
11. else

26
12. {
13. printf("Sorry ... you can't vote");
14. }
15. }

Output

Enter your age?18


You are eligible to vote...
Enter your age?13
Sorry ... you can't vote

If else-if ladder Statement

The if-else-if ladder statement is an extension to the if-else statement. It is used in the
scenario where there are multiple cases to be performed for different conditions. In if-
else-if ladder statement, if a condition is true then the statements defined in the if block
will be executed, otherwise if some other condition is true then the statements defined
in the else-if block will be executed, at the last if none of the condition is true then the
statements defined in the else block will be executed. There are multiple else-if blocks
possible. It is similar to the switch case statement where the default is executed instead
of else block if none of the cases is matched.

1. if(condition1){
2. //code to be executed if condition1 is true
3. }else if(condition2){
4. //code to be executed if condition2 is true
5. }
6. else if(condition3){
7. //code to be executed if condition3 is true
8. }
9. ...
10. else{
11. //code to be executed if all the conditions are false
12. }

Flowchart of else-if ladder statement in C

27
The example of an if-else-if statement in C language is given below.

1. #include<stdio.h>
2. int main(){
3. int number=0;
4. printf("enter a number:");
5. scanf("%d",&number);
6. if(number==10){
7. printf("number is equals to 10");
8. }
9. else if(number==50){
10. printf("number is equal to 50");
11. }
12. else if(number==100){
13. printf("number is equal to 100");
14. }
15. else{
16. printf("number is not equal to 10, 50 or 100");
17. }
18. return 0;
19. }

28
Output

enter a number:4
number is not equal to 10, 50 or 100
enter a number:50
number is equal to 50

Program to calculate the grade of the student according to the specified marks.
1. #include <stdio.h>
2. int main()
3. {
4. int marks;
5. printf("Enter your marks?");
6. scanf("%d",&marks);
7. if(marks > 85 && marks <= 100)
8. {
9. printf("Congrats ! you scored grade A ...");
10. }
11. else if (marks > 60 && marks <= 85)
12. {
13. printf("You scored grade B + ...");
14. }
15. else if (marks > 40 && marks <= 60)
16. {
17. printf("You scored grade B ...");
18. }
19. else if (marks > 30 && marks <= 40)
20. {
21. printf("You scored grade C ...");
22. }
23. else
24. {
25. printf("Sorry you are fail ...");
26. }
27. }

29
The syntax of switch statement in c language is given below:

1. switch(expression){
2. case value1:
3. //code to be executed;
4. break; //optional
5. case value2:
6. //code to be executed;
7. break; //optional
8. ......
9.
10. default:
11. code to be executed if all cases are not matched;
12. }

Rules for switch statement in C language

1) The switch expression must be of an integer or character type.

2) The case value must be an integer or character constant.

3) The case value can be used only inside the switch statement.

4) The break statement in switch case is not must. It is optional. If there is no break
statement found in the case, all the cases will be executed present after the matched
case. It is known as fall through the state of C switch statement.

Let's try to understand it by the examples. We are assuming that there are following
variables.

1. int x,y,z;
2. char a,b;
3. float f;

30
Flowchart of switch statement in C

Functioning of switch case statement

First, the integer expression specified in the switch statement is evaluated. This value is
then matched one by one with the constant values given in the different cases. If a
match is found, then all the statements specified in that case are executed along with
the all the cases present after that case including the default statement. No two cases
can have similar values. If the matched case contains a break statement, then all the
cases present after that will be skipped, and the control comes out of the switch.
Otherwise, all the cases following the matched case will be executed.

Let's see a simple example of c language switch statement.

1. #include<stdio.h>
2. int main(){
3. int number=0;
4. printf("enter a number:");
5. scanf("%d",&number);
6. switch(number){
7. case 10:
8. printf("number is equals to 10");

31
9. break;
10. case 50:
11. printf("number is equal to 50");
12. break;
13. case 100:
14. printf("number is equal to 100");
15. break;
16. default:
17. printf("number is not equal to 10, 50 or 100");
18. }
19. return 0;
20. }

Output

enter a number:4
number is not equal to 10, 50 or 100
enter a number:50
number is equal to 50

Switch case example 2


1. #include <stdio.h>
2. int main()
3. {
4. int x = 10, y = 5;
5. switch(x>y && x+y>0)
6. {
7. case 1:
8. printf("hi");
9. break;
10. case 0:
11. printf("bye");
12. break;
13. default:
14. printf(" Hello bye ");

32
15. }
16.
17. }

Output

hi

C Switch statement is fall-through

In C language, the switch statement is fall through; it means if you don't use a break
statement in the switch case, all the cases after the matching case will be executed.

Let's try to understand the fall through state of switch statement by the example given
below.

1. #include<stdio.h>
2. int main(){
3. int number=0;
4.
5. printf("enter a number:");
6. scanf("%d",&number);
7.
8. switch(number){
9. case 10:
10. printf("number is equal to 10\n");
11. case 50:
12. printf("number is equal to 50\n");
13. case 100:
14. printf("number is equal to 100\n");
15. default:
16. printf("number is not equal to 10, 50 or 100");
17. }
18. return 0;
19. }

Output

33
enter a number:10
number is equal to 10
number is equal to 50
number is equal to 100
number is not equal to 10, 50 or 100

Output

enter a number:50
number is equal to 50
number is equal to 100
number is not equal to 10, 50 or 100

Nested switch case statement

We can use as many switch statement as we want inside a switch statement. Such type
of statements is called nested switch case statements. Consider the following example.

1. #include <stdio.h>
2. int main () {
3.
4. int i = 10;
5. int j = 20;
6.
7. switch(i) {
8.
9. case 10:
10. printf("the value of i evaluated in outer switch: %d\n",i);
11. case 20:
12. switch(j) {
13. case 20:
14. printf("The value of j evaluated in nested switch: %d\n",j);
15. }
16. }
17.
18. printf("Exact value of i is : %d\n", i );
19. printf("Exact value of j is : %d\n", j );

34
20.
21. return 0;
22. }

Output

the value of i evaluated in outer switch: 10


The value of j evaluated in nested switch: 20
Exact value of i is : 10
Exact value of j is : 20

35
Unit -2

Array

An array is defined as the collection of similar type of data items stored at contiguous
memory locations. Arrays are the derived data type in C programming language which
can store the primitive type of data such as int, char, double, float, etc. It also has the
capability to store the collection of derived data types, such as pointers, structure, etc.
The array is the simplest data structure where each data element can be randomly
accessed by using its index number.

C array is beneficial if you have to store similar elements. For example, if we want to
store the marks of a student in 6 subjects, then we don't need to define different
variables for the marks in the different subject. Instead of that, we can define an array
which can store the marks in each subject at the contiguous memory locations.

By using the array, we can access the elements easily. Only a few lines of code are
required to access the elements of the array.

Properties of Array

The array contains the following properties.Features of Java - Javatpoint

o Each element of an array is of same data type and carries the same size, i.e., int =
4 bytes.
o Elements of the array are stored at contiguous memory locations where the first
element is stored at the smallest memory location.
o Elements of the array can be randomly accessed since we can calculate the
address of each element of the array with the given base address and the size of
the data element.

Advantage of C Array

1) Code Optimization: Less code to the access the data.

2) Ease of traversing: By using the for loop, we can retrieve the elements of an array
easily.

3) Ease of sorting: To sort the elements of the array, we need a few lines of code only.

36
4) Random Access: We can access any element randomly using the array.

Disadvantage of C Array

1) Fixed Size: Whatever size, we define at the time of declaration of the array, we can't
exceed the limit. So, it doesn't grow the size dynamically like LinkedList which we will
learn later.

Declaration of C Array

We can declare an array in the c language in the following way.

data_type array_name[array_size];

Now, let us see the example to declare the array.

1. int marks[5];

Here, int is the data_type, marks are the array_name, and 5 is the array_size.

Initialization of C Array

The simplest way to initialize an array is by using the index of each element. We can
initialize each element of the array by using the index. Consider the following example.

1. marks[0]=80;//initialization of array
2. marks[1]=60;
3. marks[2]=70;
4. marks[3]=85;
5. marks[4]=75;

C array example
1. #include<stdio.h>

37
2. int main(){
3. int i=0;
4. int marks[5];//declaration of array
5. marks[0]=80;//initialization of array
6. marks[1]=60;
7. marks[2]=70;
8. marks[3]=85;
9. marks[4]=75;
10. //traversal of array
11. for(i=0;i<5;i++){
12. printf("%d \n",marks[i]);
13. }//end of for loop
14. return 0;
15. }

Output

80
60
70
85
75

C Array: Declaration with Initialization

We can initialize the c array at the time of declaration. Let's see the code.

int marks[5]={20,30,40,50,60};

In such case, there is no requirement to define the size. So it may also be written as
the following code.

1. int marks[]={20,30,40,50,60};

Let's see the C program to declare and initialize the array in C.

38
Two Dimensional Array in C

The two-dimensional array can be defined as an array of arrays. The 2D array is


organized as matrices which can be represented as the collection of rows and columns.
However, 2D arrays are created to implement a relational database lookalike data
structure. It provides ease of holding the bulk of data at once which can be passed to
any number of functions wherever required.

Declaration of two dimensional Array in C

The syntax to declare the 2D array is given below.

1. data_type array_name[rows][columns];

Consider the following example.

1. int twodimen[4][3];

Here, 4 is the number of rows, and 3 is the number of columns.

Initialization of 2D Array in C

In the 1D array, we don't need to specify the size of the array if the declaration and
initialization are being done simultaneously. However, this will not work with 2D arrays.
We will have to define at least the second dimension of the array. The two-dimensional
array can be declared and defined in the following way.

1. int arr[4][3]={{1,2,3},{2,3,4},{3,4,5},{4,5,6}};

Two-dimensional array example in C


1. #include<stdio.h>
2. int main(){
3. int i=0,j=0;
4. int arr[4][3]={{1,2,3},{2,3,4},{3,4,5},{4,5,6}};
5. //traversing 2D array
6. for(i=0;i<4;i++){
7. for(j=0;j<3;j++){
8. printf("arr[%d] [%d] = %d \n",i,j,arr[i][j]);
9. }//end of j

39
10. }//end of i
11. return 0;
12. }

Output

arr[0][0] = 1
arr[0][1] = 2
arr[0][2] = 3
arr[1][0] = 2
arr[1][1] = 3
arr[1][2] = 4
arr[2][0] = 3
arr[2][1] = 4
arr[2][2] = 5
arr[3][0] = 4
arr[3][1] = 5
arr[3][2] = 6

C 2D array example: Storing elements in a matrix and printing it.


1. #include <stdio.h>
2. void main ()
3. {
4. int arr[3][3],i,j;
5. for (i=0;i<3;i++)
6. {
7. for (j=0;j<3;j++)
8. {
9. printf("Enter a[%d][%d]: ",i,j);
10. scanf("%d",&arr[i][j]);
11. }
12. }
13. printf("\n printing the elements ....\n");
14. for(i=0;i<3;i++)
15. {
16. printf("\n");
17. for (j=0;j<3;j++)

40
18. {
19. printf("%d\t",arr[i][j]);
20. }
21. }
22. }

Output

Enter a[0][0]: 56
Enter a[0][1]: 10
Enter a[0][2]: 30
Enter a[1][0]: 34
Enter a[1][1]: 21
Enter a[1][2]: 34

Enter a[2][0]: 45
Enter a[2][1]: 56
Enter a[2][2]: 78

printing the elements ....

56 10 30
34 21 34
45 56 78

C Strings

The string can be defined as the one-dimensional array of characters terminated by a


null ('\0'). The character array or the string is used to manipulate text such as word or
sentences. Each character in the array occupies one byte of memory, and the last
character must always be 0. The termination character ('\0') is important in a string since
it is the only way to identify where the string ends. When we define a string as char
s[10], the character s[10] is implicitly initialized with the null in the memory.

There are two ways to declare a string in c language.

1. By char array
2. By string literal

41
Let's see the example of declaring string by char array in C language.

1. char ch[10]={'j', 'a', 'v', 'a', 't', 'p', 'o', 'i', 'n', 't', '\0'};

As we know, array index starts from 0, so it will be represented as in the figure given
below.OOPs Concepts in Java

While declaring string, size is not mandatory. So we can write the above code as given
below:

1. char ch[]={'j', 'a', 'v', 'a', 't', 'p', 'o', 'i', 'n', 't', '\0'};

We can also define the string by the string literal in C language. For example:

1. char ch[]="javatpoint";

In such case, '\0' will be appended at the end of the string by the compiler.

string manipulation function in C


String-manipulation functions accept arguments of type CHAR, NCHAR, VARCHAR,
NVARCHAR, or LVARCHAR. You can use a string-manipulation function anywhere you
use an expression. The following functions convert between upper and lowercase letters
in a character string: LOWER. UPPER.

Character Array in Java

Character Array in Java is an Array that holds character data types values. In Java
programming, unlike C, a character array is different from a string array, and neither a
string nor a character array can be terminated by the NUL character.

The Java language uses UTF-16 representation in a character array, string, and
StringBuffer classes.

The Character arrays are very advantageous in Java. They are very efficient and faster.
Also, the data can be manipulated without any allocations.

42
Java Strings are immutable means we can not change their internal state once they are
created. However, char arrays allow us to manipulate after the creation. Even data
structures List and Set are also acceptable.

Three-Dimensional Array

Initializing Three-Dimensional Array: Initialization in a Three-Dimensional array is


the same as that of Two-dimensional arrays. The difference is as the number of
dimensions increases so the number of nested braces will also increase.
Method 1:

int x[2][3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,


11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23};
Better Method:

int x[2][3][4] =
{
{ {0,1,2,3}, {4,5,6,7}, {8,9,10,11} },
{ {12,13,14,15}, {16,17,18,19}, {20,21,22,23} }
};
Accessing elements in Three-Dimensional Arrays: Accessing elements in Three-
Dimensional Arrays is also similar to that of Two-Dimensional Arrays. The difference is
we have to use three loops instead of two loops for one additional dimension in

43
Three-dimensional Arrays.

 CPP

// C++ program to print elements of Three-Dimensional

// Array

#include<iostream>

using namespace std;

int main()

// initializing the 3-dimensional array

int x[2][3][2] =

{ {0,1}, {2,3}, {4,5} },

{ {6,7}, {8,9}, {10,11} }

};

// output each element's value

for (int i = 0; i < 2; ++i)

44
{

for (int j = 0; j < 3; ++j)

for (int k = 0; k < 2; ++k)

cout << "Element at x[" << i << "][" << j

<< "][" << k << "] = " << x[i][j][k]

<< endl;

return 0;

Output:

Element at x[0][0][0] = 0
Element at x[0][0][1] = 1
Element at x[0][1][0] = 2
Element at x[0][1][1] = 3

45
Element at x[0][2][0] = 4
Element at x[0][2][1] = 5
Element at x[1][0][0] = 6
Element at x[1][0][1] = 7
Element at x[1][1][0] = 8
Element at x[1][1][1] = 9
Element at x[1][2][0] = 10
Element at x[1][2][1] = 11
In similar ways, we can create arrays with any number of dimensions. However, the
complexity also increases as the number of dimensions increases.
The most used multidimensional array is the Two-Dimensional Array.

String Handling Functions In C Language

1) strlen( ) Function :

strlen( ) function is used to find the length of a character string.

Example: int n;

char st[20] = “Bangalore”;

n = strlen(st);

• This will return the length of the string 9 which is assigned to an integer variable n.

• Note that the null character “\0‟ available at the end of a string is not counted.

2) strcpy( ) Function :

strcpy( ) function copies contents of one string into another string. Syntax for strcpy
function is given below.

46
Syntax: char * strcpy (char * destination, const char * source);

Example:

strcpy ( str1, str2) – It copies contents of str2 into str1.

strcpy ( str2, str1) – It copies contents of str1 into str2.

If destination string length is less than source string, entire source string value won’t be
copied into destination string.

For example, consider destination string length is 20 and source string length is 30.
Then, only 20 characters from source string will be copied into destination string and
remaining 10 characters won’t be copied and will be truncated.

Example : char city[15];

strcpy(city, “BANGALORE”) ;

This will assign the string “BANGALORE” to the character variable city.

3) strcat( ) Function :

strcat( ) function in C language concatenates two given strings. It concatenates source


string at the end of destination string. Syntax for strcat( ) function is given below.

Syntax : char * strcat ( char * destination, const char * source );

47
Example :

strcat ( str2, str1 ); - str1 is concatenated at the end of str2.

strcat ( str1, str2 ); - str2 is concatenated at the end of str1.

• As you know, each string in C is ended up with null character (‘\0′).

• In strcat( ) operation, null character of destination string is overwritten by source


string’s first character and null character is added at the end of new destination string
which is created after strcat( ) operation.

Program : The following program is an example of strcat() function

#include <stdio.h>

#include <string.h>

int main( )

char source[ ] = “ ftl” ;

char target[ ]= “ welcome to” ;

printf (“\n Source string = %s”, source ) ;

printf ( “\n Target string = %s”, target ) ;

strcat ( target, source ) ;

printf ( “\n Target string after strcat( ) = %s”, target ) ;

Output :

Source string = ftl

48
Target string = welcome to

Target string after strcat() = welcome to ftl

4) Strncat() function :

strncat( ) function in C language concatenates (appends) portion of one string at the


end of another string.

Syntax : char * strncat ( char * destination, const char * source, size_t num );

Example :

strncat ( str2, str1, 3 ); – First 3 characters of str1 is concatenated at the end of str2.

strncat ( str1, str2, 3 ); - First 3 characters of str2 is concatenated at the end of str1.

As you know, each string in C is ended up with null character (‘\0′).

In strncat( ) operation, null character of destination string is overwritten by source


string’s first character and null character is added at the end of new destination string
which is created after strncat( ) operation.

Program : The following program is an example of strncat() function

#include <stdio.h>

#include <string.h>

int main( )

char source[ ] =”" ftl” ;

char target[ ]= “welcome to” ;

printf ( “\n Source string = %s”, source ) ;

printf ( “\n Target string = %s”, target ) ;

strncat ( target, source, 3 ) ;

49
printf ( "”\n Target string after strncat( ) = %s”, target ) ;

Output :

Source string = ftl

Target string = welcome to

Target string after strncat()= welcome to ft

5) strcmp( ) Function :

strcmp( ) function in C compares two given strings and returns zero if they are same. If
length of string1 < string2, it returns < 0 value. If length of string1 > string2, it returns >
0 value.

Syntax : int strcmp ( const char * str1, const char * str2 );

strcmp( ) function is case sensitive. i.e., “A” and “a” are treated as different characters.

Example :

char city[20] = “Madras”;

char town[20] = “Mangalore”;

strcmp(city, town);

This will return an integer value “-10‟ which is the difference in the ASCII values of the
first mismatching letters “D‟ and “N‟.

* Note that the integer value obtained as the difference may be assigned to an integer
variable as follows:

int n;

n = strcmp(city, town);

6) strcmpi() function :

50
strcmpi( ) function in C is same as strcmp() function. But, strcmpi( ) function is not case
sensitive. i.e., “A” and “a” are treated as same characters. Whereas, strcmp() function
treats “A” and “a” as different characters.

• strcmpi() function is non standard function which may not available in standard library.

• Both functions compare two given strings and returns zero if they are same.

• If length of string1 < string2, it returns < 0 value. If length of string1 > string2, it
returns > 0 value.

strcmp( ) function is case sensitive. i.e., “A” and “a” are treated as different characters.

Syntax : int strcmpi ( const char * str1, const char * str2 );

Example :

m = 0. m=strcmpi(“ DELHI ”, “ delhi ”);

7) strlwr() function :

strlwr() function converts a given string into lowercase.

Syntax : char *strlwr(char *string);

strlwr() function is non standard function which may not available in standard library in
C.

Program : In this program, string ”MODIFY This String To LOwer” is converted into
lower case using strlwr( ) function and result is displayed as “modify this string to lower”.

#include<stdio.h>

#include<string.h>

int main()

char str[ ] = “MODIFY This String To Lower”;

printf(“%s\n”, strlwr (str));

return 0;

51
}

Output :

modify this string to lower

8) strupr() function :

strupr() function converts a given string into uppercase.

Syntax : char *strupr(char *string);

strupr() function is non standard function which may not available in standard library in
C.

Program : In this program, string ”Modify This String To Upper” is converted into
uppercase using strupr( ) function and result is displayed as “MODIFY THIS STRING TO
UPPER”.

#include<stdio.h>

#include<string.h>

int main()

char str[ ] = “Modify This String To Upper”;

printf(“%s\n”, strupr(str));

return 0;

Output :

MODIFY THIS STRING TO UPPER

9) strrev() function :

strrev() function reverses a given string in C language.

Syntax : char *strrev(char *string);

52
strrev() function is non standard function which may not available in standard library in
C.

Example :

char name[20]=”ftl”; then

strrev(name)= ltf

Program : In below program, string “Hello” is reversed using strrev( ) function and
output is displayed as “olleH”.

#include<stdio.h>

#include<string.h>

int main()

char name[30] = “Hello”;

printf(“String before strrev( ) : %s\n”, name);

printf(“String after strrev( ) : %s”, strrev(name));

return 0;

Output :

String before strrev( ) : Hello

String after strrev( ) : olleH

10) strchr() function :

strchr() function returns pointer to the first occurrence of the character in a given string.

Syntax : char *strchr(const char *str, int character);

53
Program : In this program, strchr( ) function is used to locate first occurrence of the
character ‘i’ in the string ”This is a string ”. Character ‘i’ is located at position 3 and
pointer is returned at first occurrence of the character ‘i’.

#include <stdio.h>

#include <string.h>

int main ()

char string[25] =”This is a string “;

char *p;

p = strchr (string,'i');

printf (“Character i is found at position %d\n”,p-string+1);

printf (“First occurrence of character \”i\” in \”%s\” is” \” \”%s\””,string, p);

return 0;

Output :

Character i is found at position 3

First occurrence of character “i” in “This is a string” is “is is a string”

11) strstr() function :

strstr( ) function returns pointer to the first occurrence of the string in a given string.

Syntax : char *strstr(const char *str1, const char *str2);

Program : In this program, strstr( ) function is used to locate first occurrence of the
string “test” in the string ”This is a test string for testing”. Pointer is returned at first
occurrence of the string “test”.

54
#include <stdio.h>

#include <string.h>

int main( )

char string[55] =”This is a test string for testing”;

char *p;

p = strstr (string, ”test”);

if(p)

printf(“string found\n” );

printf (“First occurrence of string \”test\” in \”%s\” is”\” \”%s\””,string, p);

else printf(“string not found\n” );

return 0;

Output :

String found

First occurrence of ”test” in “this is a test string for testing” is “testing string for testing”

12) atoi() function :

It converts string-value to numeric-value and it converts a numeric-string value to


equivalent integer-value.

Syntax : int atoi(string);

Example :

55
printf(“output=%d”, atoi(“123”)+atoi(“234”));

This printf() will print 357

13) atol() function :

converts a long int string value to equivalent long integer value.

Syntax : long int atol(string);

Example :

printf(“output=%d”, atol(“486384”)-atol(“112233”));

This statement will print 374151

14) atof() function :

converts a floating point text format value to double value.

Syntax : int atoi(string);

Example :

printf(“%1f”,atof(“3.1412”)*5*5);

This statement will print 78.530000

15) itoa(),ltoa(),ultoa() :

These functions converts a given number(int/long int/unsigned long int) to equivalent


text 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.

Syntax : char* itoa(int value, char *targetstringaddress, int radix );

Example :

Char temp[50];

Printf(“output=%s”, itoa(45,temp,2));

56
Output : 101101

Program : Write a C program to count the number of vowels present in a sentence.

# include<stdio.h>

# include<conio.h>

# include<string.h>

main( )

char st[80], ch;

int count = 0, i;

clrscr( );

printf(“ \n Enter the sentence: \n”);

gets(st);

for( i=0; i<strlen(st); i++)

switch(st [i ])

case ‘A’:

case ‘E’:

case ‘I’:

case ‘O’:

case ‘U’:

case ‘a’:

case ‘e’:

case ‘I’:

57
case ‘o’:

case ‘u’:

count ++;

break;

printf(“\n %d vowels are present in the sentence”, count);

getch( );

• When this program is executed, the user has to enter the sentence.

• Note that gets( ) function is used to read the sentence because the string has white
spaces between the words.

• The vowels are counted using a switch statement in a loop.

• Note that a count++ statement is given only once to execute it for the cases in the
switch statement.

Output :

Enter the sentence :

This is a book

5 vowels are present in the sentence.

Functions

In c, we can divide a large program into the basic building blocks known as function.
The function contains the set of programming statements enclosed by {}. A function can
be called multiple times to provide reusability and modularity to the C program. In other
words, we can say that the collection of functions creates a program. The function is also
known as procedureor subroutinein other programming languages.

Advantage of functions in C

58
There are the following advantages of C functions.

o By using functions, we can avoid rewriting same logic/code again and again in a
program.
o We can call C functions any number of times in a program and from any place in
a program.
o We can track a large C program easily when it is divided into multiple functions.
o Reusability is the main achievement of C functions.
o However, Function calling is always a overhead in a C program.

Function Aspects

There are three aspects of a C function.

o Function declaration A function must be declared globally in a c program to tell


the compiler about the function name, function parameters, and return type.

o Function call Function can be called from anywhere in the program. The
parameter list must not differ in function calling and function declaration. We
must pass the same number of functions as it is declared in the function
declaration.

o Function definition It contains the actual statements which are to be executed. It


is the most important aspect to which the control comes when the function is
called. Here, we must notice that only one value can be returned from the
function.

SN C function Syntax
aspects

1 Function return_type function_name (argument list);


declaration

59
2 Function call function_name (argument_list)

The 3 Function return_type function_name (argument list)


definition {function body;}

syntax of creating function in c language is given below2.6M599Prime Ministers of Iiaist


oe Minister of India (1947-2020)

1. return_type function_name(data_type parameter...){


2. //code to be executed
3. }

Types of Functions

There are two types of functions in C programming:

1. Library Functions: are the functions which are declared in the C header files such
as scanf(), printf(), gets(), puts(), ceil(), floor() etc.
2. User-defined functions: are the functions which are created by the C
programmer, so that he/she can use it many times. It reduces the complexity of a
big program and optimizes the code.

Return Value

A C function may or may not return a value from the function. If you don't have to
return any value from the function, use void for the return type.

Let's see a simple example of C function that doesn't return any value from the function.

60
Example without return value:

1. void hello(){
2. printf("hello c");
3. }

If you want to return any value from the function, you need to use any data type such as
int, long, char, etc. The return type depends on the value to be returned from the
function.

Let's see a simple example of C function that returns int value from the function.

Example with return value:

1. int get(){
2. return 10;
3. }

In the above example, we have to return 10 as a value, so the return type is int. If you
want to return floating-point value (e.g., 10.2, 3.1, 54.5, etc), you need to use float as the
return type of the method.

1. float get(){
2. return 10.2;
3. }

Now, you need to call the function, to get the value of the function.

categories of functions in C
Depending on whether arguments are present or not and whether a value is returned or
not, functions are categorized into −

 Functions without arguments and without return values

 Functions without arguments and with return values

 Functions with arguments and without return values

 Functions with arguments and with return values

Functions without arguments and without return values

61
Example
#include<stdio.h>
main (){
void sum ();
clrscr ();
sum ();
getch ();
}
void sum (){
int a,b,c;
printf("enter 2 numbers:\n");
scanf ("%d%d", &a, &b);
c = a+b;
printf("sum = %d",c);
}
Output
Enter 2 numbers:
3
5
Sum=8
Functions without arguments and with return values

62
Example
#include<stdio.h>
main (){
int sum ();
int c;
c= sum ();
printf(“sum = %d”,c);
getch ();
}
int sum (){
int a,b,c;
printf(“enter 2 numbers”);
scanf (“%d%d”, &a, &b);
c = a+b;
return c;
}
Output
Enter two numbers 10 20
30

63
Functions with arguments and without return values

Example
#include<stdio.h>
main (){
void sum (int, int );
int a,b;
printf("enter 2 numbers");
scanf("%d%d", &a,&b);
sum (a,b);
getch ();
}
void sum ( int a, int b){
int c;
c= a+b;
printf (“sum=%d”, c);
}
Output
Enter two numbers 10 20
Sum=30

64
Functions with arguments and with return values

Example
#include<stdio.h>
main (){
int sum ( int,int);
int a,b,c;
printf("enter 2 numbers");
scanf("%d%d", &a,&b);
c= sum (a,b);
printf ("sum=%d", c);
getch ();
}
int sum ( int a, int b ){
int c;
c= a+b;
return c;
}
Output
Enter two numbers 10 20

65
Sum=30

C Function Parameters
Parameters and Arguments

Information can be passed to functions as a parameter. Parameters act as variables


inside the function.

Parameters are specified after the function name, inside the parentheses. You can add as
many parameters as you want, just separate them with a comma:

Syntax

returnType functionName(parameter1, parameter2, parameter3) {


// code to be executed
}

The following function that takes a string of characters with name as parameter. When
the function is called, we pass along a name, which is used inside the function to print
"Hello" and the name of each person.

Example

void myFunction(char name[]) {


printf("Hello %s\n", name);
}

int main() {
myFunction("Liam");
myFunction("Jenny");
myFunction("Anja");
return 0;
}

// Hello Liam
// Hello Jenny
// Hello Anja

66
When a parameter is passed to the function, it is called an argument. So, from the
example above: name is a parameter, while Liam, Jenny and Anja are arguments.

Multiple Parameters

Inside the function, you can add as many parameters as you want:

Example

void myFunction(char name[], int age) {


printf("Hello %s. You are %d years old.\n", name, age);
}

int main() {
myFunction("Liam", 3);
myFunction("Jenny", 14);
myFunction("Anja", 30);
return 0;
}

// Hello Liam. You are 3 years old.


// Hello Jenny. You are 14 years old.
// Hello Anja. You are 30 years old.

Return Values

The void keyword, used in the previous examples, indicates that the function should not
return a value. If you want the function to return a value, you can use a data type (such
as int or float, etc.) instead of void, and use the return keyword inside the function:

Example

int myFunction(int x) {
return 5 + x;
}

int main() {
printf("Result is: %d", myFunction(3));

67
return 0;
}

// Outputs 8 (5 + 3)

Parameter Passing in C
When a function gets executed in the program, the execution control is transferred from

calling-function to called function and executes function definition, and finally comes

back to the calling function. When the execution control is transferred from calling-

function to called-function it may carry one or number of data values. These data values

are called as parameters.

Parameters are the data values that are passed from calling function to called

function.

In C, there are two types of parameters and they are as follows...

 Actual Parameters

 Formal Parameters

The actual parameters are the parameters that are speficified in calling function.

The formal parameters are the parameters that are declared at called function. When a

function gets executed, the copy of actual parameter values are copied into formal

parameters.

In C Programming Language, there are two methods to pass parameters from calling

function to called function and they are as follows...

 Call by Value

 Call by Reference

Call by Value

68
In call by value parameter passing method, the copy of actual parameter values are

copied to formal parameters and these formal parameters are used in called

function. The changes made on the formal parameters does not effect the values of

actual parameters. That means, after the execution control comes back to the calling

function, the actual parameter values remains same. For example consider the following

program...
Example Program
#include<stdio.h>
#include<conio.h>

void main(){
int num1, num2 ;
void swap(int,int) ; // function declaration
clrscr() ;
num1 = 10 ;
num2 = 20 ;

printf("\nBefore swap: num1 = %d, num2 = %d", num1, num2) ;

swap(num1, num2) ; // calling function

printf("\nAfter swap: num1 = %d\nnum2 = %d", num1, num2);


getch() ;
}
void swap(int a, int b) // called function
{
int temp ;

69
temp = a ;
a=b;
b = temp ;
}

Output:

In the above example program, the variables num1 and num2 are called actual

parameters and the variables a and b are called formal parameters. The value

of num1 is copied into a and the value of num2 is copied into b. The changes made on

variables a and b does not effect the values of num1 and num2.

Call by Reference

In Call by Reference parameter passing method, the memory location address of the

actual parameters is copied to formal parameters. This address is used to access the

memory locations of the actual parameters in called function. In this method of

parameter passing, the formal parameters must be pointer variables.

That means in call by reference parameter passing method, the address of the actual

parameters is passed to the called function and is recieved by the formal parameters

(pointers). Whenever we use these formal parameters in called function, they directly

access the memory locations of actual parameters. So the changes made on the

formal parameters effects the values of actual parameters. For example consider the

following program...

70
Example Program
#include<stdio.h>
#include<conio.h>

void main(){
int num1, num2 ;
void swap(int *,int *) ; // function declaration
clrscr() ;
num1 = 10 ;
num2 = 20 ;

printf("\nBefore swap: num1 = %d, num2 = %d", num1, num2) ;


swap(&num1, &num2) ; // calling function

printf("\nAfter swap: num1 = %d, num2 = %d", num1, num2);


getch() ;
}
void swap(int *a, int *b) // called function
{
int temp ;
temp = *a ;
*a = *b ;
*b = temp ;
}

Output:

71
In the above example program, the addresses of variables num1 and num2 are copied

to pointer variables a and b. The changes made on the pointer variables a and b in

called function effects the values of actual parameters num1 and num2 in calling

function.
Scope rules
Scope of an identifier is the part of the program where the identifier may directly be
accessible. In C, all identifiers are lexically(or statically) scoped. C scope rules can be
covered under the following two categories.
There are basically 4 scope rules:

Scope Meaning

Scope of a Identifier starts at the beginning of the file and ends at the
end of the file. It refers to only those Identifiers that are declared
outside of all functions. The Identifiers of File scope are visible all over
File Scope the file Identifiers having file scope are global

Scope of a Identifier begins at opening of the block / ‘{‘ and ends at the
Block Scope end of the block / ‘}’. Identifiers with block scope are local to their block

Function
Prototype Identifiers declared in function prototype are visible within the
Scope prototype

Function Function scope begins at the opening of the function and ends with the

72
Scope Meaning

scope closing of it. Function scope is applicable to labels only. A label


declared is used as a target to goto statement and both goto and label
statement must be in same function

Let’s discuss each scope rules with examples.


File Scope: These variables are usually declared outside of all of the functions and
blocks, at the top of the program and can be accessed from any portion of the program.
These are also called the global scope variables as they can be globally accessed.
Block Scope: A Block is a set of statements enclosed within left and right braces i.e. ‘{‘
and ‘}’ respectively. Blocks may be nested in C(a block may contain other blocks inside
it). A variable declared inside a block is accessible in the block and all inner blocks of
that block, but not accessible outside the block. Basically these are local to the blocks in
which the variables are defined and are not accessible outside.
Function Prototype Scope: These variables range includes within the function
parameter list. The scope of the these variables begins right after the declaration in the
function prototype and runs to the end of the declarations list. These scopes don’t
include the function definition, but just the function prototype.
Function Scope: A Function scope begins at the opening of the function and ends with
the closing of it. Function scope is applicable to labels only. A label declared is used as a
target to go to the statement and both goto and label statement must be in the same
function.
Block Structure
A block is a statement containing its own local data declaration. The concept of a block
is originated with ALGOL. The block-structured language permits an array with
adjustable length. The main feature of blocks is their bracketing structure (begin and
end used in ALGOL) in which they can define their data. In 'C' language, the syntax of
the block is −

{
declaration statements;
}
where the braces limit the block. The characteristic of a block is its nesting structure.
Delimiters mark the starting and end of the block. In 'C' language, the braces { } act as

73
delimiters, while ALGOL uses begin and end. Delimiter ensures that the block is
independent of one another or is nested inside the other. The nesting property is
sometimes referred to as a block structure.

The most closely nested rule gives the scope of declaration −

 The scope of a declaration in Block B contains B.


 If a name x is used in block B but is not declared in B then using a declaration of x
in an enclosing block B is in the scope of a declaration of x in an enclosing block
B′ such that
o B′ has a declaration of x and
o B′ is more closely nested around B than any other block with the
declaration of x.
Consider a C program −

The execution of the above block structure program using stack can be shown in the
following way −

Storage Classes in C

Storage classes in C are used to determine the lifetime, visibility, memory location, and
initial value of a variable. There are four types of storage classes in C

74
Automatic

External

Static

Register

Automatic

Automatic variables are allocated memory automatically at runtime.

The visibility of the automatic variables is limited to the block in which they are defined.

The scope of the automatic variables is limited to the block in which they are defined.

The automatic variables are initialized to garbage by default.

The memory assigned to automatic variables gets freed upon exiting from the block.

The keyword used for defining automatic variables is auto.

Every local variable is automatic in C by default.

Example 1

#include <stdio.h>

int main()

int a; //auto

char b;

float c;

printf("%d %c %f",a,b,c); // printing initial default value of automatic variables a, b, and c.

return 0;

75
Output:

garbage garbage garbage

Static

The variables defined as static specifier can hold their value between the multiple
function calls.

Static local variables are visible only to the function or the block in which they are
defined.

A same static variable can be declared many times but can be assigned at only one time.

Default initial value of the static integral variable is 0 otherwise null.

The visibility of the static global variable is limited to the file in which it has declared.

The keyword used to define static variable is static.

Example 1

#include<stdio.h>

static char c;

static int i;

static float f;

static char s[100];

void main ()

printf("%d %d %f %s",c,i,f); // the initial default value of c, i, and f will be printed.

Output:

0 0 0.000000 (null)

76
Register

The variables defined as the register is allocated the memory into the CPU registers
depending upon the size of the memory remaining in the CPU.

We can not dereference the register variables, i.e., we can not use &operator for the
register variable.

The access time of the register variables is faster than the automatic variables.

The initial default value of the register local variables is 0.

The register keyword is used for the variable which should be stored in the CPU register.
However, it is compiler?s choice whether or not; the variables can be stored in the
register.

We can store pointers into the register, i.e., a register can store the address of a variable.

Static variables can not be stored into the register since we can not use more than one
storage specifier for the same variable.

Example 1

#include <stdio.h>

int main()

register int a; // variable a is allocated memory in the CPU register. The initial default
value of a is 0.

printf("%d",a);

Output:

77
External

The external storage class is used to tell the compiler that the variable defined as extern
is declared with an external linkage elsewhere in the program.

The variables declared as extern are not allocated any memory. It is only declaration and
intended to specify that the variable is declared elsewhere in the program.

The default initial value of external integral type is 0 otherwise null.

We can only initialize the extern variable globally, i.e., we can not initialize the external
variable within any block or method.

An external variable can be declared many times but can be initialized at only once.

If a variable is declared as external then the compiler searches for that variable to be
initialized somewhere in the program which may be extern or static. If it is not, then the
compiler will show an error.

Example 1

#include <stdio.h>

int main()

extern int a;

printf("%d",a);

Output

main.c:(.text+0x6): undefined reference to `a'

collect2: error: ld returned 1 exit status

78
Recursion in C

Recursion is the process which comes into existence when a function calls a copy of
itself to work on a smaller problem. Any function which calls itself is called recursive
function, and such function calls are called recursive calls. Recursion involves several
numbers of recursive calls. However, it is important to impose a termination condition of
recursion. Recursion code is shorter than iterative code however it is difficult to
understand.

Recursion cannot be applied to all the problem, but it is more useful for the tasks that
can be defined in terms of similar subtasks. For Example, recursion may be applied to
sorting, searching, and traversal problems.

Generally, iterative solutions are more efficient than recursion since function call is
always overhead. Any problem that can be solved recursively, can also be solved
iteratively. However, some problems are best suited to be solved by the recursion, for
example, tower of Hanoi, Fibonacci series, factorial finding, etc.

In the following example, recursion is used to calculate the factorial of a numberM

1. #include <stdio.h>
2. int fact (int);
3. int main()
4. {
5. int n,f;
6. printf("Enter the number whose factorial you want to calculate?");
7. scanf("%d",&n);
8. f = fact(n);
9. printf("factorial = %d",f);
10. }
11. int fact(int n)
12. {
13. if (n==0)
14. {
15. return 0;
16. }
17. else if ( n == 1)
18. {

79
19. return 1;
20. }
21. else
22. {
23. return n*fact(n-1);
24. }
25. }

Output
Enter the number whose factorial you want to calculate?5
factorial = 120

We can understand the above program of the recursive method call by the figure given
below:

Recursive Function

A recursive function performs the tasks by dividing it into the subtasks. There is a
termination condition defined in the function which is satisfied by some specific subtask.
After this, the recursion stops and the final result is returned from the function.

The case at which the function doesn't recur is called the base case whereas the
instances where the function keeps calling itself to perform a subtask, is called the
recursive case. All the recursive functions can be written using this format.

Pseudocode for writing any recursive function is given below

80
1. if (test_for_base)

2. {

3. return some_value;

4. }

5. else if (test_for_another_base)

6. {

7. return some_another_value;

8. }

9. else

10. {

11. // Statements;

12. recursive call;

13. }

Example of recursion in C

Let's see an example to find the nth term of the Fibonacci series.

1. #include<stdio.h>

2. int fibonacci(int);

3. void main ()

4. {

5. int n,f;

6. printf("Enter the value of n?");

7. scanf("%d",&n);

81
8. f = fibonacci(n);

9. printf("%d",f);

10. }

11. int fibonacci (int n)

12. {

13. if (n==0)

14. {

15. return 0;

16. }

17. else if (n == 1)

18. {

19. return 1;

20. }

21. else

22. {

23. return fibonacci(n-1)+fibonacci(n-2);

24. }

25. }

Output

Enter the value of n?12

144

82
Memory allocation of Recursive method

Each recursive call creates a new copy of that method in the memory. Once some data is
returned by the method, the copy is removed from the memory. Since all the variables
and other stuff declared inside function get stored in the stack, therefore a separate
stack is maintained at each recursive call. Once the value is returned from the
corresponding function, the stack gets destroyed. Recursion involves so much
complexity in resolving and tracking the values at each recursive call. Therefore we need
to maintain the stack and track the values of the variables defined in the stack.

Let us consider the following example to understand the memory allocation of the
recursive functions.

1. int display (int n)

2. {

3. if(n == 0)

4. return 0; // terminating condition

5. else

6. {

7. printf("%d",n);

8. return display(n-1); // recursive call

9. }

10. }

Explanation

Let us examine this recursive function for n = 4. First, all the stacks are maintained which
prints the corresponding value of n until n becomes 0, Once the termination condition is
reached, the stacks get destroyed one by one by returning 0 to its calling stack.
Consider the following image for more information regarding the stack trace for the
recursive functions.

83
Unit-3
C Pointers

The pointer in C language is a variable which stores the address of another variable. This
variable can be of type int, char, array, function, or any other pointer. The size of the
pointer depends on the architecture. However, in 32-bit architecture the size of a
pointer is 2 byte.

Consider the following example to define a pointer which stores the address of an
integer.

1. int n = 10;
2. int* p = &n; // Variable p of type pointer is pointing to the address of the variable n of t
ype integer.

Declaring a pointer

The pointer in c language can be declared using * (asterisk symbol). It is also known as
indirection pointer used to dereference a pointer.

1. int *a;//pointer to int


2. char *c;//pointer to char

Pointer Example

An example of using pointers to print the address and value is given below.

istory of Java

84
As you can see in the above figure, pointer variable stores the address of number
variable, i.e., fff4. The value of number variable is 50. But the address of pointer variable
p is aaa3.

By the help of * (indirection operator), we can print the value of pointer variable p.

Let's see the pointer example as explained for the above figure.

1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %x \n",p); // p contains the address of the number theref
ore printing p gives the address of number.
7. printf("Value of p variable is %d \n",*p); // As we know that * is used to dereference a po
inter therefore if we print *p, we will get the value stored at the address contained by p.

8. return 0;
9. }

Output

Address of number variable is fff4


Address of p variable is fff4
Value of p variable is 50

Pointer to array
1. int arr[10];
2. int *p[10]=&arr; // Variable p of type pointer is pointing to the address of an integer arr
ay arr.

Pointer to a function
1. void show (int);
2. void(*p)(int) = &display; // Pointer p is pointing to the address of a function

Pointer to structure
1. struct st {

85
2. int i;
3. float f;
4. }ref;
5. struct st *p = &ref;

Advantage of pointer

1) Pointer reduces the code and improves the performance, it is used to retrieving
strings, trees, etc. and used with arrays, structures, and functions.

2) We can return multiple values from a function using the pointer.

3) It makes you able to access any memory location in the computer's memory.

Usage of pointer

There are many applications of pointers in c language.

1) Dynamic memory allocation

In c language, we can dynamically allocate memory using malloc() and calloc() functions
where the pointer is used.

2) Arrays, Functions, and Structures

Pointers in c language are widely used in arrays, functions, and structures. It reduces the
code and improves the performance.

Address Of (&) Operator

The address of operator '&' returns the address of a variable. But, we need to use %u to
display the address of a variable.

1. #include<stdio.h>
2. int main(){
3. int number=50;

86
4. printf("value of number is %d, address of number is %u",number,&number);
5. return 0;
6. }

Output

value of number is 50, address of number is fff4


C Double Pointer (Pointer to Pointer)

As we know that, a pointer is used to store the address of a variable in C. Pointer


reduces the access time of a variable. However, In C, we can also define a pointer to
store the address of another pointer. Such pointer is known as a double pointer (pointer
to pointer). The first pointer is used to store the address of a variable whereas the
second pointer is used to store the address of the first pointer. Let's understand it by the
diagram given below.

The syntax of declaring a double pointer is given below.

1. int **p; // pointer to a pointer which is pointing to an integer.

Consider the following example.

1. #include<stdio.h>
2. void main ()
3. {
4. int a = 10;
5. int *p;
6. int **pp;
7. p = &a; // pointer p is pointing to the address of a
8. pp = &p; // pointer pp is a double pointer pointing to the address of pointer p
9. printf("address of a: %x\n",p); // Address of a will be printed
10. printf("address of p: %x\n",pp); // Address of p will be printed

87
11. printf("value stored at p: %d\n",*p); // value stoted at the address contained by p i.e. 1
0 will be printed
12. printf("value stored at pp: %d\n",**pp); // value stored at the address contained by th
e pointer stoyred at pp
13. }

Output
address of a: d26a8734
address of p: d26a8738
value stored at p: 10
value stored at pp: 10

void pointer in C

Till now, we have studied that the address assigned to a pointer should be of the same
type as specified in the pointer declaration. For example, if we declare the int pointer,
then this int pointer cannot point to the float variable or some other type of variable,
i.e., it can point to only int type variable. To overcome this problem, we use a pointer to
void. A pointer to void means a generic pointer that can point to any data type. We can
assign the address of any data type to the void pointer, and a void pointer can be
assigned to any type of the pointer without performing any explicit typecasting.

Syntax of void pointer


1. void *pointer name;

Declaration of the void pointer is given below:

1. void *ptr;

In the above declaration, the void is the type of the pointer, and 'ptr' is the name of the
pointer.

Function pointer as argument in C

Till now, we have seen that in C programming, we can pass the variables as an argument
to a function. We cannot pass the function as an argument to another function. But we
can pass the reference of a function as a parameter by using a function pointer. This
process is known as call by reference as the function parameter is passed as a pointer

88
that holds the address of arguments. If any change made by the function using pointers,
then it will also reflect the changes at the address of the passed variable.

Therefore, C programming allows you to create a pointer pointing to the function, which
can be further passed as an argument to the function. We can create a function pointer
as follows:

1. (type) (*pointer_name)(parameter);

In the above syntax, the type is the variable type which is returned by the
function, *pointer_name is the function pointer, and the parameter is the list of the
argument passed to the function.

Let's consider an example:

1. float (*add)(); // this is a legal declaration for the function pointer


2. float *add(); // this is an illegal declaration for the function pointer

A function pointer can also point to another function, or we can say that it holds the
address of another function.

1. float add (int a, int b); // function declaration


2. float (*a)(int, int); // declaration of a pointer to a function
3. a=add; // assigning address of add() to 'a' pointer

In the above case, we have declared a function named as 'add'. We have also declared
the function pointer (*a) which returns the floating-type value, and contains two
parameters of integer type. Now, we can assign the address of add() function to the 'a'
pointer as both are having the same return type(float), and the same type of arguments.

Now, 'a' is a pointer pointing to the add() function. We can call the add() function by
using the pointer, i.e., 'a'. Let's see how we can do that:

1. a(2, 3);

The above statement calls the add() function by using pointer 'a', and two parameters
are passed in 'a', i.e., 2 and 3.

Let's see a simple example of how we can pass the function pointer as a
parameter.

89
1. void display(void (*p)())
2. {
3. for(int i=1;i<=5;i++)
4. {
5. p(i);
6. }
7. }
8. void print_numbers(int num)
9. {
10. cout<<num;
11. }
12. int main()
13. {
14. void (*p)(int); // void function pointer declaration
15. printf("The values are :");
16. display(print_numbers);
17. return 0;
18. }

In the above code,

o We have defined two functions named 'display()' and print_numbers().


o Inside the main() method, we have declared a function pointer named as (*p), and
we call the display() function in which we pass the print_numbers() function.
o When the control goes to the display() function, then pointer *p contains the
address of print_numbers() function. It means that we can call the
print_numbers() function using function pointer *p.
o In the definition of display() function, we have defined a 'for' loop, and inside the
for loop, we call the print_numbers() function using statement p(i). Here, p(i)
means that print_numbers() function will be called on each iteration of i, and the
value of 'i' gets printed.

Output

90
Pass By Address:
We've seen Pass By Value and Pass By Reference. If you declare a formal parameter of a
function as a pointer type, you are passing that parameter by its address. The pointer is
copied, but not the data it points to. So, Pass By Address offers another method of
allowing us to change the original argument of a function (like with Pass By Reference).
Don't pass in the argument itself -- just pass in its address.

Example:

void SquareByAddress(int * n)
{ *n = (*n) * (*n); }

int main()
{
int num = 4;
cout << "Original = " << num << '\n';
SquareByAddress(&num);
cout << "New value = " << num << '\n';
}
pointers and two-dimensional array
Pointer is a variable that stores the address of another variable.

Features
 Pointer saves the memory space.

 Execution time of pointer is faster because of direct access to memory location.

91
 With the help of pointers, the memory is accessed efficiently, i.e., memory is
allocated and deallocated dynamically.

 Pointers are used with data structures.

Pointers and two dimensional arrays


Memory allocation for a two-dimensional array is as follows −

int a[3] [3] = {1,2,3,4,5,6,7,8,9};

a[1] [2] = *(1234 + 1*3+2)


= *(1234 + 3+2)
= *(1234 + 5*4) // 4 is Scale factor
= * (1234+20)
= *(1254)
a[1] [2] = 6
Example
Following is the C program for pointers and two-dimensional array −

#include<stdio.h>
main ( ){

92
int a[3] [3], i,j;
int *p;
clrscr ( );
printf ("Enter elements of 2D array");
for (i=0; i<3; i++){
for (j=0; j<3; j++){
scanf ("%d", &a[i] [j]);
}
}
p = &a[0] [0];
printf ("elements of 2d array are");
for (i=0; i<3; i++){
for (j=0; j<3; j++){
printf ("%d \t", *(p+i*3+j));
}
printf ("\n");
}
getch ( );
}
Output
When the above program is executed, it produces the following result −

enter elements of 2D array


123456789
Elements of 2D array are
123
456
789

93
Dynamic Memory Allocation in C using malloc(), calloc(), free() and
realloc()
Since C is a structured language, it has some fixed rules for programming. One of them
includes changing the size of an array. An array is a collection of items stored at
contiguous memory locations.

As it can be seen that the length (size) of the array above made is 9. But what if there is
a requirement to change this length (size). For Example,
 If there is a situation where only 5 elements are needed to be entered in this array. In
this case, the remaining 4 indices are just wasting memory in this array. So there is a
requirement to lessen the length (size) of the array from 9 to 5.
 Take another situation. In this, there is an array of 9 elements with all 9 indices filled.
But there is a need to enter 3 more elements in this array. In this case, 3 indices more
are required. So the length (size) of the array needs to be changed from 9 to 12.
This procedure is referred to as Dynamic Memory Allocation in C.
Therefore, C Dynamic Memory Allocation can be defined as a procedure in which the
size of a data structure (like Array) is changed during the runtime.
C provides some functions to achieve these tasks. There are 4 library functions provided
by C defined under <stdlib.h> header file to facilitate dynamic memory allocation in C
programming. They are:
1. malloc()
2. calloc()
3. free()
4. realloc()
Let’s look at each of them in greater detail.

C malloc() method

The “malloc” or “memory allocation” method in C is used to dynamically allocate a


single large block of memory with the specified size. It returns a pointer of type void

94
which can be cast into a pointer of any form. It doesn’t Initialize memory at execution
time so that it has initialized each block with the default garbage value initially.
Syntax:
ptr = (cast-type*) malloc(byte-size)
For Example:
ptr = (int*) malloc(100 * sizeof(int));
Since the size of int is 4 bytes, this statement will allocate 400 bytes of memory. And, the
pointer ptr holds the address of the first byte in the allocated memory.

If space is insufficient, allocation fails and returns a NULL pointer.


Example:
#include <stdio.h>

#include <stdlib.h>

int main()

// This pointer will hold the

// base address of the block created

int* ptr;

int n, i;

// Get the number of elements for the array

printf("Enter number of elements:");

scanf("%d",&n);

printf("Entered number of elements: %d\n", n);

// Dynamically allocate memory using malloc()

ptr = (int*)malloc(n * sizeof(int));

// Check if the memory has been successfully

95
// allocated by malloc or not

if (ptr == NULL) {

printf("Memory not allocated.\n");

exit(0);

else {

// Memory has been successfully allocated

printf("Memory successfully allocated using malloc.\n");

// Get the elements of the array

for (i = 0; i < n; ++i) {

ptr[i] = i + 1;

} // Print the elements of the array

printf("The elements of the array are: ");

for (i = 0; i < n; ++i) {

printf("%d, ", ptr[i]);

return 0;

}Output:

Enter number of elements: 5


Memory successfully allocated using malloc.
The elements of the array are: 1, 2, 3, 4, 5,

96
calloc() method
1. “calloc” or “contiguous allocation” method in C is used to dynamically allocate the
specified number of blocks of memory of the specified type. it is very much similar to
malloc() but has two different points and these are:
2. It initializes each block with a default value ‘0’.
3. It has two parameters or arguments as compare to malloc().
Syntax:
ptr = (cast-type*)calloc(n, element-size);
here, n is the no. of elements and element-size is the size of each element.
For Example:
ptr = (float*) calloc(25, sizeof(float));
This statement allocates contiguous space in memory for 25 elements each with the size of
the float.

If space is insufficient, allocation fails and returns a NULL pointer.


Example

#include <stdio.h>

#include <stdlib.h>

int main()

// This pointer will hold the

// base address of the block created

int* ptr;

97
int n, i;

// Get the number of elements for the array

n = 5;

printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using calloc()

ptr = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully

// allocated by calloc or not

if (ptr == NULL) {

printf("Memory not allocated.\n");

exit(0);

else {

// Memory has been successfully allocated

printf("Memory successfully allocated using calloc.\n");

// Get the elements of the array

for (i = 0; i < n; ++i) {

ptr[i] = i + 1;

// Print the elements of the array

printf("The elements of the array are: ");

for (i = 0; i < n; ++i) {

98
printf("%d, ", ptr[i]);

return 0;

}
Output:
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,

C free() method

“free” method in C is used to dynamically de-allocate the memory. The memory


allocated using functions malloc() and calloc() is not de-allocated on their own. Hence
the free() method is used, whenever the dynamic memory allocation takes place. It helps
to reduce wastage of memory by freeing it.
Syntax:
free(ptr);

Example:

#include <stdio.h>

99
#include <stdlib.h>

int main()

// This pointer will hold the

// base address of the block created

int *ptr, *ptr1;

int n, i;

// Get the number of elements for the array

n = 5;

printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using malloc()

ptr = (int*)malloc(n * sizeof(int));

// Dynamically allocate memory using calloc()

ptr1 = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully

// allocated by malloc or not

if (ptr == NULL || ptr1 == NULL) {

printf("Memory not allocated.\n");

exit(0);

else {

// Memory has been successfully allocated

100
printf("Memory successfully allocated using malloc.\n");

// Free the memory

free(ptr);

printf("Malloc Memory successfully freed.\n");

// Memory has been successfully allocated

printf("\nMemory successfully allocated using calloc.\n");

// Free the memory

free(ptr1);

printf("Calloc Memory successfully freed.\n");

return 0;

}
Output:
Enter number of elements: 5
Memory successfully allocated using malloc.
Malloc Memory successfully freed.

Memory successfully allocated using calloc.


Calloc Memory successfully freed.
C realloc() method
“realloc” or “re-allocation” method in C is used to dynamically change the memory
allocation of a previously allocated memory. In other words, if the memory previously
allocated with the help of malloc or calloc is insufficient, realloc can be used
to dynamically re-allocate memory. re-allocation of memory maintains the already
present value and new blocks will be initialized with the default garbage value.
Syntax:
ptr = realloc(ptr, newSize);

101
where ptr is reallocated with new size 'newSize'.

If space is insufficient, allocation fails and returns a NULL pointer.


Example:

#include <stdio.h>

#include <stdlib.h>

int main()

// This pointer will hold the

// base address of the block created

int* ptr;

int n, i;

// Get the number of elements for the array

n = 5;

printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using calloc()

102
ptr = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully

// allocated by malloc or not

if (ptr == NULL) {

printf("Memory not allocated.\n");

exit(0);

else {

// Memory has been successfully allocated

printf("Memory successfully allocated using calloc.\n");

// Get the elements of the array

for (i = 0; i < n; ++i) {

ptr[i] = i + 1;

// Print the elements of the array

printf("The elements of the array are: ");

for (i = 0; i < n; ++i) {

printf("%d, ", ptr[i]);

// Get the new size for the array

n = 10;

printf("\n\nEnter the new size of the array: %d\n", n);

103
// Dynamically re-allocate memory using realloc()

ptr = realloc(ptr, n * sizeof(int));

// Memory has been successfully allocated

printf("Memory successfully re-allocated using realloc.\n");

// Get the new elements of the array

for (i = 5; i < n; ++i) {

ptr[i] = i + 1;

// Print the elements of the array

printf("The elements of the array are: ");

for (i = 0; i < n; ++i) {

printf("%d, ", ptr[i]);

free(ptr);

return 0;

Output:
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,
Enter the new size of the array: 10
Memory successfully re-allocated using realloc.

104
The elements of the array are: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

Array of pointers
Before we understand the concept of arrays of pointers, let us consider the following
example, which uses an array of 3 integers −

#include <stdio.h>

const int MAX = 3;

int main () {

int var[] = {10, 100, 200};


int i;

for (i = 0; i < MAX; i++) {


printf("Value of var[%d] = %d\n", i, var[i] );
}

return 0;
}

When the above code is compiled and executed, it produces the following result −
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
There may be a situation when we want to maintain an array, which can store pointers
to an int or char or any other data type available. Following is the declaration of an
array of pointers to an integer −
int *ptr[MAX];
It declares ptr as an array of MAX integer pointers. Thus, each element in ptr, holds a
pointer to an int value. The following example uses three integers, which are stored in
an array of pointers, as follows −

#include <stdio.h>

const int MAX = 3;

int main () {

105
int var[] = {10, 100, 200};
int i, *ptr[MAX];

for ( i = 0; i < MAX; i++) {


ptr[i] = &var[i]; /* assign the address of integer. */
}

for ( i = 0; i < MAX; i++) {


printf("Value of var[%d] = %d\n", i, *ptr[i] );
}

return 0;
}

When the above code is compiled and executed, it produces the following result −
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
You can also use an array of pointers to character to store a list of strings as follows −

#include <stdio.h>

const int MAX = 4;

int main () {

char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali"
};

int i = 0;

for ( i = 0; i < MAX; i++) {


printf("Value of names[%d] = %s\n", i, names[i] );
}

return 0;

106
}

When the above code is compiled and executed, it produces the following result −
Value of names[0] = Zara Ali
Value of names[1] = Hina Ali
Value of names[2] = Nuha Ali
Value of names[3] = Sara Ali

Command Line Arguments in C

The arguments passed from command line are called command line arguments. These
arguments are handled by main() function.

To support command line argument, you need to change the structure of main()
function as given below.

1. int main(int argc, char *argv[] )

Here, argc counts the number of arguments. It counts the file name as the first
argument.

The argv[] contains the total number of arguments. The first argument is the file name
always.

Example

Let's see the example of command line arguments where we are passing one argument
with file name.

1. #include <stdio.h>
2. void main(int argc, char *argv[] ) {
3.
4. printf("Program name is: %s\n", argv[0]);
5.
6. if(argc < 2){
7. printf("No argument passed through command line.\n");
8. }
9. else{

107
10. printf("First argument is: %s\n", argv[1]);
11. }
12. }

Run this program as follows in Linux:

1. ./program hello

Run this program as follows in Windows from command line:

1. program.exe hello

Output:

Program name is: program


First argument is: hello

If you pass many arguments, it will print only one.

1. ./program hello c how r u

Output:

Program name is: program


First argument is: hello

But if you pass many arguments within double quote, all arguments will be treated as a
single argument only.

1. ./program "hello c how r u"

Output:

Program name is: program


First argument is: hello c how r u

You can write your program to print all the arguments. In this program, we are printing
only argv[1], that is why it is printing only one argument.

STRUCTURES AND UNIONS

108
Structure

Structure in c is a user-defined data type that enables us to store the collection of


different data types. Each element of a structure is called a member. Structures ca;
simulate the use of classes and templates as it can store various information

The ,struct keyword is used to define the structure. Let's see the syntax to define the
structure in c.

1. struct structure_name
2. {
3. data_type member1;
4. data_type member2;
5. .
6. .
7. data_type memeberN;
8. };

Let's see the example to define a structure for an entity employee in c.

1. struct employee
2. { int id;
3. char name[20];
4. float salary;
5. };

The following image shows the memory allocation of the structure employee that is
defined in the above example.

109
Here, struct is the keyword; employee is the name of the structure; id, name,
and salary are the members or fields of the structure. Let's understand it by the diagram
given below:

Declaring structure variable

We can declare a variable for the structure so that we can access the member of the
structure easily. There are two ways to declare structure variable:

1. By struct keyword within main() function


2. By declaring a variable at the time of defining the structure.

1st way:

Let's see the example to declare the structure variable by struct keyword. It should be
declared within the main function.

struct employee

1. { int id;
2. char name[50];
3. float salary;
4. };

Now write given code inside the main() function.

1. struct employee e1, e2;

110
The variables e1 and e2 can be used to access the values stored in the structure. Here,
e1 and e2 can be treated in the same way as the objects in C++

2nd way:

Let's see another way to declare variable at the time of defining the structure.

1. struct employee
2. { int id;
3. char name[50];
4. float salary;
5. }e1,e2;

Which approach is good

If number of variables are not fixed, use the 1st approach. It provides you the flexibility
to declare the structure variable many times.

If no. of variables are fixed, use 2nd approach. It saves your code to declare a variable in
main() function.

Accessing members of the structure

There are two ways to access structure members:

1. By . (member or dot operator)


2. By -> (structure pointer operator)

Let's see the code to access the id member of p1 variable by. (member) operator.

1. p1.id

C Structure example

Let's see a simple example of structure in C language.

1. #include<stdio.h>
2. #include <string.h>
3. struct employee
4. { int id;

111
5. char name[50];
6. }e1; //declaring e1 variable for structure
7. int main( )
8. {
9. //store first employee information
10. e1.id=101;
11. strcpy(e1.name, "Sonoo Jaiswal");//copying string into char array
12. //printing first employee information
13. printf( "employee 1 id : %d\n", e1.id);
14. printf( "employee 1 name : %s\n", e1.name);
15. return 0;
16. }

Output:

employee 1 id : 101
employee 1 name : Sonoo Jaiswal

Array of Structures

An array of structres in C can be defined as the collection of multiple structures variables


where each variable contains information about different entities. The array of structures
in C are used to store information about multiple entities of different data types. The
array of structures is also known as the collection of structures.

112
Let's see an example of an array of structures that stores information of 5 students and
prints it.

1. #include<stdio.h>
2. #include <string.h>
3. struct student{
4. int rollno;
5. char name[10];
6. };
7. int main(){
8. int i;
9. struct student st[5];
10. printf("Enter Records of 5 students");
11. for(i=0;i<5;i++){
12. printf("\nEnter Rollno:");
13. scanf("%d",&st[i].rollno);
14. printf("\nEnter Name:");
15. scanf("%s",&st[i].name);
16. }
17. printf("\nStudent Information List:");
18. for(i=0;i<5;i++){
19. printf("\nRollno:%d, Name:%s",st[i].rollno,st[i].name);
20. }
21. return 0;
22. }

Output:

Enter Records of 5 students


Enter Rollno:1
Enter Name:Sonoo
Enter Rollno:2
Enter Name:Ratan
Enter Rollno:3
Enter Name:Vimal
Enter Rollno:4
Enter Name:James

113
Enter Rollno:5
Enter Name:Sarfraz

Student Information List:


Rollno:1, Name:Sonoo
Rollno:2, Name:Ratan
Rollno:3, Name:Vimal
Rollno:4, Name:James
Rollno:5, Name:Sarfraz
Array within a Structure
A structure is a data type in C/C++ that allows a group of related variables to be treated
as a single unit instead of separate entities. A structure may contain elements of
different data types – int, char, float, double, etc. It may also contain an array as its
member. Such an array is called an array within a structure. An array within a structure is
a member of the structure and can be accessed just as we access other elements of the
structure.

Below is the demonstration of a program that uses the concept of the array within a
structure. The program displays the record of a student comprising the roll
number, grade, and marks secured in various subjects. The marks in various subjects
have been stored under an array called marks. The whole record is stored under a
structure called a candidate.\

// C program to demonstrate the

// use of an array within a structure

#include <stdio.h>

// Declaration of the structure candidate

struct candidate {

114
int roll_no;

char grade;

// Array within the structure

float marks[4];

};

// Function to displays the content of

// the structure variables

void display(struct candidate a1)

printf("Roll number : %d\n", a1.roll_no);

printf("Grade : %c\n", a1.grade);

printf("Marks secured:\n");

int i;

115
int len = sizeof(a1.marks) / sizeof(float);

// Accessing the contents of the

// array within the structure

for (i = 0; i < len; i++) {

printf("Subject %d : %.2f\n",

i + 1, a1.marks[i]);

// Driver Code

int main()

// Initialize a structure

struct candidate A

= { 1, 'A', { 98.5, 77, 89, 78.5 } };

116
// Function to display structure

display(A);

return 0;

Output:

Roll number : 1
Grade : A
Marks secured:
Subject 1 : 98.50
Subject 2 : 77.00
Subject 3 : 89.00
Subject 4 : 78.50

Nested Structure

C provides us the feature of nesting one structure within another structure by using
which, complex data types are created. For example, we may need to store the address
of an entity employee in a structure. The attribute address may also have the subparts
as street number, city, state, and pin code. Hence, to store the address of the employee,
we need to store the address of the employee into a separate structure and nest the
structure address into the structure employee. Consider the following program.

1. #include<stdio.h>
2. struct address
3. {
4. char city[20];

117
5. int pin;
6. char phone[14];
7. };
8. struct employee
9. {
10. char name[20];
11. struct address add;
12. };
13. void main ()
14. {
15. struct employee emp;
16. printf("Enter employee information?\n");
17. scanf("%s %s %d %s",emp.name,emp.add.city, &emp.add.pin, emp.add.phone);
18. printf("Printing the employee information....\n");
19. printf("name: %s\nCity: %s\nPincode: %d\nPhone: %s",emp.name,emp.add.city,emp.a
dd.pin,emp.add.phone);
20. }

Output

Enter employee information?

Arun

Delhi

110001

1234567890

Printing the employee information....

name: Arun

City: Delhi

Pincode: 110001

118
Phone: 1234567890

Self-referential structure:

The self-referential structure is a structure that points to the same type of structure. It
contains one or more pointers that ultimately point to the same structure.

o Structures are a user-defined data structure type in C and C++.


o The main benefit of creating structure is that it can hold the different predefined
data types.
o It is initialized with the struct keyword and the structure's name followed by this
struct keyword.
o We can easily take the different data types like integer value, float, char, and
others within the same structure.
o It reduces the complexity of the program.
o Using a single structure can hold the values and data set in a single place.
o In the C++ programming language, placing struct keywords is optional or not
mandatory, but it is mandatory in the C programming language.
o Self-referential structure plays a very important role in creating other data
structures like Linked list.
o In this type of structure, the object of the same structure points to the same data
structure and refers to the data types of the same structure.
o It can have one or more pointers pointing to the same type of structure as their
member.
o The self-referential structure is widely used in dynamic data structures such
as trees, linked lists, etc.

119
Union in C

Union can be defined as a user-defined data type which is a collection of different


variables of different data types in the same memory location. The union can also be
defined as many members, but only one member can contain a value at a particular
point in time.

Union is a user-defined data type, but unlike structures, they share the same memory
location.

Let's understand this through an example.

1. struct abc
2. {
3. int a;
4. char b;
5. }

The above code is the user-defined structure that consists of two members, i.e., 'a' of
type int and 'b' of type character. When we check the addresses of 'a' and 'b', we found
that their addresses are different. Therefore, we conclude that the members in the
structure do not share the same memory location.

When we define the union, then we found that union is defined in the same way as the
structure is defined but the difference is that union keyword is used for defining the
union data type, whereas the struct keyword is used for defining the structure. The
union contains the data members, i.e., 'a' and 'b', when we check the addresses of both

120
the variables then we found that both have the same addresses. It means that the union
members share the same memory location.

1. union abc
2. {
3. int a;
4. char b;
5. }var;
6. int main()
7. {
8. var.a = 66;
9. printf("\n a = %d", var.a);
10. printf("\n b = %d", var.b);
11. }

Deciding the size of the union

The size of the union is based on the size of the largest member of the union.

Let's understand through an example.

1. union abc{
2. int a;
3. char b;
4. float c;
5. double d;
6. };
7. int main()
8. {
9. printf("Size of union abc is %d", sizeof(union abc));
10. return 0;
11. }

Accessing members of union using pointers

We can access the members of the union through pointers by using the (->) arrow
operator.

121
Let's understand through an example.

#include <stdio.h>

1. union abc
2. {
3. int a;
4. char b;
5. };
6. int main()
7. {
8. union abc *ptr; // pointer variable declaration
9. union abc var;
10. var.a= 90;
11. ptr = &var;
12. printf("The value of a is : %d", ptr->a);
13. return 0;
14. }
Difference between Structure and Union

Let's summarize the above discussed topic about the Struct and Union in the form of a
table that highlight the differences between structure and union

Struct Union

The struct keyword is used to define a The union keyword is used to define
structure. union.

When the variables are declared in a When the variable is declared in the
structure, the compiler allocates memory to union, the compiler allocates memory to
each variables member. The size of a the largest size variable member. The size
structure is equal or greater to the sum of of a union is equal to the size of its

122
the sizes of each data member. largest data member size.

Each variable member occupied a unique Variables members share the memory
memory space. space of the largest size variable.

Changing the value of a member will not Changing the value of one member will
affect other variables members. also affect other variables members.

Each variable member will be assessed at a Only one variable member will be
time. assessed at a time.

We can initialize multiple variables of a In union, only the first data member can
structure at a time. be initialized.

All variable members store some value at Exactly only one data member stores a
any point in the program. value at any particular instance in the
program.

The structure allows initializing multiple Union allows initializing only one variable
variable members at once. member at once.

It is used to store different data type values. It is used for storing one at a time from
different data type values.

It allows accessing and retrieving any data It allows accessing and retrieving any one
member at a time. data member at a time.

typedef in C

The typedef is a keyword used in C programming to provide some meaningful names


to the already existing variable in the C program

. It behaves similarly as we define the alias for the commands. In short, we can say that
this keyword is used to redefine the name of an already existing variable.

Syntax of typedef

typedef <existing_name> <alias_name>

123
In the above syntax, 'existing_name' is the name of an already existing variable while
'alias name' is another name given to the existing variable.

For example, suppose we want to create a variable of type unsigned int, then it
becomes a tedious task if we want to declare multiple variables of this type. To
overcome the problem, we use a typedef keyword.

1. typedef unsigned int unit;

In the above statements, we have declared the unit variable of type unsigned int by
using a typedef keyword.

Now, we can create the variables of type unsigned int by writing the following
statement:

1. unit a, b;

instead of writing:

1. unsigned int a, b;

Till now, we have observed that the typedef keyword provides a nice shortcut by
providing an alternative name for an already existing variable. This keyword is useful
when we are dealing with the long data type especially, structure declarations.

Let's understand through a simple example.

1. #include <stdio.h>
2. int main()
3. {
4. typedef unsigned int unit;
5. unit i,j;
6. i=10;
7. j=20;
8. printf("Value of i is :%d",i);
9. printf("\nValue of j is :%d",j);
10. return 0;
11. }

124
Output

Value of i is :10
Value of j is :20
Bit Fields in C
In C, we can specify size (in bits) of structure and union members. The idea is to use
memory efficiently when we know that the value of a field or group of fields will never
exceed a limit or is within a small range.
For example, consider the following declaration of date without the use of bit fields.

 C

Output:

Size of date is 12 bytes


Date is 31/12/2014

Enum Data type

The enum in C is also known as the enumerated type. It is a user-defined data type that
consists of integer values, and it provides meaningful names to these values. The use of
enum in C makes the program easy to understand and maintain. The enum is defined by
using the enum keyword.

The following is the way to define the enum in C:

1. enum flag{integer_const1, integer_const2,.....integter_constN};

In the above declaration, we define the enum named as flag containing 'N' integer
constants. The default value of integer_const1 is 0, integer_const2 is 1, and so on. We
can also change the default value of the integer constants at the time of the declaration.

125
For example:

#include <stdio.h>

// A simple representation of the date

struct date {

unsigned int d;

unsigned int m;

unsigned int y;

};

int main()

printf("Size of date is %lu bytes\n",

sizeof(struct date));

struct date dt = { 31, 12, 2014 };

printf("Date is %d/%d/%d", dt.d, dt.m, dt.y);

1. enum fruits{mango, apple, strawberry, papaya};

The default value of mango is 0, apple is 1, strawberry is 2, and papaya is 3. If we want


to change these default values, then we can do as given below:

1. enum fruits{
2. mango=2,
3. apple=1,

126
4. strawberry=5,
5. papaya=7,
6. };

Enumerated type declaration

As we know that in C language, we need to declare the variable of a pre-defined type


such as int, float, char, etc. Similarly, we can declare the variable of a user-defined data
type, such as enum. Let's see how we can declare the variable of an enum type.

Suppose we create the enum of type status as shown below:

1. enum status{false,true};

Now, we create the variable of status type:

1. enum status s; // creating a variable of the status type.

In the above statement, we have declared the 's' variable of type status.

To create a variable, the above two statements can be written as:

1. enum status{false,true} s;

In this case, the default value of false will be equal to 0, and the value of true will be
equal to 1.

Let's create a simple program of enum.

#include <stdio.h>

1. enum weekdays{Sunday=1, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

2. int main()
3. {
4. enum weekdays w; // variable declaration of weekdays type
5. w=Monday; // assigning value of Monday to w.
6. printf("The value of w is %d",w);
7. return 0;

127
8. }

In the above code, we create an enum type named as weekdays, and it contains the
name of all the seven days. We have assigned 1 value to the Sunday, and all other
names will be given a value as the previous value plus one.

Output

FILES
File Handling in C

In programming, we may require some specific input data to be generated several


numbers of times. Sometimes, it is not enough to only display the data on the console.
The data to be displayed may be very large, and only a limited amount of data can be
displayed on the console, and since the memory is volatile, it is impossible to recover
the programmatically generated data again and again. However, if we need to do so, we
may store it onto the local file system which is volatile and can be accessed every time.
Here, comes the need of file handling in C.

File handling in C enables us to create, update, read, and delete the files stored on the
local file system through our C program. The following operations can be performed on
a file.

o Creation of the new file


o Opening an existing file
o Reading from the file
o Writing to the file
o Deleting the file

Functions for file handling

128
There are many functions in the C library to open, read, write, search and close the file. A
list of file functions are given below:

No. Function Description

1 fopen() opens new or existing file

2 fprintf() write data into the file

3 fscanf() reads data from the file

4 fputc() writes a character into the file

5 fgetc() reads a character from file

6 fclose() closes the file

7 fseek() sets the file pointer to given position

8 fputw() writes an integer to file

9 fgetw() reads an integer from file

10 ftell() returns current position

11 rewind() sets the file pointer to the beginning of the file

Text and Binary file

Files is collection of records (or) it is a place on hard disk, where data is stored
permanently.

Types of Files
There are two types of files in C language which are as follows −

 Text file
 Binary File
Text File
 It contains alphabets and numbers which are easily understood by human beings.

129
 An error in a text file can be eliminated when seen.

 In text file, the text and characters will store one char per byte.

 For example, the integer value 4567 will occupy 2 bytes in memory, but, it will
occupy 5 bytes in text file.

 The data format is usually line-oriented. Here, each line is a separate command.

Binary file
 It contains 1’s and 0’s, which are easily understood by computers.

 The error in a binary file corrupts the file and is not easy to detect.

 In binary file, the integer value 1245 will occupy 2 bytes in memory and in file.

 A binary file always needs a matching software to read or write it.

 For example, an MP3 file can be produced by a sound recorder or audio editor,
and it can be played in a music player.

 MP3 file will not play in an image viewer or a database software.

Opening File: fopen()

We must open a file before it can be read, write, or update. The fopen() function is used
to open a file. The syntax of the fopen() is given below.

1. FILE *fopen( const char * filename, const char * mode );

The fopen() function accepts two parameters:

o The file name (string). If the file is stored at some specific location, then we must
mention the path at which the file is stored. For example, a file name can be
like "c://some_folder/some_file.ext".
o The mode in which the file is to be opened. It is a string.

We can use one of the following modes in the fopen() function.

The fopen function works in the following way.

o Firstly, It searches the file to be opened.

130
o Then, it loads the file from the disk and place it into the buffer. The buffer is used
to provide efficiency for the read operations.
o It sets up a character pointer which points to the first character of the file.

Consider the following example which opens a file in write mode.

1. #include<stdio.h>
2. void main( )
3. {
4. FILE *fp ;
5. char ch ;
6. fp = fopen("file_handle.c","r") ;
7. while ( 1 )
8. {
9. ch = fgetc ( fp ) ;
10. if ( ch == EOF )
11. break ;
12. printf("%c",ch) ;
13. }
14. fclose (fp ) ;
15. }

Output

The content of the file will be printed.

#include;
void main( )
{
FILE *fp; // file pointer
char ch;
fp = fopen("file_handle.c","r");
while ( 1 )
{
ch = fgetc ( fp ); //Each character of the file is read and stored in the character file.
if ( ch == EOF )
break;

131
printf("%c",ch);
}
fclose (fp );
}

Closing File: fclose():

The fclose() function is used to close a file. The file must be closed after performing all
the operations on it. The syntax of fclose() function is given below:

1. int fclose( FILE *fp );


2. C Files I/O: Create, Open, Read, Write and Close a File

C File management
A File can be used to store a large volume of persistent data. Like many other languages
‘C’ provides following file management functions,

1. Creation of a file
2. Opening a file
3. Reading a file
4. Writing to a file
5. Closing a file

Following are the most important file management functions available in ‘C,’

function purpose

fopen () Creating a file or opening an existing file

fclose () Closing a file

fprintf () Writing a block of data to a file

fscanf () Reading a block data from a file

getc () Reads a single character from a file

putc () Writes a single character to a file

132
function purpose

getw () Reads an integer from a file

putw () Writing an integer to a file

fseek () Sets the position of a file pointer to a specified location

ftell () Returns the current position of a file pointer

rewind () Sets the file pointer at the beginning of a file

How to Create a File


Whenever you want to work with a file, the first step is to create a file. A file is nothing
but space in a memory where data is stored.

To create a file in a ‘C’ program following syntax is used,

FILE *fp;
fp = fopen ("file_name", "mode");
In the above syntax, the file is a data structure which is defined in the standard library.

fopen is a standard function which is used to open a file.

 If the file is not present on the system, then it is created and then opened.
 If a file is already present on the system, then it is directly opened using this
function.

fp is a file pointer which points to the type file.

Whenever you open or create a file, you have to specify what you are going to do with
the file. A file in ‘C’ programming can be created or opened for reading/writing
purposes. A mode is used to specify whether you want to open a file for any of the
below-given purposes. Following are the different types of modes in ‘C’ programming
which can be used while working with a file.

File
Description
Mode

133
File
Description
Mode

Open a file for reading. If a file is in reading mode, then no data is deleted if a file
r
is already present on a system.

Open a file for writing. If a file is in writing mode, then a new file is created if a file
w doesn’t exist at all. If a file is already present on a system, then all the data inside
the file is truncated, and it is opened for writing purposes.

Open a file in
a append mode. If a file is in append mode, then the file is opened. The content
within the file doesn’t change.

r+ open for reading and writing from beginning

w+ open for reading and writing, overwriting a file

a+ open for reading and writing, appending to file

In the given syntax, the filename and the mode are specified as strings hence they must
always be enclosed within double quotes.

Example:

#include <stdio.h>
int main() {
FILE *fp;
fp = fopen ("data.txt", "w");
}
Output:

File is created in the same folder where you have saved your code.

134
You can specify the path where you want to create your file

#include <stdio.h>
int main() {
FILE *fp;
fp = fopen ("D://data.txt", "w");
}

How to Close a file


One should always close a file whenever the operations on file are over. It means the
contents and links to the file are terminated. This prevents accidental damage to the file.

‘C’ provides the fclose function to perform file closing operation. The syntax of fclose is
as follows,

fclose (file_pointer);
Example:

FILE *fp;
fp = fopen ("data.txt", "r");
fclose (fp);
The fclose function takes a file pointer as an argument. The file associated with the file
pointer is then closed with the help of fclose function. It returns 0 if close was successful
and EOF (end of file) if there is an error has occurred while file closing.

After closing the file, the same file pointer can also be used with other files.

In ‘C’ programming, files are automatically close when the program is terminated.
Closing a file manually by writing fclose function is a good programming practice.

Writing to a File
In C, when you write to a file, newline characters ‘\n’ must be explicitly added.

135
The stdio library offers the necessary functions to write to a file:

 fputc(char, file_pointer): It writes a character to the file pointed to by


file_pointer.
 fputs(str, file_pointer): It writes a string to the file pointed to by file_pointer.
 fprintf(file_pointer, str, variable_lists): It prints a string to the file pointed to by
file_pointer. The string can optionally include format specifiers and a list of
variables variable_lists.

The program below shows how to perform writing to a file:

fputc() Function:
#include <stdio.h>
int main() {
int i;
FILE * fptr;
char fn[50];
char str[] = "Guru99 Rocks\n";
fptr = fopen("fputc_test.txt", "w"); // "w" defines "writing mode"
for (i = 0; str[i] != '\n'; i++) {
/* write to file using fputc() function */
fputc(str[i], fptr);
}
fclose(fptr);
return 0;
}
Output:

The above program writes a single character into the fputc_test.txt file until it reaches
the next line symbol “\n” which indicates that the sentence was successfully written. The
process is to take each character of the array and write it into the file.

136
1. In the above program, we have created and opened a file called fputc_test.txt in a
write mode and declare our string which will be written into the file.
2. We do a character by character write operation using for loop and put each
character in our file until the “\n” character is encountered then the file is closed
using the fclose function.

fputs () Function:
#include <stdio.h>
int main() {
FILE * fp;
fp = fopen("fputs_test.txt", "w+");
fputs("This is Guru99 Tutorial on fputs,", fp);
fputs("We don't need to use for loop\n", fp);
fputs("Easier than fputc function\n", fp);
fclose(fp);
return (0);
}
OUTPUT:

137
1. In the above program, we have created and opened a file called fputs_test.txt in a
write mode.
2. After we do a write operation using fputs() function by writing three different
strings
3. Then the file is closed using the fclose function.

fprintf()Function:
#include <stdio.h>
int main() {
FILE *fptr;
fptr = fopen("fprintf_test.txt", "w"); // "w" defines "writing mode"
/* write to file */
fprintf(fptr, "Learning C with Guru99\n");
fclose(fptr);
return 0;
}
OUTPUT:

1. In the above program we have created and opened a file called fprintf_test.txt in
a write mode.
2. After a write operation is performed using fprintf() function by writing a string,
then the file is closed using the fclose function.

Reading data from a File


There are three different functions dedicated to reading data from a file

 fgetc(file_pointer): It returns the next character from the file pointed to by the
file pointer. When the end of the file has been reached, the EOF is sent back.

138
 fgets(buffer, n, file_pointer): It reads n-1 characters from the file and stores the
string in a buffer in which the NULL character ‘\0’ is appended as the last
character.
 fscanf(file_pointer, conversion_specifiers, variable_adresses): It is used to
parse and analyze data. It reads characters from the file and assigns the input to a
list of variable pointers variable_adresses using conversion specifiers. Keep in
mind that as with scanf, fscanf stops reading a string when space or newline is
encountered.

The following program demonstrates reading from fputs_test.txt file using


fgets(),fscanf() and fgetc () functions respectively :

#include <stdio.h>
int main() {
FILE * file_pointer;
char buffer[30], c;

file_pointer = fopen("fprintf_test.txt", "r");


printf("----read a line----\n");
fgets(buffer, 50, file_pointer);
printf("%s\n", buffer);

printf("----read and parse data----\n");


file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer
char str1[10], str2[2], str3[20], str4[2];
fscanf(file_pointer, "%s %s %s %s", str1, str2, str3, str4);
printf("Read String1 |%s|\n", str1);
printf("Read String2 |%s|\n", str2);
printf("Read String3 |%s|\n", str3);
printf("Read String4 |%s|\n", str4);

printf("----read the entire file----\n");

file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer


while ((c = getc(file_pointer)) != EOF) printf("%c", c);

fclose(file_pointer);
return 0;
}
Result:

139
----read a line----
Learning C with Guru99

----read and parse data----


Read String1 |Learning|
Read String2 |C|
Read String3 |with|
Read String4 |Guru99|
----read the entire file----
Learning C with Guru99

1. In the above program, we have opened the file called “fprintf_test.txt” which was
previously written using fprintf() function, and it contains “Learning C with
Guru99” string. We read it using the fgets() function which reads line by line
where the buffer size must be enough to handle the entire line.
2. We reopen the file to reset the pointer file to point at the beginning of the file.
Create various strings variables to handle each word separately. Print the
variables to see their contents. The fscanf() is mainly used to extract and parse
data from a file.
3. Reopen the file to reset the pointer file to point at the beginning of the file. Read
data and print it from the file character by character using getc() function until
the EOF statement is encountered
4. After performing a reading operation file using different variants, we again closed
the file using the fclose function.

Interactive File Read and Write with getc and putc


These are the simplest file operations. Getc stands for get character, and putc stands for
put character. These two functions are used to handle only a single character at a time.

Following program demonstrates the file handling functions in ‘C’ programming:

#include <stdio.h>
int main() {
FILE * fp;
char c;
printf("File Handling\n");
//open a file
fp = fopen("demo.txt", "w");
//writing operation

140
while ((c = getchar()) != EOF) {
putc(c, fp);
}
//close file
fclose(fp);
printf("Data Entered:\n");
//reading
fp = fopen("demo.txt", "r");
while ((c = getc(fp)) != EOF) {
printf("%c", c);
}
fclose(fp);
return 0;
}
Output:

141
1. In the above program we have created and opened a file called demo in a write
mode.
2. After a write operation is performed, then the file is closed using the fclose
function.
3. We have again opened a file which now contains data in a reading mode. A while
loop will execute until the eof is found. Once the end of file is found the
operation will be terminated and data will be displayed using printf function.
4. After performing a reading operation file is again closed using the fclose
function.

Summary

 A file is a space in a memory where data is stored.


 ‘C’ programming provides various functions to deal with a file.
 A mechanism of manipulating with the files is called as file management.
 A file must be opened before performing operations on it.
 A file can be opened in a read, write or an append mode.
 Getc and putc functions are used to read and write a single character.
 The function fscanf() permits to read and parse data from a file
 We can read (using the getc function) an entire file by looping to cover all the
file until the EOF is encountered
 We can write to a file after creating its name, by using the function fprintf() and
it must have the newline character at the end of the string text.

C - Formatted I/O Functions


C language provide us console input/output functions. As the name says, the console
input/output functions allow us to -
 Read the input from the keyboard by the user accessing the console.
 Display the output to the user at the console.

Note : These input and output values could be of any primitive data type.

There are two kinds of console input/output functions -


 Formatted input/output functions.
 Unformatted input/output functions.

142
Formatted input/output functions

Formatted console input/output functions are used to take one or more inputs from the
user at console and it also allows us to display one or multiple values in the output to
the user at the console.

Some of the most important formatted console input/output functions are -

Functions Description

This function is used to read one or multiple inputs from


scanf()
the user at the console.

This function is used to display one or multiple values in


printf()
the output to the user at the console.

This function is used to read the characters from a string


sscanf()
and stores them in variables.

This function is used to read the values stored in


sprintf() different variables and store these values in a character
array.

Q : Why these functions are called formatted console input/output functions?

While calling any of the formatted console input/output functions, we must use a
specific format specifiers in them, which allow us to read or display any value of a
specific primitive data type. Let's see what are these format specifiers.

143
Unit -4

Data Structure?

The data structure name indicates itself that organizing the data in memory. There are
many ways of organizing the data in the memory as we have already seen one of the
data structures, i.e., array in C language. Array is a collection of memory elements in
which data is stored sequentially, i.e., one after another. In other words, we can say that
array stores the elements in a continuous manner. This organization of data is done with
the help of an array of data structures. There are also other ways to organize the data in
memory. Let's see the different types of data structures.

The data structure is not any programming language like C, C++, java, etc. It is a set of
algorithms that we can use in any programming language to structure the data in the
memory.

To structure the data in memory, 'n' number of algorithms were proposed, and all these
algorithms are known as Abstract data types. These abstract data types are the set of
rules.

Types of Data Structures

There are two types of data structures:

o Primitive data structure


o Non-primitive data structure

144
Primitive Data structure

The primitive data structures are primitive data types. The int, char, float, double, and
pointer are the primitive data structures that can hold a single value.

Non-Primitive Data structure

The non-primitive data structure is divided into two types:

o Linear data structure


o Non-linear data structure

Linear Data Structure

The arrangement of data in a sequential manner is known as a linear data structure. The
data structures used for this purpose are Arrays, Linked list, Stacks, and Queues. In these
data structures, one element is connected to only one another element in a linear form.

Time Complexity

1. Time complexity of a simple loop when the loop variable is incremented or


decremented by a constant amount:

1. int i = 1;
2. do
3. {
4. i++;
5. }while(i<=n);

Here, i: It is a loop variable.

145
n: Number of times the loop is to be executed.

In above scenario, loop is executed 'n' times. Therefore, time complexity of this loop is
O(n).

2. Time complexity of a loop when the loop variable is divided or multiplied by a


constant amount:

1. int i=1;
2. do
3. {
4. i = i*c;
5. }while(i<=n);

Here, i: It is a loop variable.

c: It is a constant.

n: Number of times the loop is to be executed.

In this case, Time complexity is O(logn).

3. Time complexity of a nested loop.

1. int i=0;

146
2. do{
3. do{
4. int j =0;
5. j++;
6. }while(j<=i);
7. i++;
8. }while(i<=n-1);

Here, i: It is an outer loop variable.

j: It is an inner loop variable.

n: Number of times the loop is to be executed.

In this case, in each iteration of i, inner loop is executed 'n' times. The time complexity of
a loop is equal to the number of times the innermost statement is to be executed.

1. On the first iteration of i=0, the inner loop executes 0 times.


2. On the first iteration of i=1, the inner loop executes 1 times.
3. .
4. .
5. On the first iteration of i=n-1, the inner loop executes n-1 times.
6.
7. The number of times the inner loop is executed is equal to the sum of integers(0,1,2,3?n
-1) = n^2/2 - n/2

Time complexity = O(n2).

4.Time complexity of an infinite loop

Infinite loop is executed "Infinite times". Therefore, there is no "algorithm time


complexity" for an infinite loop.

5.Time complexities of different loops.

When there are more than one loop:

1. int i=1;

147
2. do{
3. i++;
4. }while(i<=m);
5.
6. int j=1;
7. do{
8. j++;
9. }while(j<=n);

Time complexity of different loops is equal to the sum of the complexities of individual
loop.

Therefore,

Time complexity = O(m)+O(n)

Space Complexity:
o Space complexity: An algorithm's space complexity is the amount of space
required to solve a problem and produce an output. Similar to the time
complexity, space complexity is also expressed in big O notation.

For an algorithm, the space is required for the following purposes:

1. To store program instructions


2. To store constant values
3. To store variable values
4. To track the function calls, jumping statements, etc.

Auxiliary space: The extra space required by the algorithm, excluding the input size, is
known as an auxiliary space. The space complexity considers both the spaces, i.e.,
auxiliary space, and space used by the input.

So,

Space complexity = Auxiliary space + Input size.

148
Naïve method
Pattern matching in C− We have to find if a string is present in another string, as an
example, the string "algorithm” is present within the string "naive algorithm". If it is
found, then its location (i.e. position it is present at) is displayed. We tend to create a
function that receives 2 character arrays and returns the position if matching happens
otherwise returns -1.

Input: txt = "HERE IS A NICE CAP"


pattern = "NICE"
Output: Pattern found at index 10
Input: txt = "XYZXACAADXYZXYZX"
pattern = "XYZX"
Output: Pattern found at index 0
Pattern found at index 9
Pattern found at index 12
We are solving this problem with Naive Pattern Searching. This algorithm is useful for
smaller texts. Naive is a simple and inefficient way to see wherever one string occurs
within another is to examine every place it could be at, one by one, to examine if it's
there.

The time complexity of the Naive Algorithm is O(mn), where m is the size of the pattern
to be searched and n is the size of the container string.

Pattern searching is a very crucial problem in computer science. Whenever we seek for a
string in notepad/word file or browser or database or in some information, pattern
searching algorithms are used to show the search results.

149
Algorithm
naive_algorithm(pattern, text)

Input − The text and the pattern

Output − locations, where the pattern is present in the text

Start
pat_len := pattern Size
str_len := string size
for i := 0 to (str_len - pat_len), do
for j := 0 to pat_len, do
if text[i+j] ≠ pattern[j], then
break
if j == patLen, then
display the position i, as there pattern found
End
Example

#include <stdio.h>
#include <string.h>
int main (){
char txt[] = "tutorialsPointisthebestplatformforprogrammers";
char pat[] = "a";
int M = strlen (pat);
int N = strlen (txt);
for (int i = 0; i <= N - M; i++){
int j;
for (j = 0; j < M; j++)
if (txt[i + j] != pat[j])
break;
if (j == M)

150
printf ("Pattern matches at index %d \n", i);
}
return 0;
}
Output
Pattern matches at 6
Pattern matches at 25
Pattern matches at 39

The Rabin-Karp-Algorithm:

The Rabin-Karp string matching algorithm calculates a hash value for the pattern, as well
as for each M-character subsequences of text to be compared. If the hash values are
unequal, the algorithm will determine the hash value for next M-character sequence. If
the hash values are equal, the algorithm will analyze the pattern and the M-character
sequence. In this way, there is only one comparison per text subsequence, and character
matching is only required when the hash values match.

RABIN-KARP-MATCHER (T, P, d, q)
1. n ← length [T]
2. m ← length [P]
3. h ← dm-1 mod q
4. p ← 0
5. t0 ← 0
6. for i ← 1 to m
7. do p ← (dp + P[i]) mod q
8. t0 ← (dt0+T [i]) mod q
9. for s ← 0 to n-m
10. do if p = ts
11. then if P [1.....m] = T [s+1.....s + m]
12. then "Pattern occurs with shift" s
13. If s < n-m
14. then ts+1 ← (d (ts-T [s+1]h)+T [s+m+1])mod q

151
Example: For string matching, working module q = 11, how many spurious hits does
the Rabin-Karp matcher encounters in Text T = 31415926535.......

1. T = 31415926535.......
2. P = 26
3. Here T.Length =11 so Q = 11
4. And P mod Q = 26 mod 11 = 4
5. Now find the exact match of P mod Q...

Solution:

152
Linear Search Algorithm

In this article, we will discuss the Linear Search Algorithm. Searching is the process of
finding some particular element in the list. If the element is present in the list, then the
process is called successful, and the process returns the location of that element;
otherwise, the search is called unsuccessful.

153
Two popular search methods are Linear Search and Binary Search. So, here we will
discuss the popular searching technique, i.e., Linear Search Algorithm.

Linear search is also called as sequential search algorithm. It is the simplest searching
algorithm. In Linear search, we simply traverse the list completely and match each
element of the list with the item whose location is to be found. If the match is found,
then the location of the item is returned; otherwise, the algorithm returns NULL.

It is widely used to search an element from the unordered list, i.e., the list in which items
are not sorted. The worst-case time complexity of linear search is O(n).

The steps used in the implementation of Linear Search are listed as follows -

o First, we have to traverse the array elements using a for loop.


o In each iteration of for loop, compare the search element with the current array
element, and -
o If the element matches, then return the index of the corresponding array
element.
o If the element does not match, then move to the next element.
o If there is no match or the search element is not present in the given array,
return -1.

Now, let's see the algorithm of linear search.

Algorithm
1. Linear_Search(a, n, val) // 'a' is the given array, 'n' is the size of given array, 'val' is the val
ue to search
2. Step 1: set pos = -1
3. Step 2: set i = 1
4. Step 3: repeat step 4 while i <= n
5. Step 4: if a[i] == val
6. set pos = i
7. print pos
8. go to step 6
9. [end of if]
10. set ii = i + 1
11. [end of loop]

154
12. Step 5: if pos = -1
13. print "value is not present in the array "
14. [end of if]
15. Step 6: exit

Working of Linear search

Now, let's see the working of the linear search Algorithm.

To understand the working of linear search algorithm, let's take an unsorted array. It will
be easy to understand the working of linear search with an example.

Let the elements of array are -

Let the element to be searched is K = 41

Now, start from the first element and compare K with each element of the array.

The value of K, i.e., 41, is not matched with the first element of the array. So, move to
the next element. And follow the same process until the respective element is found.

155
Now, the element to be searched is found. So algorithm will return the index of the
element matched

Binary Search Algorithm

In this article, we will discuss the Binary Search Algorithm. Searching is the process of
finding some particular element in the list. If the element is present in the list, then the
process is called successful, and the process returns the location of that element.
Otherwise, the search is called unsuccessful.

Linear Search and Binary Search are the two popular searching techniques. Here we will
discuss the Binary Search Algorithm.

Binary search is the search technique that works efficiently on sorted lists. Hence, to
search an element into some list using the binary search technique, we must ensure that
the list is sorted.

Binary search follows the divide and conquer approach in which the list is divided into
two halves, and the item is compared with the middle element of the list. If the match is

156
found then, the location of the middle element is returned. Otherwise, we search into
either of the halves depending upon the result produced through the match.

Now, let's see the algorithm of Binary Search.

Algorithm

1. Binary_Search(a, lower_bound, upper_bound, val) // 'a' is the given array, 'lower_bound' i


s the index of the first array element, 'upper_bound' is the index of the last array elemen
t, 'val' is the value to search
2. Step 1: set beg = lower_bound, end = upper_bound, pos = - 1
3. Step 2: repeat steps 3 and 4 while beg <=end
4. Step 3: set mid = (beg + end)/2
5. Step 4: if a[mid] = val
6. set pos = mid
7. print pos
8. go to step 6
9. else if a[mid] > val
10. set end = mid - 1
11. else
12. set beg = mid + 1
13. [end of if]
14. [end of loop]
15. Step 5: if pos = -1
16. print "value is not present in the array"
17. [end of if]
18. Step 6: exit

Working of Binary search

Now, let's see the working of the Binary Search Algorithm.

To understand the working of the Binary search algorithm, let's take a sorted array. It
will be easy to understand the working of Binary search with an example.

There are two methods to implement the binary search algorithm -

157
o Iterative method
o Recursive method

The recursive method of binary search follows the divide and conquer approach.

Let the elements of array are -

Let the element to search is, K = 56

We have to use the below formula to calculate the mid of the array -

1. mid = (beg + end)/2

So, in the given array -

beg = 0

end = 8

mid = (0 + 8)/2 = 4. So, 4 is the mid of the array.

158
Now, the element to search is found. So algorithm will return the index of the element
matched.

Sorting Algorithms

Sorting is the process of arranging the elements of an array so that they can be placed
either in ascending or descending order. For example, consider an array A = {A1, A2, A3,
A4, ?? An }, the array is called to be in ascending order if element of A are arranged like
A1 > A2 > A3 > A4 > A5 > ? > An .

Consider an array;

int A[10] = { 5, 4, 10, 2, 30, 45, 34, 14, 18, 9 )

The Array sorted in ascending order will be given as;

A[] = { 2, 4, 5, 9, 10, 14, 18, 30, 34, 45 }

There are many techniques by using which, sorting can be performed. In this section of
the tutorial, we will discuss each method in detail.

Sorting Algorithms

Sorting algorithms are described in the following table along with the description.

Bubble sort Algorithm

159
In this article, we will discuss the Bubble sort Algorithm. The working procedure of
bubble sort is simplest. This article will be very helpful and interesting to students as
they might face bubble sort as a question in their examinations. So, it is important to
discuss the topic.

Bubble sort works on the repeatedly swapping of adjacent elements until they are not in
the intended order. It is called bubble sort because the movement of array elements is
just like the movement of air bubbles in the water. Bubbles in water rise up to the
surface; similarly, the array elements in bubble sort move to the end in each iteration.

Although it is simple to use, it is primarily used as an educational tool because the


performance of bubble sort is poor in the real world. It is not suitable for large data sets.
The average and worst-case complexity of Bubble sort is O(n2), where n is a number of
items.

Bubble short is majorly used where -

o complexity does not matter


o simple and shortcode is preferred

Algorithm

In the algorithm given below, suppose arr is an array of n elements. The


assumed swap function in the algorithm will swap the values of given array elements.

1. begin BubbleSort(arr)
2. for all array elements
3. if arr[i] > arr[i+1]
4. swap(arr[i], arr[i+1])
5. end if
6. end for
7. return arr
8. end BubbleSort

Working of Bubble sort Algorithm

Now, let's see the working of Bubble sort Algorithm.

160
To understand the working of bubble sort algorithm, let's take an unsorted array. We
are taking a short and accurate array, as we know the complexity of bubble sort is O(n2).

Let the elements of array are -

First Pass

Sorting will start from the initial two elements. Let compare them to check which is
greater.

Here, 32 is greater than 13 (32 > 13), so it is already sorted. Now, compare 32 with 26.

Here, 26 is smaller than 36. So, swapping is required. After swapping new array will look
like -

Now, compare 32 and 35.

Here, 35 is greater than 32. So, there is no swapping required as they are already sorted.

Now, the comparison will be in between 35 and 10.

Here, 10 is smaller than 35 that are not sorted. So, swapping is required. Now, we reach
at the end of the array. After first pass, the array will be -

161
Now, move to the second iteration.

Second Pass

The same process will be followed for second iteration.

Here, 10 is smaller than 32. So, swapping is required. After swapping, the array will be -

Now, move to the third iteration.

Third Pass

The same process will be followed for third iteration.

Here, 10 is smaller than 26. So, swapping is required. After swapping, the array will be -

162
Now, move to the fourth iteration.

Fourth pass

Similarly, after the fourth iteration, the array will be -

Hence, there is no swapping required, so the array is completely sorted.

Selection Sort Algorithm

In this article, we will discuss the Selection sort Algorithm. The working procedure of
selection sort is also simple. This article will be very helpful and interesting to students
as they might face selection sort as a question in their examinations. So, it is important
to discuss the topic.

In selection sort, the smallest value among the unsorted elements of the array is
selected in every pass and inserted to its appropriate position into the array. It is also
the simplest algorithm. It is an in-place comparison sorting algorithm. In this algorithm,
the array is divided into two parts, first is sorted part, and another one is the unsorted
part. Initially, the sorted part of the array is empty, and unsorted part is the given array.
Sorted part is placed at the left, while the unsorted part is placed at the right.

In selection sort, the first smallest element is selected from the unsorted array and
placed at the first position. After that second smallest element is selected and placed in
the second position. The process continues until the array is entirely sorted.

The average and worst-case complexity of selection sort is O(n2), where n is the number
of items. Due to this, it is not suitable for large data sets.

Selection sort is generally used when -

o A small array is to be sorted


o Swapping cost doesn't matter
o It is compulsory to check all elements

Now, let's see the algorithm of selection sort.

Algorithm

163
1. SELECTION SORT(arr, n)
2.
3. Step 1: Repeat Steps 2 and 3 for i = 0 to n-1
4. Step 2: CALL SMALLEST(arr, i, n, pos)
5. Step 3: SWAP arr[i] with arr[pos]
6. [END OF LOOP]
7. Step 4: EXIT
8.
9. SMALLEST (arr, i, n, pos)
10. Step 1: [INITIALIZE] SET SMALL = arr[i]
11. Step 2: [INITIALIZE] SET pos = i
12. Step 3: Repeat for j = i+1 to n
13. if (SMALL > arr[j])
14. SET SMALL = arr[j]
15. SET pos = j
16. [END OF if]
17. [END OF LOOP]
18. Step 4: RETURN pos

Working of Selection sort Algorithm

Now, let's see the working of the Selection sort Algorithm.

To understand the working of the Selection sort algorithm, let's take an unsorted array.
It will be easier to understand the Selection sort via an example.

Let the elements of array are -

Now, for the first position in the sorted array, the entire array is to be scanned
sequentially.

At present, 12 is stored at the first position, after searching the entire array, it is found
that 8 is the smallest value.

164
So, swap 12 with 8. After the first iteration, 8 will appear at the first position in the sorted
array.

For the second position, where 29 is stored presently, we again sequentially scan the
rest of the items of unsorted array. After scanning, we find that 12 is the second lowest
element in the array that should be appeared at second position.

Now, swap 29 with 12. After the second iteration, 12 will appear at the second position
in the sorted array. So, after two iterations, the two smallest values are placed at the
beginning in a sorted way.

The same process is applied to the rest of the array elements. Now, we are showing a
pictorial representation of the entire sorting process.

Insertion Sort Algorithm

In this article, we will discuss the Insertion sort Algorithm. The working procedure of
insertion sort is also simple. This article will be very helpful and interesting to students
as they might face insertion sort as a question in their examinations. So, it is important
to discuss the topic.

Insertion sort works similar to the sorting of playing cards in hands. It is assumed that
the first card is already sorted in the card game, and then we select an unsorted card. If
the selected unsorted card is greater than the first card, it will be placed at the right
side; otherwise, it will be placed at the left side. Similarly, all unsorted cards are taken
and put in their exact place.

The same approach is applied in insertion sort. The idea behind the insertion sort is that
first take one element, iterate it through the sorted array. Although it is simple to use, it
is not appropriate for large data sets as the time complexity of insertion sort in the
average case and worst case is O(n2), where n is the number of items. Insertion sort is
less efficient than the other sorting algorithms like heap sort, quick sort, merge sort, etc.

Insertion sort has various advantages such as -

165
o Simple implementation
o Efficient for small data sets
o Adaptive, i.e., it is appropriate for data sets that are already substantially sorted.

Now, let's see the algorithm of insertion sort.

Algorithm

The simple steps of achieving the insertion sort are listed as follows -

Step 1 - If the element is the first element, assume that it is already sorted. Return 1.

Step2 - Pick the next element, and store it separately in a key.

Step3 - Now, compare the key with all elements in the sorted array.

Step 4 - If the element in the sorted array is smaller than the current element, then
move to the next element. Else, shift greater elements in the array towards the right.

Step 5 - Insert the value.

Step 6 - Repeat until the array is sorted.

Working of Insertion sort Algorithm

Now, let's see the working of the insertion sort Algorithm.

To understand the working of the insertion sort algorithm, let's take an unsorted array. It
will be easier to understand the insertion sort via an example.

Let the elements of array are -

Initially, the first two elements are compared in insertion sort.

Here, 31 is greater than 12. That means both elements are already in ascending order.
So, for now, 12 is stored in a sorted sub-array.

166
Now, move to the next two elements and compare them.

Here, 25 is smaller than 31. So, 31 is not at correct position. Now, swap 31 with 25.
Along with swapping, insertion sort will also check it with all elements in the sorted
array.

For now, the sorted array has only one element, i.e. 12. So, 25 is greater than 12. Hence,
the sorted array remains sorted after swapping.

Now, two elements in the sorted array are 12 and 25. Move forward to the next
elements that are 31 and 8.

Both 31 and 8 are not sorted. So, swap them.

After swapping, elements 25 and 8 are unsorted.

So, swap them.

Now, elements 12 and 8 are unsorted.

167
So, swap them too.

Now, the sorted array has three items that are 8, 12 and 25. Move to the next items that
are 31 and 32.

Hence, they are already sorted. Now, the sorted array includes 8, 12, 25 and 31.

Move to the next elements that are 32 and 17.

17 is smaller than 32. So, swap them.

Swapping makes 31 and 17 unsorted. So, swap them too.

Now, swapping makes 25 and 17 unsorted. So, perform swapping again.

Now, the array is completely sorted.

168
Now, the array is completely sorted.

Quick Sort Algorithm

In this article, we will discuss the Quicksort Algorithm. The working procedure of
Quicksort is also simple. This article will be very helpful and interesting to students as
they might face quicksort as a question in their examinations. So, it is important to
discuss the topic.

Sorting is a way of arranging items in a systematic manner. Quicksort is the widely used
sorting algorithm that makes n log n comparisons in average case for sorting an array
of n elements. It is a faster and highly efficient sorting algorithm. This algorithm follows
the divide and conquer approach. Divide and conquer is a technique of breaking down
the algorithms into subproblems, then solving the subproblems, and combining the
results back together to solve the original problem.

Divide: In Divide, first pick a pivot element. After that, partition or rearrange the array
into two sub-arrays such that each element in the left sub-array is less than or equal to
the pivot element and each element in the right sub-array is larger than the pivot
element.

Conquer: Recursively, sort two subarrays with Quicksort

Combine: Combine the already sorted array.

169
Quicksort picks an element as pivot, and then it partitions the given array around the
picked pivot element. In quick sort, a large array is divided into two arrays in which one
holds values that are smaller than the specified value (Pivot), and another array holds
the values that are greater than the pivot.

After that, left and right sub-arrays are also partitioned using the same approach. It will
continue until the single element remains in the sub-array.

Choosing the pivot

Picking a good pivot is necessary for the fast implementation of quicksort. However, it is
typical to determine a good pivot. Some of the ways of choosing a pivot are as follows -

o Pivot can be random, i.e. select the random pivot from the given array.
o Pivot can either be the rightmost element of the leftmost element of the given
array.
o Select median as the pivot element.

Algorithm

Algorithm:

1. QUICKSORT (array A, start, end)


2. {
3. 1 if (start < end)
4. 2{
5. 3 p = partition(A, start, end)
6. 4 QUICKSORT (A, start, p - 1)
7. 5 QUICKSORT (A, p + 1, end)
8. 6 }

170
9. }

Partition Algorithm:

The partition algorithm rearranges the sub-arrays in a place.

1. PARTITION (array A, start, end)


2. {
3. 1 pivot ? A[end]
4. 2 i ? start-1
5. 3 for j ? start to end -1 {
6. 4 do if (A[j] < pivot) {
7. 5 then i ? i + 1
8. 6 swap A[i] with A[j]
9. 7 }}
10. 8 swap A[i+1] with A[end]
11. 9 return i+1
12. }

Working of Quick Sort Algorithm

Now, let's see the working of the Quicksort Algorithm.

To understand the working of quick sort, let's take an unsorted array. It will make the
concept more clear and understandable.

Let the elements of array are -

In the given array, we consider the leftmost element as pivot. So, in this case, a[left] =
24, a[right] = 27 and a[pivot] = 24.

Since, pivot is at left, so algorithm starts from right and move towards left.

171
Now, a[pivot] < a[right], so algorithm moves forward one position towards left, i.e. -

Now, a[left] = 24, a[right] = 19, and a[pivot] = 24.

Because, a[pivot] > a[right], so, algorithm will swap a[pivot] with a[right], and pivot
moves to right, as -

Now, a[left] = 19, a[right] = 24, and a[pivot] = 24. Since, pivot is at right, so algorithm
starts from left and moves to right.

As a[pivot] > a[left], so algorithm moves one position to right as -

Now, a[left] = 9, a[right] = 24, and a[pivot] = 24. As a[pivot] > a[left], so algorithm
moves one position to right as -

Now, a[left] = 29, a[right] = 24, and a[pivot] = 24. As a[pivot] < a[left], so, swap a[pivot]
and a[left], now pivot is at left, i.e. -

172
Since, pivot is at left, so algorithm starts from right, and move to left. Now, a[left] = 24,
a[right] = 29, and a[pivot] = 24. As a[pivot] < a[right], so algorithm moves one position
to left, as -

Now, a[pivot] = 24, a[left] = 24, and a[right] = 14. As a[pivot] > a[right], so, swap a[pivot]
and a[right], now pivot is at right, i.e. -

Now, a[pivot] = 24, a[left] = 14, and a[right] = 24. Pivot is at right, so the algorithm starts
from left and move to right.

Now, a[pivot] = 24, a[left] = 24, and a[right] = 24. So, pivot, left and right are pointing
the same element. It represents the termination of procedure.

Element 24, which is the pivot element is placed at its exact position.

Elements that are right side of element 24 are greater than it, and the elements that are
left side of element 24 are smaller than it.

173
Now, in a similar manner, quick sort algorithm is separately applied to the left and right
sub-arrays. After sorting gets done, the array will be -

Quicksort complexity

Now, let's see the time complexity of quicksort in best case, average case, and in worst
case. We will also see the space complexity of quicksort.

Merge Sort Algorithm

In this article, we will discuss the merge sort Algorithm. Merge sort is the sorting
technique that follows the divide and conquer approach. This article will be very helpful
and interesting to students as they might face merge sort as a question in their
examinations. In coding or technical interviews for software engineers, sorting
algorithms are widely asked. So, it is important to discuss the topic.

Merge sort is similar to the quick sort algorithm as it uses the divide and conquer
approach to sort the elements. It is one of the most popular and efficient sorting
algorithm. It divides the given list into two equal halves, calls itself for the two halves
and then merges the two sorted halves. We have to define the merge() function to
perform the merging.

The sub-lists are divided again and again into halves until the list cannot be divided
further. Then we combine the pair of one element lists into two-element lists, sorting
them in the process. The sorted two-element pairs is merged into the four-element lists,
and so on until we get the sorted list.

Now, let's see the algorithm of merge sort.

Algorithm

In the following algorithm, arr is the given array, beg is the starting element, and end is
the last element of the array.

1. MERGE_SORT(arr, beg, end)

174
2.
3. if beg < end
4. set mid = (beg + end)/2
5. MERGE_SORT(arr, beg, mid)
6. MERGE_SORT(arr, mid + 1, end)
7. MERGE (arr, beg, mid, end)
8. end of if
9.
10. END MERGE_SORT

The important part of the merge sort is the MERGE function. This function performs the
merging of two sorted sub-arrays that are A[beg…mid] and A[mid+1…end], to build
one sorted array A[beg…end]. So, the inputs of the MERGE function are A[], beg,
mid, and end.

The implementation of the MERGE function is given as follows -

1. /* Function to merge the subarrays of a[] */


2. void merge(int a[], int beg, int mid, int end)
3. {
4. int i, j, k;
5. int n1 = mid - beg + 1;
6. int n2 = end - mid;
7.
8. int LeftArray[n1], RightArray[n2]; //temporary arrays
9.
10. /* copy data to temp arrays */
11. for (int i = 0; i < n1; i++)
12. LeftArray[i] = a[beg + i];
13. for (int j = 0; j < n2; j++)
14. RightArray[j] = a[mid + 1 + j];
15.
16. i = 0, /* initial index of first sub-array */
17. j = 0; /* initial index of second sub-array */
18. k = beg; /* initial index of merged sub-array */
19.

175
20. while (i < n1 && j < n2)
21. {
22. if(LeftArray[i] <= RightArray[j])
23. {
24. a[k] = LeftArray[i];
25. i++;
26. }
27. else
28. {
29. a[k] = RightArray[j];
30. j++;
31. }
32. k++;
33. }
34. while (i<n1)
35. {
36. a[k] = LeftArray[i];
37. i++;
38. k++;
39. }
40.
41. while (j<n2)
42. {
43. a[k] = RightArray[j];
44. j++;
45. k++;
46. }
47. }

Working of Merge sort Algorithm

Now, let's see the working of merge sort Algorithm.

To understand the working of the merge sort algorithm, let's take an unsorted array. It
will be easier to understand the merge sort via an example.

176
Let the elements of array are -

According to the merge sort, first divide the given array into two equal halves. Merge
sort keeps dividing the list into equal parts until it cannot be further divided.

As there are eight elements in the given array, so it is divided into two arrays of size 4.

Now, again divide these two arrays into halves. As they are of size 4, so divide them into
new arrays of size 2.

Now, again divide these arrays to get the atomic value that cannot be further divided.

Now, combine them in the same manner they were broken.

In combining, first compare the element of each array and then combine them into
another array in sorted order.

So, first compare 12 and 31, both are in sorted positions. Then compare 25 and 8, and in
the list of two values, put 8 first followed by 25. Then compare 32 and 17, sort them and
put 17 first followed by 32. After that, compare 40 and 42, and place them sequentially.

In the next iteration of combining, now compare the arrays with two data values and
merge them into an array of found values in sorted order.

177
Now, there is a final merging of the arrays. After the final merging of above arrays, the
array will look like -

Now, the array is completely sorted.

STACK AND QUEUES

What is a Stack?

A Stack is a linear data structure that follows the LIFO (Last-In-First-Out) principle.
Stack has one end, whereas the Queue has two ends (front and rear). It contains only
one pointer top pointer pointing to the topmost element of the stack. Whenever an
element is added in the stack, it is added on the top of the stack, and the element can
be deleted only from the stack. In other words, a stack can be defined as a container
in which insertion and deletion can be done from the one end known as the top of
the stack.

Some key points related to stack


o It is called as stack because it behaves like a real-world stack, piles of books, etc.
o A Stack is an abstract data type with a pre-defined capacity, which means that it
can store the elements of a limited size.
o It is a data structure that follows some order to insert and delete the elements,
and that order can be LIFO or FILO.

Working of Stack

Stack works on the LIFO pattern. As we can observe in the below figure there are five
memory blocks in the stack; therefore, the size of the stack is 5.

Suppose we want to store the elements in a stack and let's assume that stack is empty.
We have taken the stack of size 5 as shown below in which we are pushing the elements
one by one until the stack becomes full.

178
Since our stack is full as the size of the stack is 5. In the above cases, we can observe
that it goes from the top to the bottom when we were entering the new element in the
stack. The stack gets filled up from the bottom to the top.

43.4MWhen we perform the delete operation on the stack, there is only one way for entry and
exit as the other end is closed. It follows the LIFO pattern, which means that the value entered
first will be removed last. In the above case, the value 5 is entered first, so it will be removed
only after the deletion of all the other elements.

Standard Stack Operations

The following are some common operations implemented on the stack:

o push(): When we insert an element in a stack then the operation is known as a


push. If the stack is full then the overflow condition occurs.
o pop(): When we delete an element from the stack, the operation is known as a
pop. If the stack is empty means that no element exists in the stack, this state is
known as an underflow state.
o isEmpty(): It determines whether the stack is empty or not.
o isFull(): It determines whether the stack is full or not.'
o peek(): It returns the element at the given position.
o count(): It returns the total number of elements available in a stack.
o change(): It changes the element at the given position.
o display(): It prints all the elements available in the stack.

PUSH operation

The steps involved in the PUSH operation is given below:

179
o Before inserting an element in a stack, we check whether the stack is full.
o If we try to insert the element in a stack, and the stack is full, then
the overflow condition occurs.
o When we initialize a stack, we set the value of top as -1 to check that the stack is
empty.
o When the new element is pushed in a stack, first, the value of the top gets
incremented, i.e., top=top+1, and the element will be placed at the new position
of the top.
o The elements will be inserted until we reach the max size of the stack.

POP operation

The steps involved in the POP operation is given below:

o Before deleting the element from the stack, we check whether the stack is empty.
o If we try to delete the element from the empty stack, then
the underflow condition occurs.
o If the stack is not empty, we first access the element which is pointed by the top
o Once the pop operation is performed, the top is decremented by 1, i.e., top=top-
1.

Infix to Postfix notation

180
Before understanding the conversion from infix to postfix notation, we should know
about the infix and postfix notations separately.

An infix and postfix are the expressions. An expression consists of constants, variables,
and symbols. Symbols can be operators or parenthesis. All these components must be
arranged according to a set of rules so that all these expressions can be evaluated using
the set of rules.

Examples of expressions are:

5+6

A-B

(P * 5)

All the above expressions have a common structure, i.e., we have an operator between
the two operands. An Operand is an object or a value on which the operation is to be
performed. In the above expressions, 5, 6 are the operands while '+', '-', and '*' are the
operators.

What is infix notation?

When the operator is written in between the operands, then it is known as infix
notation. Operand does not have to be always a constant or a variable; it can also be an
expression itself.

For example,

(p + q) * (r + s)

In the above expression, both the expressions of the multiplication operator are the
operands, i.e., (p + q), and (r + s) are the operands.

In the above expression, there are three operators. The operands for the first plus
operator are p and q, the operands for the second plus operator are r and s. While
performing the operations on the expression, we need to follow some set of rules
to evaluate the result. In the above expression, addition operation would be
performed on the two expressions, i.e., p+q and r+s, and then the multiplication
operation would be performed.

Syntax of infix notation is given below:

181
<operand> <operator> <operand>

If there is only one operator in the expression, we do not require applying any rule. For
example, 5 + 2; in this expression, addition operation can be performed between the
two operands (5 and 2), and the result of the operation would be 7.

If there are multiple operators in the expression, then some rule needs to be followed to
evaluate the expression.

If the expression is:

4+6*2

If the plus operator is evaluated first, then the expression would look like:

10 * 2 = 20

If the multiplication operator is evaluated first, then the expression would look like:

4 + 12 = 16

The above problem can be resolved by following the operator precedence rules. In the
algebraic expression, the order of the operator precedence is given in the below table:

Operators Symbols

Parenthesis ( ), {}, [ ]

Exponents ^

Multiplication and Division *, /

Addition and Subtraction +,-

The first preference is given to the parenthesis; then next preference is given to the
exponents. In the case of multiple exponent operators, then the operation will be
applied from right to left.

182
For example:

2^2^3 = 2 ^ 8

= 256

After exponent, multiplication, and division operators are evaluated. If both the
operators are present in the expression, then the operation will be applied from left to
right.

The next preference is given to addition and subtraction. If both the operators are
available in the expression, then we go from left to right.

The operators that have the same precedence termed as operator associativity. If we
go from left to right, then it is known as left-associative. If we go from right to left, then
it is known as right-associative.

Problem with infix notation

To evaluate the infix expression, we should know about the operator precedence rules,
and if the operators have the same precedence, then we should follow
the associativity rules. The use of parenthesis is very important in infix notation to
control the order in which the operation to be performed. Parenthesis improves the
readability of the expression. An infix expression is the most common way of writing
expression, but it is not easy to parse and evaluate the infix expression without
ambiguity. So, mathematicians and logicians studied this problem and discovered two
other ways of writing expressions which are prefix and postfix. Both expressions do not
require any parenthesis and can be parsed without ambiguity. It does not require
operator precedence and associativity rules.

Postfix Expression

The postfix expression is an expression in which the operator is written after the
operands. For example, the postfix expression of infix notation ( 2+3) can be written as
23+.

Some key points regarding the postfix expression are:

o In postfix expression, operations are performed in the order in which they have
written from left to right.
o It does not any require any parenthesis.

183
o We do not need to apply operator precedence rules and associativity rules.

Algorithm to evaluate the postfix expression

o Scan the expression from left to right until we encounter any operator.
o Perform the operation
o Replace the expression with its computed value.
o Repeat the steps from 1 to 3 until no more operators exist.

Let's understand the above algorithm through an example.

Infix expression: 2 + 3 * 4

We will start scanning from the left most of the expression. The multiplication operator
is an operator that appears first while scanning from left to right. Now, the expression
would be:

Expression = 2 + 34*

= 2 + 12

Again, we will scan from left to right, and the expression would be:

Expression = 2 12 +

= 14

Evaluation of postfix expression using stack.


o Scan the expression from left to right.
o If we encounter any operand in the expression, then we push the operand in the
stack.
o When we encounter any operator in the expression, then we pop the
corresponding operands from the stack.
o When we finish with the scanning of the expression, the final value remains in the
stack.

Let's understand the evaluation of postfix expression using stack.

184
Example 1: Postfix expression: 2 3 4 * +

Input Stack

2 3 4 * empty Push 2
+

34*+ 2 Push 3

4*+ 32 Push 4

*+ 432 Pop 4 and 3, and perform 4*3 = 12. Push 12 into the stack.

+ 12 2 Pop 12 and 2 from the stack, and perform 12+2 = 14. Push 14
into the stack.

The result of the above expression is 14.

Input Stack

3 4 * 2 5 * empty Push 3
+

4*25*+ 3 Push 4

*2 5 * + 43 Pop 3 and 4 from the stack and perform 3*4 = 12. Push 12 into
the stack.

25*+ 12 Push 2

185
5*+ 2 12 Push 5

*+ 5 2 12 Pop 5 and 2 from the stack and perform 5*2 = 10. Push 10 into
the stack.

+ 10 12 Pop 10 and 12 from the stack and perform 10+12 = 22. Push 22
into the stack.

Example 2: Postfix expression: 3 4 * 2 5 * +

The result of the above expression is 22.

Algorithm to evaluate postfix expression

1. Read a character
2. If the character is a digit, convert the character into int and push the integer into
the stack.
3. If the character is an operator,
o Pop the elements from the stack twice obtaining two operands.
o Perform the operation
o Push the result into the stack.

Conversion of infix to postfix

Here, we will use the stack data structure for the conversion of infix expression to prefix
expression. Whenever an operator will encounter, we push operator into the stack. If we
encounter an operand, then we append the operand to the expression.

Rules for the conversion from infix to postfix expression

1. Print the operand as they arrive.


2. If the stack is empty or contains a left parenthesis on top, push the incoming
operator on to the stack.
3. If the incoming symbol is '(', push it on to the stack.

186
4. If the incoming symbol is ')', pop the stack and print the operators until the left
parenthesis is found.
5. If the incoming symbol has higher precedence than the top of the stack, push it
on the stack.
6. If the incoming symbol has lower precedence than the top of the stack, pop and
print the top of the stack. Then test the incoming operator against the new top of
the stack.
7. If the incoming operator has the same precedence with the top of the stack then
use the associativity rules. If the associativity is from left to right then pop and
print the top of the stack then push the incoming operator. If the associativity is
from right to left then push the incoming operator.
8. At the end of the expression, pop and print all the operators of the stack.

Let's understand through an example.

Infix expression: K + L - M*N + (O^P) * W/U/V * T + Q

Input Expression Stack Postfix Expression

K K

+ +

L + KL

- - K L+

M - K L+ M

* -* K L+ M

N -* KL+MN

187
+ + K L + M N*
K L + M N* -

( +( K L + M N *-

O +( KL+MN*-O

^ +(^ K L + M N* - O

P +(^ K L + M N* - O P

) + K L + M N* - O P ^

* +* K L + M N* - O P ^

W +* K L + M N* - O P ^ W

/ +/ K L + M N* - O P ^ W *

U +/ K L + M N* - O P ^W*U

/ +/ K L + M N* - O P ^W*U/

V +/ KL + MN*-OP^W*U/V

* +* KL+MN*-OP^W*U/V/

T +* KL+MN*-OP^W*U/V/T

+ + KL+MN*-OP^W*U/V/T*

188
KL+MN*-OP^W*U/V/T*+

Q + KL+MN*-OP^W*U/V/T*Q

KL+MN*-OP^W*U/V/T*+Q+

The final postfix expression of infix expression(K + L - M*N + (O^P) * W/U/V * T + Q) is


KL+MN*-OP^W*U/V/T*+Q+.

Infix to Postfix notation

Before understanding the conversion from infix to postfix notation, we should know
about the infix and postfix notations separately.

An infix and postfix are the expressions. An expression consists of constants, variables,
and symbols. Symbols can be operators or parenthesis. All these components must be
arranged according to a set of rules so that all these expressions can be evaluated using
the set of rules.

Examples of expressions are:

5+6

A-B

189
(P * 5)

All the above expressions have a common structure, i.e., we have an operator between
the two operands. An Operand is an object or a value on which the operation is to be
performed. In the above expressions, 5, 6 are the operands while '+', '-', and '*' are the
operators.

What is infix notation?

When the operator is written in between the operands, then it is known as infix
notation. Operand does not have to be always a constant or a variable; it can also be an
expression itself.

For example,

(p + q) * (r + s)

In the above expression, both the expressions of the multiplication operator are the
operands, i.e., (p + q), and (r + s) are the operands.

In the above expression, there are three operators. The operands for the first plus
operator are p and q, the operands for the second plus operator are r and s. While
performing the operations on the expression, we need to follow some set of rules
to evaluate the result. In the above expression, addition operation would be
performed on the two expressions, i.e., p+q and r+s, and then the multiplication
operation would be performed.

Syntax of infix notation is given below:

<operand> <operator> <operand>

If there is only one operator in the expression, we do not require applying any rule. For
example, 5 + 2; in this expression, addition operation can be performed between the
two operands (5 and 2), and the result of the operation would be 7.

If there are multiple operators in the expression, then some rule needs to be followed to
evaluate the expression.

If the expression is:

4+6*2

190
If the plus operator is evaluated first, then the expression would look like:

10 * 2 = 20

If the multiplication operator is evaluated first, then the expression would look like:

4 + 12 = 16

The above problem can be resolved by following the operator precedence rules. In the
algebraic expression, the order of the operator precedence is given in the below table:

Operators Symbols

Parenthesis ( ), {}, [ ]

Exponents ^

Multiplication and Division *, /

Addition and Subtraction +,-

The first preference is given to the parenthesis; then next preference is given to the
exponents. In the case of multiple exponent operators, then the operation will be
applied from right to left.

For example:

2^2^3 = 2 ^ 8

= 256

After exponent, multiplication, and division operators are evaluated. If both the
operators are present in the expression, then the operation will be applied from left to
right.

The next preference is given to addition and subtraction. If both the operators are
available in the expression, then we go from left to right.

191
The operators that have the same precedence termed as operator associativity. If we
go from left to right, then it is known as left-associative. If we go from right to left, then
it is known as right-associative.

Problem with infix notation

To evaluate the infix expression, we should know about the operator precedence rules,
and if the operators have the same precedence, then we should follow
the associativity rules. The use of parenthesis is very important in infix notation to
control the order in which the operation to be performed. Parenthesis improves the
readability of the expression. An infix expression is the most common way of writing
expression, but it is not easy to parse and evaluate the infix expression without
ambiguity. So, mathematicians and logicians studied this problem and discovered two
other ways of writing expressions which are prefix and postfix. Both expressions do not
require any parenthesis and can be parsed without ambiguity. It does not require
operator precedence and associativity rules.

Postfix Expression

The postfix expression is an expression in which the operator is written after the
operands. For example, the postfix expression of infix notation ( 2+3) can be written as
23+.

Some key points regarding the postfix expression are:

o In postfix expression, operations are performed in the order in which they have
written from left to right.
o It does not any require any parenthesis.
o We do not need to apply operator precedence rules and associativity rules.

Algorithm to evaluate the postfix expression

o Scan the expression from left to right until we encounter any operator.
o Perform the operation
o Replace the expression with its computed value.
o Repeat the steps from 1 to 3 until no more operators exist.

Let's understand the above algorithm through an example.

192
Infix expression: 2 + 3 * 4

We will start scanning from the left most of the expression. The multiplication operator
is an operator that appears first while scanning from left to right. Now, the expression
would be:

Expression = 2 + 34*

= 2 + 12

Again, we will scan from left to right, and the expression would be:

Expression = 2 12 +

= 14

Evaluation of postfix expression using stack.


o Scan the expression from left to right.
o If we encounter any operand in the expression, then we push the operand in the
stack.
o When we encounter any operator in the expression, then we pop the
corresponding operands from the stack.
o When we finish with the scanning of the expression, the final value remains in the
stack.

Let's understand the evaluation of postfix expression using stack.

Example 1: Postfix expression: 2 3 4 * +

Input Stack

2 3 4 * empty Push 2
+

34*+ 2 Push 3

193
4*+ 32 Push 4

*+ 432 Pop 4 and 3, and perform 4*3 = 12. Push 12 into the stack.

+ 12 2 Pop 12 and 2 from the stack, and perform 12+2 = 14. Push 14
into the stack.

The result of the above expression is 14.

Example 2: Postfix expression: 3 4 * 2 5 * +

Input Stack

3 4 * 2 5 * empty Push 3
+

4*25*+ 3 Push 4

*2 5 * + 43 Pop 3 and 4 from the stack and perform 3*4 = 12. Push 12 into the
stack.

25*+ 12 Push 2

5*+ 2 12 Push 5

*+ 5 2 12 Pop 5 and 2 from the stack and perform 5*2 = 10. Push 10 into the
stack.

+ 10 12 Pop 10 and 12 from the stack and perform 10+12 = 22. Push 22
into the stack.

194
The result of the above expression is 22.

Algorithm to evaluate postfix expression

1. Read a character
2. If the character is a digit, convert the character into int and push the integer into
the stack.
3. If the character is an operator,
o Pop the elements from the stack twice obtaining two operands.
o Perform the operation
o Push the result into the stack.

Conversion of infix to postfix

Here, we will use the stack data structure for the conversion of infix expression to prefix
expression. Whenever an operator will encounter, we push operator into the stack. If we
encounter an operand, then we append the operand to the expression.

Rules for the conversion from infix to postfix expression

1. Print the operand as they arrive.


2. If the stack is empty or contains a left parenthesis on top, push the incoming
operator on to the stack.
3. If the incoming symbol is '(', push it on to the stack.

Input Expression Stack Postfix Expression

K K

195
+ +

L + KL

- - K L+

M - K L+ M

* -* K L+ M

N -* KL+MN

+ + K L + M N*
K L + M N* -

( +( K L + M N *-

O +( KL+MN*-O

^ +(^ K L + M N* - O

P +(^ K L + M N* - O P

) + K L + M N* - O P ^

* +* K L + M N* - O P ^

W +* K L + M N* - O P ^ W

/ +/ K L + M N* - O P ^ W *

196
U +/ K L + M N* - O P ^W*U

/ +/ K L + M N* - O P ^W*U/

V +/ KL + MN*-OP^W*U/V

* +* KL+MN*-OP^W*U/V/

T +* KL+MN*-OP^W*U/V/T

+ + KL+MN*-OP^W*U/V/T*
KL+MN*-OP^W*U/V/T*+

Q + KL+MN*-OP^W*U/V/T*Q

KL+MN*-OP^W*U/V/T*+Q+

4. If the incoming symbol is ')', pop the stack and print the operators until the left
parenthesis is found.
5. If the incoming symbol has higher precedence than the top of the stack, push it
on the stack.

197
6. If the incoming symbol has lower precedence than the top of the stack, pop and
print the top of the stack. Then test the incoming operator against the new top of
the stack.
7. If the incoming operator has the same precedence with the top of the stack then
use the associativity rules. If the associativity is from left to right then pop and
print the top of the stack then push the incoming operator. If the associativity is
from right to left then push the incoming operator.
8. At the end of the expression, pop and print all the operators of the stack.

Let's understand through an example.

Infix expression: K + L - M*N + (O^P) * W/U/V * T + Q

The final postfix expression of infix expression(K + L - M*N + (O^P) * W/U/V * T + Q) is


KL+MN*-OP^W*U/V/T*+Q+.

ostfix Expression Evaluation

A postfix expression is a collection of operators and operands in which the operator is

placed after the operands. That means, in a postfix expression the operator follows the

operands.

Postfix Expression has following general structure...

Operand1 Operand2 Operator

Example

Postfix Expression Evaluation using Stack Data Structure

198
A postfix expression can be evaluated using the Stack data structure. To evaluate a

postfix expression using Stack data structure we can use the following steps...

1. Read all the symbols one by one from left to right in the given Postfix

Expression

2. If the reading symbol is operand, then push it on to the Stack.

3. If the reading symbol is operator (+ , - , * , / etc.,), then perform TWO pop

operations and store the two popped oparands in two different variables

(operand1 and operand2). Then perform reading symbol operation using

operand1 and operand2 and push result back on to the Stack.

4. Finally! perform a pop operation and display the popped value as final

result.

Example

199
200
Stack Using Array

A stack data structure can be implemented using a one-dimensional array. But stack

implemented using array stores only a fixed number of data values. This implementation

is very simple. Just define a one dimensional array of specific size and insert or delete

the values into that array by using LIFO principle with the help of a variable called 'top'.

Initially, the top is set to -1. Whenever we want to insert a value into the stack,

increment the top value by one and then insert. Whenever we want to delete a value

from the stack, then delete the top value and decrement the top value by one.

Stack Operations using Array

A stack can be implemented using array as follows...

Before implementing actual operations, first follow the below steps to create an empty

stack.

 Step 1 - Include all the header files which are used in the program and define a

constant 'SIZE' with specific value.

 Step 2 - Declare all the functions used in stack implementation.

 Step 3 - Create a one dimensional array with fixed size (int stack[SIZE])

 Step 4 - Define a integer variable 'top' and initialize with '-1'. (int top = -1)

 Step 5 - In main method, display menu with list of operations and make suitable

function calls to perform operation selected by the user on the stack.

push(value) - Inserting value into the stack

In a stack, push() is a function used to insert an element into the stack. In a stack, the

new element is always inserted at top position. Push function takes one integer value as

parameter and inserts that value into the stack. We can use the following steps to push

an element on to the stack...

201
 Step 1 - Check whether stack is FULL. (top == SIZE-1)

 Step 2 - If it is FULL, then display "Stack is FULL!!! Insertion is not

possible!!!" and terminate the function.

 Step 3 - If it is NOT FULL, then increment top value by one (top++) and set

stack[top] to value (stack[top] = value).

pop() - Delete a value from the Stack

In a stack, pop() is a function used to delete an element from the stack. In a stack, the

element is always deleted from top position. Pop function does not take any value as

parameter. We can use the following steps to pop an element from the stack...

 Step 1 - Check whether stack is EMPTY. (top == -1)

 Step 2 - If it is EMPTY, then display "Stack is EMPTY!!! Deletion is not

possible!!!" and terminate the function.

 Step 3 - If it is NOT EMPTY, then delete stack[top] and decrement top value by

one (top--).

display() - Displays the elements of a Stack

We can use the following steps to display the elements of a stack...

 Step 1 - Check whether stack is EMPTY. (top == -1)

 Step 2 - If it is EMPTY, then display "Stack is EMPTY!!!" and terminate the

function.

 Step 3 - If it is NOT EMPTY, then define a variable 'i' and initialize with top.

Display stack[i] value and decrement i value by one (i--).

 Step 3 - Repeat above step until i value becomes '0'.

Implementation of Stack using Array


#include<stdio.h>

202
#include<conio.h>
#define SIZE 10
void push(int);
void pop();
void display();
int stack[SIZE], top = -1;
void main()
{
int value, choice;
clrscr();
while(1){
printf("\n\n***** MENU *****\n");
printf("1. Push\n2. Pop\n3. Display\n4. Exit");
printf("\nEnter your choice: ");
scanf("%d",&choice);
switch(choice){
case 1: printf("Enter the value to be insert: ");
scanf("%d",&value);
push(value);
break;
case 2: pop();
break;
case 3: display();
break;
case 4: exit(0);
default: printf("\nWrong selection!!! Try again!!!");
}

203
}
}
void push(int value){
if(top == SIZE-1)
printf("\nStack is Full!!! Insertion is not possible!!!");
else{
top++;
stack[top] = value;
printf("\nInsertion success!!!");
}
}
void pop(){
if(top == -1)
printf("\nStack is Empty!!! Deletion is not possible!!!");
else{
printf("\nDeleted : %d", stack[top]);
top--;
}
}
void display(){
if(top == -1)
printf("\nStack is Empty!!!");
else{
int i;
printf("\nStack elements are:\n");
for(i=top; i>=0; i--)
printf("%d\n",stack[i]);

204
}
}

Output

Queue?

Queue is the data structure that is similar to the queue in the real world. A queue is a
data structure in which whatever comes first will go out first, and it follows the FIFO
(First-In-First-Out) policy. Queue can also be defined as the list or collection in which the
insertion is done from one end known as the rear end or the tail of the queue, whereas
the deletion is done from another end known as the front end or the head of the
queue.

The real-world example of a queue is the ticket queue outside a cinema hall, where the
person who enters first in the queue gets the ticket first, and the last person enters in
the queue gets the ticket at last. Similar approach is followed in the queue in data
structure.

The representation of the queue is shown in the below image -

205
Now, let's move towards the types of queue.

Types of Queue

There are four different types of queue that are listed as follows -

o Simple Queue or Linear Queue


o Circular Queue
o Priority Queue
o Double Ended Queue (or Deque)

Let's discuss each of the type of queue.

Simple Queue or Linear Queue

In Linear Queue, an insertion takes place from one end while the deletion occurs from
another end. The end at which the insertion takes place is known as the rear end, and
the end at which the deletion takes place is known as front end. It strictly follows the
FIFO rule.

206
The major drawback of using a linear Queue is that insertion is done only from the rear
end. If the first three elements are deleted from the Queue, we cannot insert more
elements even though the space is available in a Linear Queue. In this case, the linear
Queue shows the overflow condition as the rear is pointing to the last element of the
Queue.

To know more about the queue in data structure, you can click the link -
https://www.javatpoint.com/data-structure-queue

Circular Queue

In Circular Queue, all the nodes are represented as circular. It is similar to the linear
Queue except that the last element of the queue is connected to the first element. It is
also known as Ring Buffer, as all the ends are connected to another end. The
representation of circular queue is shown in the below image -

The drawback that occurs in a linear queue is overcome by using the circular queue. If
the empty space is available in a circular queue, the new element can be added in an
empty space by simply incrementing the value of rear. The main advantage of using the
circular queue is better memory utilization.

To know more about the circular queue, you can click the link -
https://www.javatpoint.com/circular-queue

Priority Queue

It is a special type of queue in which the elements are arranged based on the priority. It
is a special type of queue data structure in which every element has a priority associated
with it. Suppose some elements occur with the same priority, they will be arranged
according to the FIFO principle. The representation of priority queue is shown in the
below image -

207
Insertion in priority queue takes place based on the arrival, while deletion in the priority
queue occurs based on the priority. Priority queue is mainly used to implement the CPU
scheduling algorithms.

There are two types of priority queue that are discussed as follows -

o Ascending priority queue - In ascending priority queue, elements can be


inserted in arbitrary order, but only smallest can be deleted first. Suppose an
array with elements 7, 5, and 3 in the same order, so, insertion can be done with
the same sequence, but the order of deleting the elements is 3, 5, 7.
o Descending priority queue - In descending priority queue, elements can be
inserted in arbitrary order, but only the largest element can be deleted first.
Suppose an array with elements 7, 3, and 5 in the same order, so, insertion can be
done with the same sequence, but the order of deleting the elements is 7, 5, 3.

Deque (or, Double Ended Queue)

In Deque or Double Ended Queue, insertion and deletion can be done from both ends
of the queue either from the front or rear. It means that we can insert and delete
elements from both front and rear ends of the queue. Deque can be used as a
palindrome checker means that if we read the string from both ends, then the string
would be the same.

Deque can be used both as stack and queue as it allows the insertion and deletion
operations on both ends. Deque can be considered as stack because stack follows the
LIFO (Last In First Out) principle in which insertion and deletion both can be performed
only from one end. And in deque, it is possible to perform both insertion and deletion
from one end, and Deque does not follow the FIFO principle.

The representation of the deque is shown in the below image -

208
To know more about the deque, you can click the link - https://www.javatpoint.com/ds-
deque

There are two types of deque that are discussed as follows -

o Input restricted deque - As the name implies, in input restricted queue, insertion
operation can be performed at only one end, while deletion can be performed
from both ends.

o Output restricted deque - As the name implies, in output restricted queue,


deletion operation can be performed at only one end, while insertion can be
performed from both ends.

Now, let's see the operations performed on the queue.

Application of Queue

209
A queue data structure is generally used in scenarios where the FIFO approach (First In
First Out) has to be implemented. The following are some of the most common
applications of queue in data structure:

 Managing requests on a single shared resource such as CPU scheduling and disk
scheduling
 Handling hardware or real-time systems interrupts
 Handling website traffic
 Routers and switches in networking
 Maintaining the playlist in media players

Queue implementation Using Array

A queue data structure can be implemented using one dimensional array. The queue

implemented using array stores only fixed number of data values. The implementation

of queue data structure using array is very simple. Just define a one dimensional array of

specific size and insert or delete the values into that array by using FIFO (First In First

Out) principle with the help of variables 'front' and 'rear'. Initially both 'front' and

'rear' are set to -1. Whenever, we want to insert a new value into the queue, increment

'rear' value by one and then insert at that position. Whenever we want to delete a value

from the queue, then delete the element which is at 'front' position and increment

'front' value by one.

Queue Operations using Array

Queue data structure using array can be implemented as follows...

Before we implement actual operations, first follow the below steps to create an empty

queue.

 Step 1 - Include all the header files which are used in the program and define a

constant 'SIZE' with specific value.

210
 Step 2 - Declare all the user defined functions which are used in queue

implementation.

 Step 3 - Create a one dimensional array with above defined SIZE (int

queue[SIZE])

 Step 4 - Define two integer variables 'front' and 'rear' and initialize both with '-

1'. (int front = -1, rear = -1)

 Step 5 - Then implement main method by displaying menu of operations list and

make suitable function calls to perform operation selected by the user on queue.

enQueue(value) - Inserting value into the queue

In a queue data structure, enQueue() is a function used to insert a new element into the

queue. In a queue, the new element is always inserted at rear position. The enQueue()

function takes one integer value as a parameter and inserts that value into the queue.

We can use the following steps to insert an element into the queue...

 Step 1 - Check whether queue is FULL. (rear == SIZE-1)

 Step 2 - If it is FULL, then display "Queue is FULL!!! Insertion is not

possible!!!" and terminate the function.

 Step 3 - If it is NOT FULL, then increment rear value by one (rear++) and

set queue[rear] = value.

deQueue() - Deleting a value from the Queue

In a queue data structure, deQueue() is a function used to delete an element from the

queue. In a queue, the element is always deleted from front position. The deQueue()

function does not take any value as parameter. We can use the following steps to delete

an element from the queue...

 Step 1 - Check whether queue is EMPTY. (front == rear)

211
 Step 2 - If it is EMPTY, then display "Queue is EMPTY!!! Deletion is not

possible!!!" and terminate the function.

 Step 3 - If it is NOT EMPTY, then increment the front value by one (front ++).

Then display queue[front] as deleted element. Then check whether

both front and rear are equal (front == rear), if it TRUE, then set

both front and rear to '-1' (front = rear = -1).

display() - Displays the elements of a Queue

We can use the following steps to display the elements of a queue...

 Step 1 - Check whether queue is EMPTY. (front == rear)

 Step 2 - If it is EMPTY, then display "Queue is EMPTY!!!" and terminate the

function.

 Step 3 - If it is NOT EMPTY, then define an integer variable 'i' and set

'i = front+1'.

 Step 4 - Display 'queue[i]' value and increment 'i' value by one (i++). Repeat the

same until 'i' value reaches to rear (i <= rear)

Implementation of Queue Datastructure using Array - C Programming


#include<stdio.h>
#include<conio.h>
#define SIZE 10
void enQueue(int);
void deQueue();
void display();
int queue[SIZE], front = -1, rear = -1;
void main()
{

212
int value, choice;
clrscr();
while(1){
printf("\n\n***** MENU *****\n");
printf("1. Insertion\n2. Deletion\n3. Display\n4. Exit");
printf("\nEnter your choice: ");
scanf("%d",&choice);
switch(choice){
case 1: printf("Enter the value to be insert: ");
scanf("%d",&value);
enQueue(value);
break;
case 2: deQueue();
break;
case 3: display();
break;
case 4: exit(0);
default: printf("\nWrong selection!!! Try again!!!");
}
}
}
void enQueue(int value){
if(rear == SIZE-1)
printf("\nQueue is Full!!! Insertion is not possible!!!");
else{
if(front == -1)
front = 0;

213
rear++;
queue[rear] = value;
printf("\nInsertion success!!!");
}
}
void deQueue(){
if(front == rear)
printf("\nQueue is Empty!!! Deletion is not possible!!!");
else{
printf("\nDeleted : %d", queue[front]);
front++;
if(front == rear)
front = rear = -1;
}
}
void display(){
if(rear == -1)
printf("\nQueue is Empty!!!");
else{
int i;
printf("\nQueue elements are:\n");
for(i=front; i<=rear; i++)
printf("%d\t",queue[i]);
}
}

Output

214
215
UNIT-5
Linked List

o Linked List can be defined as collection of objects called nodes that are randomly
stored in the memory.
o A node contains two fields i.e. data stored at that particular address and the
pointer which contains the address of the next node in the memory.
o The last node of the list contains pointer to the null.

Uses of Linked List

o The list is not required to be contiguously present in the memory. The node can
reside any where in the memory and linked together to make a list. This achieves
optimized utilization of space.
o list size is limited to the memory size and doesn't need to be declared in advance.
o Empty node can not be present in the linked list.
o We can store values of primitive types or objects in the singly linked list.

Singly linked list or One way chain

o Singly linked list can be defined as the collection of ordered set of elements. The
number of elements may vary according to need of the program. A node in the
singly linked list consist of two parts: data part and link part. Data part of the
node stores actual information that is to be represented by the node while the
link part of the node stores the address of its immediate successor.
o 45.1M
o 841
o Difference between JDK, JRE, and JVM

216
o One way chain or singly linked list can be traversed only in one direction. In other
words, we can say that each node contains only next pointer, therefore we can
not traverse the list in the reverse direction.
o Consider an example where the marks obtained by the student in three subjects
are stored in a linked list as shown in the figure.

o
o In the above figure, the arrow represents the links. The data part of every node
contains the marks obtained by the student in the different subject. The last node
in the list is identified by the null pointer which is present in the address part of
the last node. We can have as many elements we require, in the data part of the
list.

Operations on Singly Linked List

There are various operations which can be performed on singly linked list. A list of all
such operations is given below.

Node Creation
1. struct node
2. {
3. int data;
4. struct node *next;
5. };
6. struct node *head, *ptr;
7. ptr = (struct node *)malloc(sizeof(struct node *));

Insertion

The insertion into a singly linked list can be performed at different positions. Based on
the position of the new node being inserted, the insertion is categorized into the
following categories.

Deletion and Traversing

The Deletion of a node from a singly linked list can be performed at different positions.
Based on the position of the node being deleted, the operation is categorized into the
following categories.

217
Linked List in C: Menu Driven Program

1. #include<stdio.h>

218
219
Doubly linked list

Doubly linked list is a complex type of linked list in which a node contains a pointer to
the previous as well as the next node in the sequence. Therefore, in a doubly linked list,
a node consists of three parts: node data, pointer to the next node in sequence (next
pointer) , pointer to the previous node (previous pointer). A sample node in a doubly
linked list is shown in the figure.

A doubly linked list containing three nodes having numbers from 1 to 3 in their data
part, is shown in the following image.

In C, structure of a node in doubly linked list can be given as :

1. struct node
2. {
3. struct node *prev;
4. int data;
5. struct node *next;
6. }

The prev part of the first node and the next part of the last node will always contain null
indicating end in each direction.

220
In a singly linked list, we could traverse only in one direction, because each node
contains address of the next node and it doesn't have any record of its previous nodes.
However, doubly linked list overcome this limitation of singly linked list. Due to the fact
that, each node of the list contains the address of its previous node, we can find all the
details about the previous node as well by using the previous address stored inside the
previous part of each node.

Memory Representation of a doubly linked list

Memory Representation of a doubly linked list is shown in the following image.


Generally, doubly linked list consumes more space for every node and therefore, causes
more expansive basic operations such as insertion and deletion. However, we can easily
manipulate the elements of the list since the list maintains pointers in both the
directions (forward and backward).

In the following image, the first element of the list that is i.e. 13 stored at address 1. The
head pointer points to the starting address 1. Since this is the first element being added
to the list therefore the prev of the list contains null. The next node of the list resides at
address 4 therefore the first node contains 4 in its next pointer.

We can traverse the list in this way until we find any node containing null or -1 in its
next part.

221
Operations on doubly linked list

Node Creation

1. struct node
2. {
3. struct node *prev;
4. int data;
5. struct node *next;
6. };
7. struct node *head;

All the remaining operations regarding doubly linked list are described in the following
table.

222
Circular Linked List
Circular Linked List is a variation of Linked list in which the first element points to the
last element and the last element points to the first element. Both Singly Linked List
and Doubly Linked List can be made into a circular linked list.

Singly Linked List as Circular

In singly linked list, the next pointer of the last node points to the first node.

Doubly Linked List as Circular

In doubly linked list, the next pointer of the last node points to the first node and the
previous pointer of the first node points to the last node making the circular in both
directions.

As per the above illustration, following are the important points to be considered.
 The last link's next points to the first link of the list in both cases of singly as well
as doubly linked list.
 The first link's previous points to the last of the list in case of doubly linked list.

Basic Operations

Following are the important operations supported by a circular list.


 insert − Inserts an element at the start of the list.
 delete − Deletes an element from the start of the list.
 display − Displays the list.

Insertion Operation

223
Following code demonstrates the insertion operation in a circular linked list based on
single linked list.

Example
insertFirst(data):
Begin
create a new node
node -> data := data
if the list is empty, then
head := node
next of node = head
else
temp := head
while next of temp is not head, do
temp := next of temp
done
next of node := head
next of temp := node
head := node
end if
End

Deletion Operation

Following code demonstrates the deletion operation in a circular linked list based on
single linked list.

deleteFirst():
Begin
if head is null, then
it is Underflow and return
else if next of head = head, then
head := null
deallocate head
else
ptr := head
while next of ptr is not head, do
ptr := next of ptr
next of ptr = next of head
deallocate head
head := next of ptr

224
end if
End

Display List Operation

Following code demonstrates the display list operation in a circular linked list.

display():
Begin
if head is null, then
Nothing to print and return
else
ptr := head
while next of ptr is not head, do
display data of ptr
ptr := next of ptr
display data of ptr
end if
End
Trees

We read the linear data structures like an array, linked list, stack and queue in which all
the elements are arranged in a sequential manner. The different data structures are used
for different kinds of data.

Some factors are considered for choosing the data structure:

o What type of data needs to be stored?: It might be a possibility that a certain


data structure can be the best fit for some kind of data.
o Cost of operations: If we want to minimize the cost for the operations for the
most frequently performed operations. For example, we have a simple list on
which we have to perform the search operation; then, we can create an array in
which elements are stored in sorted order to perform the binary search. The
binary search works very fast for the simple list as it divides the search space into
half.
o Memory usage: Sometimes, we want a data structure that utilizes less memory.

225
A tree is also one of the data structures that represent hierarchical data. Suppose we
want to show the employees and their positions in the hierarchical form then it can be
represented as shown below:

The above tree shows the organization hierarchy of some company. In the above
structure, john is the CEO of the company, and John has two direct reports named
as Steve and Rohan. Steve has three direct reports named Lee, Bob, Ella where Steve is
a manager. Bob has two direct reports named Sal and Emma. Emma has two direct
reports named Tom and Raj. Tom has one direct report named Bill. This particular
logical structure is known as a Tree. Its structure is similar to the real tree, so it is named
a Tree. In this structure, the root is at the top, and its branches are moving in a
downward direction. Therefore, we can say that the Tree data structure is an efficient
way of storing the data in a hierarchical way.

4.4Let's understand some key points of the Tree data structure.


o A tree data structure is defined as a collection of objects or entities known as
nodes that are linked together to represent or simulate hierarchy.
o A tree data structure is a non-linear data structure because it does not store in a
sequential manner. It is a hierarchical structure as elements in a Tree are arranged
in multiple levels.
o In the Tree data structure, the topmost node is known as a root node. Each node
contains some data, and data can be of any type. In the above tree structure, the
node contains the name of the employee, so the type of data would be a string.
o Each node contains some data and the link or reference of other nodes that can
be called children.

Some basic terms used in Tree data structure.

226
Let's consider the tree structure, which is shown below:

In the above structure, each node is labeled with some number. Each arrow shown in the
above figure is known as a link between the two nodes.

o Root: The root node is the topmost node in the tree hierarchy. In other words,
the root node is the one that doesn't have any parent. In the above structure,
node numbered 1 is the root node of the tree. If a node is directly linked to
some other node, it would be called a parent-child relationship.
o Child node: If the node is a descendant of any node, then the node is known as a
child node.
o Parent: If the node contains any sub-node, then that node is said to be the
parent of that sub-node.
o Sibling: The nodes that have the same parent are known as siblings.
o Leaf Node:- The node of the tree, which doesn't have any child node, is called a
leaf node. A leaf node is the bottom-most node of the tree. There can be any
number of leaf nodes present in a general tree. Leaf nodes can also be called
external nodes.
o Internal nodes: A node has atleast one child node known as an internal
o Ancestor node:- An ancestor of a node is any predecessor node on a path from
the root to that node. The root node doesn't have any ancestors. In the tree
shown in the above image, nodes 1, 2, and 5 are the ancestors of node 10.

227
o Descendant: The immediate successor of the given node is known as a
descendant of a node. In the above figure, 10 is the descendant of node 5.

Binary Tree

The Binary tree means that the node can have maximum two children. Here, binary
name itself suggests that 'two'; therefore, each node can have either 0, 1 or 2 children.

Let's understand the binary tree through an example.

The above tree is a binary tree because each node contains the utmost two children. The
logical representation of the above tree is given below:

In the above tree, node 1 contains two pointers, i.e., left and a right pointer pointing to
the left and right node respectively. The node 2 contains both the nodes (left and right
node); therefore, it has two pointers (left and right). The nodes 3, 5 and 6 are the leaf
nodes, so all these nodes contain NULL pointer on both left and right parts

Properties of Binary Tree


o At each level of i, the maximum number of nodes is 2i.
o The height of the tree is defined as the longest path from the root node to the
leaf node. The tree which is shown above has a height equal to 3. Therefore, the
maximum number of nodes at height 3 is equal to (1+2+4+8) = 15. In general,

228
the maximum number of nodes possible at height h is (20 + 21 + 22+….2h) =
2h+1 -1.
o The minimum number of nodes possible at height h is equal to h+1.
o If the number of nodes is minimum, then the height of the tree would be
maximum. Conversely, if the number of nodes is maximum, then the height of the
tree would be minimum.

If there are 'n' number of nodes in the binary tree.

The minimum height can be computed as:

As we know that,

n = 2h+1 -1

n+1 = 2h+1

Taking log on both the sides,

log2(n+1) = log2(2h+1)

log2(n+1) = h+1

h = log2(n+1) - 1

The maximum height can be computed as:

As we know that,

n = h+1

h= n-1

Types of Binary Tree

There are four types of Binary tree:

o Full/ proper/ strict Binary tree


o Complete Binary tree
o Perfect Binary tree

229
o Degenerate Binary tree
o Balanced Binary tree

1. Full/ proper/ strict Binary tree

The full binary tree is also known as a strict binary tree. The tree can only be considered
as the full binary tree if each node must contain either 0 or 2 children. The full binary
tree can also be defined as the tree in which each node must contain 2 children except
the leaf nodes.

Let's look at the simple example of the Full Binary tree.

In the above tree, we can observe that each node is either containing zero or two
children; therefore, it is a Full Binary tree.

Properties of Full Binary Tree

o The number of leaf nodes is equal to the number of internal nodes plus 1. In the
above example, the number of internal nodes is 5; therefore, the number of leaf
nodes is equal to 6.
o The maximum number of nodes is the same as the number of nodes in the binary
tree, i.e., 2h+1 -1.
o The minimum number of nodes in the full binary tree is 2*h-1.
o The minimum height of the full binary tree is log2(n+1) - 1.
o The maximum height of the full binary tree can be computed as:

n= 2*h - 1

n+1 = 2*h

230
h = n+1/2

Complete Binary Tree

The complete binary tree is a tree in which all the nodes are completely filled except the
last level. In the last level, all the nodes must be as left as possible. In a complete binary
tree, the nodes should be added from the left.

Let's create a complete binary tree.

The above tree is a complete binary tree because all the nodes are completely filled, and
all the nodes in the last level are added at the left first.

Properties of Complete Binary Tree

o The maximum number of nodes in complete binary tree is 2h+1 - 1.


o The minimum number of nodes in complete binary tree is 2h.
o The minimum height of a complete binary tree is log2(n+1) - 1.
o The maximum height of a complete binary tree is

Perfect Binary Tree

A tree is a perfect binary tree if all the internal nodes have 2 children, and all the leaf
nodes are at the same level.

231
Let's look at a simple example of a perfect binary tree.

The below tree is not a perfect binary tree because all the leaf nodes are not at the same
level.

Degenerate Binary Tree

The degenerate binary tree is a tree in which all the internal nodes have only one
children.

Let's understand the Degenerate binary tree through examples.

232
The above tree is a degenerate binary tree because all the nodes have only one child. It
is also known as a right-skewed tree as all the nodes have a right child only.

The above tree is also a degenerate binary tree because all the nodes have only one
child. It is also known as a left-skewed tree as all the nodes have a left child only.

Balanced Binary Tree

The balanced binary tree is a tree in which both the left and right trees differ by atmost
1. For example, AVL and Red-Black trees are balanced binary tree.

Let's understand the balanced binary tree through examples.

The above tree is a balanced binary tree because the difference between the left subtree
and right subtree is zero.

233
The above tree is not a balanced binary tree because the difference between the left
subtree and the right subtree is greater than 1.

Binary Tree Implementation

A Binary tree is implemented with the help of pointers. The first node in the tree is
represented by the root pointer. Each node in the tree consists of three parts, i.e., data,
left pointer and right pointer. To create a binary tree, we first need to create the node.
We will create the node of user-defined as shown below:

1. struct node
2. {
3. int data,
4. struct node *left, *right;
5. }

In the above structure, data is the value, left pointer contains the address of the left
node, and right pointer contains the address of the right node.

Terminology

In linear data structure data is organized in sequential order and in non-linear data

structure data is organized in random order. A tree is a very popular non-linear data

structure used in a wide range of applications. A tree data structure can be defined as

follows...

Tree is a non-linear data structure which organizes data in hierarchical structure

and this is a recursive definition.

A tree data structure can also be defined as follows...

Tree data structure is a collection of data (Node) which is organized in hierarchical

structure recursively

In tree data structure, every individual element is called as Node. Node in a tree data

structure stores the actual data of that particular element and link to next element in

234
hierarchical structure.

In a tree data structure, if we have N number of nodes then we can have a maximum

of N-1 number of links.

Example

Terminology

In a tree data structure, we use the following terminology...

1. Root

In a tree data structure, the first node is called as Root Node. Every tree must have a

root node. We can say that the root node is the origin of the tree data structure. In any

tree, there must be only one root node. We never have multiple root nodes in a tree.

2. Edge

In a tree data structure, the connecting link between any two nodes is called as EDGE. In

a tree with 'N' number of nodes there will be a maximum of 'N-1' number of edges.

235
3. Parent

In a tree data structure, the node which is a predecessor of any node is called

as PARENT NODE. In simple words, the node which has a branch from it to any other

node is called a parent node. Parent node can also be defined as "The node which has

child / children".

4. Child

In a tree data structure, the node which is descendant of any node is called as CHILD

Node. In simple words, the node which has a link from its parent node is called as child

node. In a tree, any parent node can have any number of child nodes. In a tree, all the

nodes except root are child nodes.

236
5. Siblings

In a tree data structure, nodes which belong to same Parent are called as SIBLINGS. In

simple words, the nodes with the same parent are called Sibling nodes.

6. Leaf

In a tree data structure, the node which does not have a child is called as LEAF Node. In

simple words, a leaf is a node with no child.

In a tree data structure, the leaf nodes are also called as External Nodes. External node

is also a node with no child. In a tree, leaf node is also called as 'Terminal' node.

7. Internal Nodes

In a tree data structure, the node which has atleast one child is called as INTERNAL

Node. In simple words, an internal node is a node with atleast one child.

In a tree data structure, nodes other than leaf nodes are called as Internal Nodes. The

root node is also said to be Internal Node if the tree has more than one node. Internal

nodes are also called as 'Non-Terminal' nodes.

237
8. Degree

In a tree data structure, the total number of children of a node is called as DEGREE of

that Node. In simple words, the Degree of a node is total number of children it has. The

highest degree of a node among all the nodes in a tree is called as 'Degree of Tree'

9. Level

In a tree data structure, the root node is said to be at Level 0 and the children of root

node are at Level 1 and the children of the nodes which are at Level 1 will be at Level 2

and so on... In simple words, in a tree each step from top to bottom is called as a Level

and the Level count starts with '0' and incremented by one at each level (Step).

238
10. Height

In a tree data structure, the total number of edges from leaf node to a particular node in

the longest path is called as HEIGHT of that Node. In a tree, height of the root node is

said to be height of the tree. In a tree, height of all leaf nodes is '0'.

11. Depth

In a tree data structure, the total number of egdes from root node to a particular node is

called as DEPTH of that Node. In a tree, the total number of edges from root node to a

leaf node in the longest path is said to be Depth of the tree. In simple words, the

highest depth of any leaf node in a tree is said to be depth of that tree. In a tree, depth

of the root node is '0'.

12. Path

In a tree data structure, the sequence of Nodes and Edges from one node to another

node is called as PATH between that two Nodes. Length of a Path is total number of

nodes in that path. In below example the path A - B - E - J has length 4.

239
13. Sub Tree

In a tree data structure, each child from a node forms a subtree recursively. Every child

node will form a subtree on its parent node.

Tree Representations

A tree data structure can be represented in two methods. Those methods are as

follows...

1. List Representation

2. Left Child - Right Sibling Representation

Consider the following tree...

240
1. List Representation

In this representation, we use two types of nodes one for representing the node with

data called 'data node' and another for representing only references called 'reference

node'. We start with a 'data node' from the root node in the tree. Then it is linked to an

internal node through a 'reference node' which is further linked to any other node

directly. This process repeats for all the nodes in the tree.

The above example tree can be represented using List representation as follows...

2. Left Child - Right Sibling Representation

In this representation, we use a list with one type of node which consists of three fields

namely Data field, Left child reference field and Right sibling reference field. Data field

stores the actual value of a node, left reference field stores the address of the left child

and right reference field stores the address of the right sibling node. Graphical

representation of that node is as follows...

241
In this representation, every node's data field stores the actual value of that node. If that

node has left a child, then left reference field stores the address of that left child node

otherwise stores NULL. If that node has the right sibling, then right reference field stores

the address of right sibling node otherwise stores NULL.

The above example tree can be represented using Left Child - Right Sibling

representation as follows...

Tree traversal (Inorder, Preorder an Postorder)

In this article, we will discuss the tree traversal in the data structure. The term 'tree
traversal' means traversing or visiting each node of a tree. There is a single way to
traverse the linear data structure such as linked list, queue, and stack. Whereas, there are
multiple ways to traverse a tree that are listed as follows -

o Preorder traversal
o Inorder traversal
o Postorder traversal

So, in this article, we will discuss the above-listed techniques of traversing a tree. Now,
let's start discussing the ways of tree traversal.

242
Preorder traversal

This technique follows the 'root left right' policy. It means that, first root node is visited
after that the left subtree is traversed recursively, and finally, right subtree is recursively
traversed. As the root node is traversed before (or pre) the left and right subtree, it is
called preorder traversal.

So, in a preorder traversal, each node is visited before both of its subtrees.

The applications of preorder traversal include -

o It is used to create a copy of the tree.


o It can also be used to get the prefix expression of an expression tree.

Algorithm

1. Until all nodes of the tree are not visited


2.
3. Step 1 - Visit the root node
4. Step 2 - Traverse the left subtree recursively.
5. Step 3 - Traverse the right subtree recursively.

Example

Now, let's see the example of the preorder traversal technique.

Now, start applying the preorder traversal on the above tree. First, we traverse the root
node A; after that, move to its left subtree B, which will also be traversed in preorder.

243
So, for left subtree B, first, the root node B is traversed itself; after that, its left
subtree D is traversed. Since node D does not have any children, move to right
subtree E. As node E also does not have any children, the traversal of the left subtree of
root node A is completed.

Now, move towards the right subtree of root node A that is C. So, for right subtree C,
first the root node C has traversed itself; after that, its left subtree F is traversed. Since
node F does not have any children, move to the right subtree G. As node G also does
not have any children, traversal of the right subtree of root node A is completed.

Therefore, all the nodes of the tree are traversed. So, the output of the preorder
traversal of the above tree is -

A→B→D→E→C→F→G

To know more about the preorder traversal in the data structure, you can follow the
link Preorder traversal.

Postorder traversal

This technique follows the 'left-right root' policy. It means that the first left subtree of
the root node is traversed, after that recursively traverses the right subtree, and finally,
the root node is traversed. As the root node is traversed after (or post) the left and right
subtree, it is called postorder traversal.

So, in a postorder traversal, each node is visited after both of its subtrees.

The applications of postorder traversal include -

o It is used to delete the tree.


o It can also be used to get the postfix expression of an expression tree.

Algorithm

1. Until all nodes of the tree are not visited


2.
3. Step 1 - Traverse the left subtree recursively.
4. Step 2 - Traverse the right subtree recursively.
5. Step 3 - Visit the root node.

244
Example

Now, let's see the example of the postorder traversal technique.

Now, start applying the postorder traversal on the above tree. First, we traverse the left
subtree B that will be traversed in postorder. After that, we will traverse the right
subtree C in postorder. And finally, the root node of the above tree, i.e., A, is traversed.

So, for left subtree B, first, its left subtree D is traversed. Since node D does not have any
children, traverse the right subtree E. As node E also does not have any children, move
to the root node B. After traversing node B, the traversal of the left subtree of root node
A is completed.

Now, move towards the right subtree of root node A that is C. So, for right subtree C,
first its left subtree F is traversed. Since node F does not have any children, traverse the
right subtree G. As node G also does not have any children, therefore, finally, the root
node of the right subtree, i.e., C, is traversed. The traversal of the right subtree of root
node A is completed.

At last, traverse the root node of a given tree, i.e., A. After traversing the root node, the
postorder traversal of the given tree is completed.

Therefore, all the nodes of the tree are traversed. So, the output of the postorder
traversal of the above tree is -

D→E→B→F→G→C→A

To know more about the postorder traversal in the data structure, you can follow the
link Postorder traversal.

Inorder traversal

This technique follows the 'left root right' policy. It means that first left subtree is visited
after that root node is traversed, and finally, the right subtree is traversed. As the root
node is traversed between the left and right subtree, it is named inorder traversal.

So, in the inorder traversal, each node is visited in between of its subtrees.

245
The applications of Inorder traversal includes -

o It is used to get the BST nodes in increasing order.


o It can also be used to get the prefix expression of an expression tree.

Algorithm

1. Until all nodes of the tree are not visited


2.
3. Step 1 - Traverse the left subtree recursively.
4. Step 2 - Visit the root node.
5. Step 3 - Traverse the right subtree recursively.

Example

Now, let's see the example of the Inorder traversal technique.

Now, start applying the inorder traversal on the above tree. First, we traverse the left
subtree B that will be traversed in inorder. After that, we will traverse the root node A.
And finally, the right subtree C is traversed in inorder.

So, for left subtree B, first, its left subtree D is traversed. Since node D does not have any
children, so after traversing it, node B will be traversed, and at last, right subtree of node
B, that is E, is traversed. Node E also does not have any children; therefore, the traversal
of the left subtree of root node A is completed.

After that, traverse the root node of a given tree, i.e., A.

246
At last, move towards the right subtree of root node A that is C. So, for right subtree C;
first, its left subtree F is traversed. Since node F does not have any children, node C will
be traversed, and at last, a right subtree of node C, that is, G, is traversed. Node G also
does not have any children; therefore, the traversal of the right subtree of root node A is
completed.

As all the nodes of the tree are traversed, the inorder traversal of the given tree is
completed. The output of the inorder traversal of the above tree is -

D→B→E→A→F→C→G

To know more about the inorder traversal in data structure, you can follow the
link Inorder Traversal.

Complexity of Tree traversal techniques

The time complexity of tree traversal techniques discussed above is O(n), where 'n' is
the size of binary tree.

Whereas the space complexity of tree traversal techniques discussed above is O(1) if we
do not consider the stack size for function calls. Otherwise, the space complexity of
these techniques is O(h), where 'h' is the tree's height.

247

You might also like