PPS Notes
PPS Notes
UNIT-III
NOTES For
FUNCTIONS
Program Output
HOW TO CALL C FUNCTIONS IN A PROGRAM?
There are two ways that a C function can be called from a program. They are,
1. Call by value
2. Call by reference
1. CALL BY VALUE:
In call by value method, the value of the variable is passed to the function as parameter.
The value of the actual parameter can not be modified by formal parameter.
Different Memory is allocated for both actual and formal parameters. Because, value of actual
parameter is copied to formal parameter.
Note:
While calling a function, we pass values of variables to it. variables, we pass address of variables(location of variables) to
Such functions are known as “Call By Values”. the function known as “Call By References.
In this method, the value of each variable in calling In this method, the address of actual variables in the calling
function is copied into corresponding dummy variables of function are copied into the dummy variables of the called
With this method, the changes made to the dummy With this method, using addresses we would have an access to
variables in the called function have no effect on the the actual variables and hence we would be able to manipulate
In call by values we cannot alter the values of actual In call by reference we can alter the values of variables through
UNIT-IV
NOTES For
ARRAYS
Array in C programming
CHARACTER ARRAY AND STRING IN C
String and Character Array
String is a sequence of characters that is treated as a single data item and terminated by null character '\0'.
Remember that C language does not support strings as a data type. A string is actually one-dimensional array
of characters in C language. These are often used to create meaningful and readable programs.
For example: The string "hello world" contains 12 characters including '\0' character which is automatically
added by the compiler at the end of the string.
char str[4];
str = "hell"; // Illegal String Input and Output
Input function scanf() can be used with %s format specifier to read a string input from the terminal. But there is
one problem with scanf() function, it terminates its input on the first white space it encounters. Therefore if you
try to read an input string "Hello World" using scanf() function, it will only read Hello and terminate after
encountering white spaces.
However, C supports a format specification known as the edit set conversion code %[..] that can be used to
read a line containing a variety of characters, including white spaces.
#include<stdio.h>
#include<string.h>
void main()
{
char str[20];
printf("Enter a string");
scanf("%[^\n]", &str); //scanning the whole string, including the white spaces
printf("%s", str);
}
Another method to read character string with white spaces from terminal is by using the gets() function.
char text[20];
gets(text);
printf("%s", text);
String Handling Functions
C language supports a large number of string handling functions that can be used to carry out many of the
string manipulations. These functions are packaged in string.h library. Hence, you must
include string.h header file in your programs to use these functions.
The following are the most commonly used string handling functions.
Method Description
strcat() function
strcat("hello", "world");
strcat() function will add the string "world" to "hello" i.e it will ouput helloworld.
strlen() function
strlen() function will return the length of the string passed to it.
int j;
j = strlen("studytonight");
printf("%d",j);
strcmp() function
strcmp() function will return the ASCII difference between first unmatching character of two strings.
int j;
j = strcmp("study", "tonight");
printf("%d",j);
strcpy() function
It copies the second string argument to the first string argument.
#include<stdio.h>
#include<string.h>
int main()
{
char s1[50];
char s2[50];
printf("%s\n", s2);
return(0);
}
strrev() function
It is used to reverse the given string expression.
#include<stdio.h>
int main()
{
char s1[50];
printf("Enter your string: ");
gets(s1);
printf("\nYour reverse string is: %s",strrev(s1));
return(0);
}
Lets say we need to store the data of students like student name, age, address, id etc. One way of doing this
would be creating a different variable for each attribute, however when you need to store the data of multiple
students then in that case, you would need to create these several variables again for each student. This is
such a big headache to store data in this way.
We can solve this problem easily by using structure. We can create a structure that has members for name, id,
address and age and then we can create the variables of this structure for each student. This may sound
confusing, do not worry we will understand this with the help of example.
struct struct_name {
DataType member1_name;
DataType member2_name;
DataType member3_name;
…
};
Here struct_name can be anything of your choice. Members data type can be same or different. Once we have
declared the structure we can use the struct name as a data type like int, float etc.
First we will see the syntax of creating struct variable, accessing struct members etc and then we will see a
complete example.
struct struct_name {
DataType member1_name;
DataType member2_name;
DataType member3_name;
…
} var_name;
How to access data members of a structure using a struct variable?
var_name.member1_name;
var_name.member2_name;
…
How to assign values to structure members?
There are three ways to do this.
1) Using Dot(.) operator
var_name.memeber_name = value;
2) All members assigned in one statement
struct struct_name var_name =
{value for memeber1, value for memeber2 …so on for all the members}
3) Designated initializers – We will discuss this later at the end of this post.
Example of Structure in C
#include <stdio.h>
/* Created a structure here. The name of the structure is
* StudentData.
*/
struct StudentData{
char *stu_name;
int stu_id;
int stu_age;
};
int main()
{
/* student is the variable of structure StudentData*/
struct StudentData student;
UNION IN C PROGRAMMING
C Union is also like structure, i.e. collection of different data types which are grouped together. Each element in
a union is called member.
Union and structure in C are same in concepts, except allocating memory for their members.
Structure allocates storage space for all its members separately.
Whereas, Union allocates one common storage space for all its members
We can access only one member of union at a time. We can’t access all member values at the same
time in union. But, structure can access all member values at the same time. This is because, Union
allocates one common storage space for all its members. Where as Structure allocates storage space
for all its members separately.
Many union variables can be created in a program and memory will be allocated for each union variable
separately.
Below table will help you how to form a C union, declare a union, initializing and accessing the
members of the union.
Using normal variable Using pointer variable
Syntax: Syntax:
union tag_name union tag_name
{ {
data type var_name1; data type var_name1;
data type var_name2; data type var_name2;
data type var_name3; data type var_name3;
}; };
Example: Example:
union student union student
{ {
int mark; int mark;
char name[10]; char name[10];
float average; float average;
}; };
Declaring union using Declaring union using
normal variable: pointer variable:
union student report; union student *report, rep;
Initializing union using
Initializing union using pointer variable:
normal variable: union student rep = {100,
union student report = {100, “Mani”, 99.5};
“Mani”, 99.5}; report = &rep;
Accessing union members Accessing union members
using normal variable: using pointer variable:
report.mark; report -> mark;
report.name; report -> name;
report.average; report -> average;
EXAMPLE PROGRAM FOR C UNION:
1 #include <stdio.h>
2 #include <string.h>
3
4 union student
5 {
6 char name[20];
7 char subject[20];
8 float percentage;
9 };
10
11 int main()
12 {
13 union student record1;
14 union student record2;
15
16 // assigning values to record1 union variable
17 strcpy(record1.name, "Raju");
18 strcpy(record1.subject, "Maths");
19 record1.percentage = 86.50;
20
21 printf("Union record1 values example\n");
22 printf(" Name : %s \n", record1.name);
23 printf(" Subject : %s \n", record1.subject);
24 printf(" Percentage : %f \n\n", record1.percentage);
25
26 // assigning values to record2 union variable
27 printf("Union record2 values example\n");
28 strcpy(record2.name, "Mani");
29 printf(" Name : %s \n", record2.name);
30
31 strcpy(record2.subject, "Physics");
32 printf(" Subject : %s \n", record2.subject);
33
34 record2.percentage = 99.50;
35 printf(" Percentage : %f \n", record2.percentage);
36 return 0;
37 }
OUTPUT:
Union record1 values example
Name :
Subject :
Percentage : 86.500000;
Union record2 values example
Name : Mani
Subject : Physics
Percentage : 99.500000
EXPLANATION FOR ABOVE C UNION PROGRAM:
There are 2 union variables declared in this program to understand the difference in accessing values of union
members.
If we want to access all member values using union, we have to access the member before assigning
values to other members as shown in record2 union variable in this program.
Each union members are accessed in record2 example immediately after assigning values to them.
If we don’t access them before assigning values to other member, member name and value will be over
written by other member as all members are using same memory.
We can’t access all members in union at same time but structure can do that.
EXAMPLE PROGRAM – ANOTHER WAY OF DECLARING C UNION:
In this program, union variable “record” is declared while declaring union itself as shown in the below program.
1 #include <stdio.h>
2 #include <string.h>
3
4 union student
5 {
6 char name[20];
7 char subject[20];
8 float percentage;
9 }record;
10
11 int main()
12 {
13
14 strcpy(record.name, "Raju");
15 strcpy(record.subject, "Maths");
16 record.percentage = 86.50;
17
18 printf(" Name : %s \n", record.name);
19 printf(" Subject : %s \n", record.subject);
20 printf(" Percentage : %f \n", record.percentage);
21 return 0;
22 }
OUTPUT:
Name :
Subject :
Percentage : 86.500000
NOTE:
We can access only one member of union at a time. We can’t access all member values at the same
time in union.
But, structure can access all member values at the same time. This is because, Union allocates one
common storage space for all its members. Where as Structure allocates storage space for all its
members separately.
DIFFERENCE BETWEEN STRUCTURE AND UNION IN C:
C Structure C Union
Union allocates one common storage
Structure allocates space for all its members.
storage space for all Union finds that which of its member
its members needs high storage space over other
separately. members and allocates that much
space
Structure occupies
higher memory Union occupies lower memory space
space. over structure.
We can access all
members of We can access only one member of
structure at a time. union at a time.
Structure example: Union example:
struct student union student
{ {
int mark; int mark;
char name[6]; char name[6];
double average; double average;
}; };
For above structure, For above union, only 8 bytes of
memory allocation memory will be allocated since
will be like below. double data type will occupy
int mark – 2B maximum space of memory over
char name[6] – 6B other data types.
double average – Total memory allocation=8 bytes
8B
Total memory
allocation = 2+6+8 =
16 Bytes
Enumeration (enum) is a user-defined datatype (same as structure). It consists of various elements of that type. There is
no such specific use of enum, we use it just to make our codes neat and more readable. We can write C programs without
using enumerations also.
For example, Summer, Spring, Winter and Autumn are the names of four seasons. Thus, we can say that these are of
types season. Therefore, this becomes an enumeration with name season and Summer, Spring, Winter and Autumn as its
elements.
So, you are clear with the basic idea of enum. Now let's see how to define it.
Defining an Enum
An enum is defined in the same way as structure with the keyword struct replaced by the keyword enum and the elements
separated by 'comma' as follows.
enum enum_name
{
element1,
element2,
element3,
element4,
};
Here, we have defined an enum with name 'season' and 'Summer, Spring, Winter and Autumn' as its elements.
We also declare an enum variable in the same way as that of structures. We create an enum variable as follows.
enum season{
Summer,
Spring,
Winter,
Autumn
};
main()
{
enum season s;
}
So, here 's' is the variable of the enum named season. This variable will represent a season. We can also declare an
enum variable as follows.
enum season{
Summer,
Spring,
Winter,
Autumn
}s;
All the elements of an enum have a value. By default, the value of the first element is 0, that of the second element is 1
and so on.
#include <stdio.h>
enum season{ Summer, Spring, Winter, Autumn};
int main()
{
enum season s;
s = Spring;
printf("%d\n",s);
return 0;
}
Output
Here, first we defined an enum named 'season' and declared its variable 's' in the main function as we have seen before.
The values of Summer, Spring, Winter and Autumn are 0, 1, 2 and 3 respectively. So, by writing s = Spring, we assigned
a value '1' to the variable 's' since the value of 'Spring' is 1.
We can also change the default value and assign any value of our choice to an element of enum. Once we change the
default value of any enum element, then the values of all the elements after it will also be changed accordingly. An
example will make this point clearer.
#include <stdio.h>
enum days{ sun, mon, tue = 5, wed, thurs, fri, sat};
int main()
{
enum days day;
day = thurs;
printf("%d\n",day);
return 0;
}
Output
The default value of 'sun' will be 0, 'mon' will be 1, 'tue' will be 2 and so on. In the above example, we defined the value of
tue as 5. So the values of 'wed', 'thurs', 'fri' and 'sat' will become 6, 7, 8 and 9 respectively. There will be no effect on the
values of sun and mon which will remain 0 and 1 respectively. Thus the value of thurs i.e. 7 will get printed.
#include <stdio.h>
enum days{ sun, mon, tue, wed, thurs, fri, sat};
int main()
{
enum days day;
day = thurs;
printf("%d\n",day+2);
return 0;
}
Output
In this example, the value of 'thurs' i.e. 4 is assigned to the variable day. Since we are printing 'day+2' i.e. 6 (=4+2), so the
output will be 6.
ARRAY OF STRUCTURE
Array of Structures in C
In C Programming, Structures are useful to group different data types to organize the data in a structural way.
And Arrays are used to group the same data type values. In this article, we will show you the Array of Structures in
C concept with one practical example.
For example, we are storing employee details such as name, id, age, address, and salary. We usually group them
as employee structure with the members mentioned above. We can create the structure variable to access or
modify the structure members. A company may have 10 to 100 employee, how about storing the same for 100
employees?
In C Programming, We can easily solve the problem mentioned above by combining two powerful concepts Arrays
of Structures in C. We can create the employee structure. Then instead of creating the structure variable, we create
the array of a structure variable.
Declaring C Array of Structures at structure Initialization
Let me declare an Array of Structures in C at the initialization of the structure
#include <stdio.h>
struct Student
{
char Student_Name[50];
int C_Marks;
int DataBase_Marks;
int CPlus_Marks;
int English_Marks;
};
int main()
{
int i;
struct Student Students[4] =
{
{"Suresh", 80, 70, 60, 70},
{"Tutorial", 85, 82, 65, 68},
{"Gateway", 75, 70, 89, 82},
{"Mike", 70, 65, 69, 92}
};
printf(".....Student Details....");
for(i=0; i<4; i++)
{
printf("\n Student Name = %s", Students[i].Student_Name);
printf("\n First Year Marks = %d", Students[i].C_Marks);
printf("\n Second Year Marks = %d", Students[i].DataBase_Marks);
printf("\n First Year Marks = %d", Students[i].CPlus_Marks);
printf("\n Second Year Marks = %d", Students[i].English_Marks);
}
return 0;
}
OUTPUT:
ANALYSIS
Within this Array of Structures in C example, We declared the student structure with Student Name, C Marks,
DataBase Marks, C++ Marks, and English Marks members of different data types.
Within the main() function, we created the array of structures student variable. Next, we initialized the appropriate
values to the structure members
In the Next line, we have For Loop in C Programming Condition inside the for loop. It will control the compiler not to
exceed the array limit. The below printf statements will print the values inside the student structure array.
First Iteration
Third Iteration
i value incremented by 1 using i++ incremental Operator. So, i becomes 4, and the i<4 condition Fails. So, the
compiler will exit from the loop.
PASSING ARRAY TO FUNCTION IN c
2. Or, we can have a pointer in the parameter list, to hold the base address of our array.
We will study the second way in details later when we will study pointers.
// statements
return x ;
We will discuss about this when we will study pointers with arrays.
#include<stdio.h>
int main()
int myArray[] = { 2, 3, 4 };
giveMeArray(myArray[2]); //Passing array element myArray[2] only.
return 0;
void giveMeArray(int a)
printf("%d", a);
#include<stdio.h>
int main()
float avg;
return 0;
int i, sum = 0;
float avg;
sum += marks[i];
return avg;
}
Passing a Multi-dimensional array to a function
Here again, we will only pass the name of the array as argument.
#include<stdio.h>
int main()
int arr[3][3], i, j;
scanf("%d", &arr[i][j]);
displayArray(arr);
return 0;
int i, j;
printf("\n");
printf("%d\t", arr[i][j]);
}
Please enter 9 numbers for the array:
123
456
789
U.N.S.I.E.T, VEER BAHADUR SINGH PURVANCHAL UNIVERSITY, JAUNPUR
DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING
UNIT-IV
NOTES For
BASIC ALGORITHM
SEARCHING AND BASIC SORTING ALGORITHMS
Searching Algorithms
Searching Algorithms are designed to check for an element or retrieve an element from any data structure
where it is stored. Based on the type of search operation, these algorithms are generally classified into two
categories:
1. Sequential Search: In this, the list or array is traversed sequentially and every element is checked. For
example: Linear Search.
2. Interval Search: These algorithms are specifically designed for searching in sorted data-structures.
These type of searching algorithms are much more efficient than Linear Search as they repeatedly target
the center of the search structure and divide the search space in half. For Example: Binary Search.
Linear Search
Problem: Given an array arr[] of n elements, write a function to search a given element x in arr[].
Examples :
Input : arr[] = {10, 20, 80, 30, 60, 50,
110, 100, 130, 170}
x = 110;
Output : 6
Element x is present at index 6
Binary Search
Given a sorted array arr[] of n elements, write a function to search a given element x in arr[].
A simple approach is to do linear search.The time complexity of above algorithm is O(n). Another approach to
perform the same task is using Binary Search.
Binary Search: Search a sorted array by repeatedly dividing the search interval in half. Begin with an interval
covering the whole array. If the value of the search key is less than the item in the middle of the interval,
narrow the interval to the lower half. Otherwise narrow it to the upper half. Repeatedly check until the value is
found or the interval is empty.
Example :
The idea of binary search is to use the information that the array is sorted and reduce the time complexity to
O(Log n).
Sorting Algorithms
A Sorting Algorithm is used to rearrange a given array or list elements according to a comparison operator on
the elements. The comparison operator is used to decide the new order of element in the respective data
structure.
For example: The below list of characters is sorted in increasing order of their ASCII values. That is, the
character with lesser ASCII value will be placed first than the character with higher ASCII value.
SELECTION SORT
Selection sort is a simple sorting algorithm. This sorting algorithm is an in-place comparison-based algorithm
in which the list is divided into two parts, the sorted part at the left end and the unsorted part at the right end.
Initially, the sorted part is empty and the unsorted part is the entire list.
The smallest element is selected from the unsorted array and swapped with the leftmost element, and that
element becomes a part of the sorted array. This process continues moving unsorted array boundary by one
element to the right.
This algorithm is not suitable for large data sets as its average and worst case complexities are of Ο(n2),
where n is the number of items.
How Selection Sort Works?
Consider the following depicted array as an example.
For the first position in the sorted list, the whole list is scanned sequentially. The first position where 14 is
stored presently, we search the whole list and find that 10 is the lowest value.
So we replace 14 with 10. After one iteration 10, which happens to be the minimum value in the list, appears
in the first position of the sorted list.
For the second position, where 33 is residing, we start scanning the rest of the list in a linear manner.
We find that 14 is the second lowest value in the list and it should appear at the second place. We swap these
values.
After two iterations, two least values are positioned at the beginning in a sorted manner.
The same process is applied to the rest of the items in the array.
Following is a pictorial depiction of the entire sorting process −
Now, let us learn some programming aspects of selection sort.
Algorithm
Step 1 − Set MIN to location 0
Step 2 − Search the minimum element in the list
Step 3 − Swap with value at location MIN
Step 4 − Increment MIN to point to next element
Step 5 − Repeat until list is sorted
#include <stdio.h>
int main()
{
int array[100], n, c, d, position, t;
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for (c = 0; c < n; c++)
scanf("%d", &array[c]);
for (c = 0; c < (n - 1); c++) // finding minimum element (n-1) times
{
position = c;
for (d = c + 1; d < n; d++)
{
if (array[position] > array[d])
position = d;
}
if (position != c)
{
t = array[c];
array[c] = array[position];
array[position] = t;
}
}
printf("Sorted list in ascending order:\n");
for (c = 0; c < n; c++)
printf("%d\n", array[c]);
return 0;
}
Output of program:
Bubble Sort
Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they
are in wrong order.
Example:
First Pass:
( 5 1 4 2 8 ) –> ( 1 5 4 2 8 ), Here, algorithm compares the first two elements, and swaps since 5 > 1.
( 1 5 4 2 8 ) –> ( 1 4 5 2 8 ), Swap since 5 > 4
( 1 4 5 2 8 ) –> ( 1 4 2 5 8 ), Swap since 5 > 2
( 1 4 2 5 8 ) –> ( 1 4 2 5 8 ), Now, since these elements are already in order (8 > 5), algorithm does not swap
them.
Second Pass:
( 1 4 2 5 8 ) –> ( 1 4 2 5 8 )
( 1 4 2 5 8 ) –> ( 1 2 4 5 8 ), Swap since 4 > 2
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
Now, the array is already sorted, but our algorithm does not know if it is completed. The algorithm needs
one whole pass without any swap to know it is sorted.
Third Pass:
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
Now, compare the second and the third elements. Swap them if they are not in order.
The array is sorted when all the unsorted elements are placed at their correct
bubbleSort(array)
for i <- 1 to indexOfLastUnsortedElement-1
if leftElement > rightElement
swap leftElement and rightElement
end bubbleSort
Another Example:
12, 11, 13, 5, 6
Let us loop for i = 1 (second element of the array) to 4 (last element of the array)
i = 1. Since 11 is smaller than 12, move 12 and insert 11 before 12
11, 12, 13, 5, 6
i = 2. 13 will remain at its position as all elements in A[0..I-1] are smaller than 13
11, 12, 13, 5, 6
i = 3. 5 will move to the beginning and all other elements from 11 to 13 will move one position ahead of their
current position.
5, 11, 12, 13, 6
i = 4. 6 will move to position after 5, and elements from 11 to 13 will move one position ahead of their current
position.
5, 6, 11, 12, 13
Algorithm
Now we have a bigger picture of how this sorting technique works, so we can derive simple steps by which we
can achieve insertion sort.
Step 1 − If it is the first element, it is already sorted. return 1;
Step 2 − Pick next element
Step 3 − Compare with all elements in the sorted sub-list
Step 4 − Shift all the elements in the sorted sub-list that is greater than the
value to be sorted
Step 5 − Insert the value
Step 6 − Repeat until list is sorted
o Sometimes, there are more than one way to solve a problem. We need to learn how to compare the
performance different algorithms and choose the best one to solve a particular problem. While
analyzing an algorithm, we mostly consider time complexity and space complexity. Time complexity of
an algorithm quantifies the amount of time taken by an algorithm to run as a function of the length of the
input. Similarly, Space complexity of an algorithm quantifies the amount of space or memory taken by
an algorithm to run as a function of the length of the input.
o Time and space complexity depends on lots of things like hardware, operating system, processors, etc.
However, we don't consider any of these factors while analyzing the algorithm. We will only consider
the execution time of an algorithm.
o Lets start with a simple example. Suppose you are given an array A and an integer x and you have to
find if x exists in array A.
o Order of growth is how the time of execution depends on the length of the input. In the above
example, we can clearly see that the time of execution is linearly depends on the length of the array.
Order of growth will help us to compute the running time with ease. We will ignore the lower order
terms, since the lower order terms are relatively insignificant for large input. We use different notation to
describe limiting behavior of a function.
o O-notation:
To denote asymptotic upper bound, we use O-notation. For a given function g(n), we denote
by O(g(n)) (pronounced “big-oh of g of n”) the set of functions:
O(g(n))= { f(n) : there exist positive constants c and n0 such that 0≤f(n)≤c∗g(n) for all n≥n0 }
o Ω-notation:
To denote asymptotic lower bound, we use Ω-notation. For a given function g(n), we denote
by Ω(g(n)) (pronounced “big-omega of g of n”) the set of functions:
Ω(g(n))= { f(n) : there exist positive constants c and n0 such that 0≤c∗g(n)≤f(n) for all n≥n0 }
o Θ-notation:
To denote asymptotic tight bound, we use Θ-notation. For a given function g(n), we denote
by Θ(g(n)) (pronounced “big-theta of g of n”) the set of functions:
Θ(g(n))= { f(n) : there exist positive constants c1,c2 and n0 such that 0≤c1∗g(n)≤f(n)≤c2∗g(n) for
all n>n0 }
o
o While analysing an algorithm, we mostly consider O-notation because it will give us an upper limit of the
execution time i.e. the execution time in the worst case.