Professional Documents
Culture Documents
FoP Theory Final
FoP Theory Final
WITH C LANGUAGE
E_mail: hatahilaa@gmail.com
1.1 Program
There is a close analogy between learning a language like English and learning
C language. The classical method of learning English is to first learn the
alphabets used in the language, then learn to combine these alphabets to form
words, which in turn are combined to form sentences and sentences are
combined to form paragraphs. Learning C is similar and easier. Instead of
straight- away learning how to write programs, we must first know what
alphabets, numbers and special symbols are used in C, then how using them.
Constants, variables and keywords are constructed, and finally how are these
combined to form an instruction. A group of instructions would be combined
later on to form a program.
Low level languages are machine level and assembly level languages.
The assembly language is on the other hand modified version of machine level
2
language. Where instructions are given in English like words such as ADD,
SUM, MOV etc. It is easy to write and understand but not understood by the
machine. So the translator used here is assembler to translate into machine
level. Although the language is a bit easier, a programmer has to know low level
details related to low level language. In the assembly level language, the data is
stored in the computer register, which varies for different computers. Hence,
the assembly language is not portable.
These languages are machine independent, which means they are portable.
Examples of languages in this category are Pascal, Cobol, Fortran, C, Python,
Java, etc.
3
1.2.2.1 Translator
Compiler and interpreter are used to convert the high-level language into
machine-level language.
Both compiler and interpreter perform the same task but how they work is
different. Compiler reads the program at-a-time and searches the errors and
lists them. If the program is error free then it is converted into an object
program. When program size is large then compiler is preferred. Whereas the
interpreter reads only one line of the source code and converts it to object code.
Interpreter checks errors, statement by statement and hence this process takes
more time.
4
CPUs use different programming languages.
5
Difference between Compiler and Interpreter
Compiler Interpreter
Translates the whole program to Translates and executes one line at
produce the executable object code. a time.
Compiled programs execute faster as Interpreted programs take more
they are already in machine code. time to execute because each
instruction is translated before
being executed.
Users do not need to have the Users must have the interpreter
compiler installed on their installed on their computer and
computer to run the software. they can see the source code.
Users cannot see the actual source Users can see the source code and
code when you distribute the can copy it.
program.
Used for software that will run Used for program development and
frequently or copying software sold when the program must be able to
to a third party. run on multiple hardware
platforms.
6
interpreter.
One statement
translated into
many machine
code
instructions.
Low- Assembly Translated using LDA1
level language an assembler. One 81
Languag statement ADD
e translated into 93
machine code STO1
instruction. 85
Machine Code Executable binary 110100101010000011
code produced 101010
either by a 00101101
compiler,
interpreter or
assembler.
Most software are developed using high-level languages for the following
reasons:
program in.
7
● Allowing the programmer to show how the algorithm will solve a problem
8
● Specialized high-level languages have been developed to make the
● It has features that make it suitable for the following types of applications:
On Mac OS X, CodeWarrior, Xcode and Eclipse are examples of IDEs that are
used by many programmers. Under Windows OS, Visual Studio Code, Eclipse,
NetBeans, CodeBlocks are good examples of popular IDEs. Kylix, Dev-C++,
Eclipse, NetBeans are popular IDEs for developing applications under Linux
OS.
There are two main ways that algorithms can be represented – pseudocode and
flowcharts.
A simple program could be created to ask someone their name and age, and to
make a comment based on these. This program represented in pseudocode would
look like the following two examples:
Example 1:
START
10
INPUT name
INPUT age
ELSE
END
Example 2:
START
END
Pseudocode Guide:
11
General Syntax
● IntExp, BoolExp, CharExp and StringExp means any expression which can
be evaluated to an integer, Boolean, character or string respectively.
● Exp means any expression
● Emboldened pseudocode is used to indicate the keywords/operators.
● In this material, indexing for arrays and strings starts at 0 unless
specifically stated otherwise.
1. a ← 3
Variable
Identifier ← Exp 2. a← a + 1
assignment
3. a← c – 2
constant PI ←3.141
constant constant
Constant
IDENTIFIER ← Exp
assignment CLASS_SIZE ← 23
Arithmetic Operations
9 DIV 5 evaluates to 1
8 DIV 4 evaluates to 2
12
9 MOD 5 evaluates to 4
5 MOD 2 evaluates to 1
Modulus IntExp MOD IntExp
8 MOD 4 evaluates to 0
operator
4<6
Less than Exp < Exp
3≤4
Less than
or equal Exp ≤ Exp 4≤4
to
4≥3
Greater than
4.5 ≥ 4.5
or equal to Exp ≥ Exp
Boolean Operations
(x < 1) OR (x > 9)
Logical OR BoolExp OR
BoolExp
NOT (another_go =
Logical NOT NOT BoolExp
False)
13
Condition-controlled Iteration
a←1
Repeat-until (repeat the statements REPEAT
REPEAT
until the Boolean expression is # statements here
PRINT a
True) UNTIL BoolExp
a←a+1
UNTIL a = 4
# will output 1 2 3
a←1
While (while the Boolean WHILE BoolExp WHILE a < 4
expression is True, repeat the # statements here PRINT a
statements) a←a+1
ENDWHILE
ENDWHILE
# will output 1 2 3
FOR a ← 1 TO 3
FOR Identifier ←IntExp TO IntExp
OUTPUT a
# statements here
ENDFOR
14
For ENDFOR
# will output 1 2 3
Selection
a←1
IF BoolExp THEN
# statements here IF (a MOD 2) = 0 THEN
OUTPUT 'even'
ELSE
ELSE
# statements here
If-else OUTPUT 'odd'
ENDIF
ENDIF
a←1
IF BoolExp THEN
IF (a MOD 4) = 0 THEN
# statements here
OUTPUT 'multiple of 4'
ELSE IF BoolExpTHEN
ELSE IF (a MOD 4) = 1 THEN
# statements here
OUTPUT 'leaves a remainder of1'
# possibly more
ELSE IF (a MOD 4) = 2 THEN
ELSE IFs
OUTPUT 'leaves a remainder of2'
ELSE
ELSE
# statements here
OUTPUT ‘leaves a remainder of 3’
ENDIF
ENDIF
Else-if
15
Arrays:
Arrays are fundamental data structures in computer programming that allow you to
store multiple values of the same data type in contiguous memory locations. They
play a crucial role in algorithms and are used to solve various computational
problems efficiently.
primes[0]
# evaluates to 2
# start indexing at
# otherwise
Accessing an Identifier[IntExp]
element
primes[5] ← 17
Updating an
# array is now [2,3,5,7,11,17]
element Identifier[IntExp] ← Exp
tables[3][1]
16
# evaluates to 8 as second element
array
tables[3][1] ← 16
tables is now
Updating an
element in a # [[1, 2, 3],
two- Identifier[IntExp][IntExp]←Exp
array
# [3, 6, 9],
# [4, 16, 12]
LEN(primes)
LEN(tables)
# evaluates to 4 using example above
LEN(tables[0])
# evaluates to 3 using example above
17
Comments
Flowchart
18
19
Examples of flowcharts
Sum =875
20
2.1. Qualities of a good algorithm
1. Input and output should be well defined with precision.
2. Each step in an algorithm should be clear and unambiguous.
3. An algorithm should be most effective among many different ways to solve
a problem.
4. An algorithm should be human understandable, it shouldn't have
computer code. Instead, the algorithm should be written in such a way
that it can be used in similar programming languages.
5. A good algorithm should be programming language independent, i.e can
be implemented by any software developer using any programming
language.
0. Start
1. Preheat the oven;
2. Mix flour, sugar, and other ingredients;
3. Pour into a baking pan;
4. Heat for some
times 5. … …
n. Stop
21
5. Compute A+B into Sum
6. Output Sum
7. Stop
Pseudo code
START
VAR A,B,
Sum; GET A;
GET B;
Sum←A+B;
PRINT Sum;
STOP
Flow chart
22
List of steps
1. Start
2. Declare Variables
c[n] # array to hold n numbers
max # to hold the maximum number
3. Assign the first number in the list to max
4. Iterate through all numbers in the list comparing the value of max to
the next number in the list. If the number in the list is greater than
max, change the value of max by the next number in the list.
5. Return max/Print max
6. End
Pseudocode
START
DECLARE C, max, i
C←[val1,val2,.....valn]
max←C[0]
FOR i←1 TO n-1
IF C[i]>max THEN
max←C[i]
ENDIF
ENDFOR
PRINT max
STOP
III. Calculate the sum and average of all even numbers between 1 and n
Pseudocode
START
VAR sum←0, average, i
23
INPUT n
FOR i←1 TO n
IF i MOD 2=0 THEN
sum←sum+i
ENDIF
ENDFOR
average←sum/n
PRINT average
END
IV. Write an algorithm to find the largest among three different numbers
Pseudocode
START
DECLARE n1, n2, n3, largest
INPUT n1,n2,n3
IF n1>n2 THEN
IF n1>n3 THEN
n1←largest
ELSE IF n3>n1 THEN
n3←largest
ENDIF
ELSE IF n2>n1 THEN
n2←largest
END IF
PRINT largest
END
24
V. Write an algorithm to check whether a number entered by a user is
prime or not.
Algorithm:
START
DECLARE n, lv, flag←1
INPUT n
FOR lv←n-1 To 3
IF n%lv=0 THEN
flag←0
BREAK
END IF
END FOR
IF flag = 0 THEN
PRINT “n is not prime”
ELSE
PRINT “n is prime”
END IF
STOP
VI. Define an algorithm to find the number of digits in any given positive
integer number n.
For example, if n is 10, the number of digits is 2 (1 and 0), if n is 527, the
number of digits is 3 (5, 2 and 7)
1. START
2. VAR n, counter←0
3. INPUT n
4. REPEAT
5. n←n DIV 10 # integer division
6. counter←counter+1 # increment counter by one
7. UNTIL n=0
8. RETURN/OUTPUT counter #counter will store the number of digits
9. END
25
VII. Define an algorithm to find the greatest common divisor (GCD)
between to numbers
26
CHAP 3: C DATA TYPES
Prerequisite:
1. Number systems:
https://docs.google.com/document/d/1OtiVijwX7A96kC1ifrE3KHj1U-
UgpvhN/edit?
usp=sharing&ouid=111492439619719304666&rtpof=true&sd=true
2.
Broadly, there are 5 different categories of data types in the C language, they
are:
Category Example
Primary character, integer, floating-point,
double.
Derived Array, structure, union, pointer,
function.
Enumeration Enums
Bool type true or false
Void Empty value
The C language has 5 basic (primary or primitive) data types, they are:
27
There are different keywords to specify these data types, the keywords are:
Datatype Keyword
Character char
Integer int
Floating-point float
Double double
Void void
Each data type has a size defined in bytes (B(1B=8 bits(b))) and has a range for
the values that these data types can hold.
The size for different data types depends on the compiler and processor types,
in short, it depends on the Computer on which you are running the C language
and the version of the C compiler that you have installed.
3.1.1.1. character
The char datatype is 1 byte in size or 8 bits. This is mostly the same and is not
affected by the processor or the compiler used.
3.1.1.2. integer
There is a very easy way to remember the size for integer data type. The size of
the integer data type is usually equal to the word length of the execution
environment of the program. In simpler words, for a 16- bit environment,
integer is 16 bits or 2 bytes, and for a 32-bit environment, int is 32 bits or 4
bytes. Unfortunately, this rule is not applicable in a 64-bit environment
where the size remains the same as in a 32-bit environment.
28
3.1.1.3. float
float is a faster data type as compared to double, because double data type
works with very large values, hence it is slow.
3.1.1.4. double
The double datatype is 8 bytes or 64 bits in size. It can store values that are
double the size of what a float data type can store, hence it is called double.
In the 64 bits, 1 bit is for sign representation, 11 bits for the exponent, and
the rest 52 bits are used for the mantissa.
The double data type can hold approximately 15 to 17 digits, before the
decimal and after the decimal.
3.1.1.5. void
The void data type is 0 bytes means nothing, hence it doesn't have a size.
Before moving on to the range of values for these data types, there is one more
important concept to learn, which is Data Type modifiers.
In the C language, there are 4 data type modifiers that are used along with
the basic data types to categorize them further.
For example, if you say, there is a playground, the other person will know that
there is a playground, but you can be more specific and say, there is a Cricket
29
playground or a Football playground, which makes it even more clear for the
other person.
Similarly, there are modifiers in the C language, to make the primary data
types more specific. Following are the modifiers:
6. signed
7. unsigned
8. long
9. short
As the name suggests, signed and unsigned are used to represent the signed (+
and -) and unsigned (only +) values for any data type. And long and short
affects the range of the values for any datatype.
For example, signed int, unsigned int, short int, long int, etc. are all valid
data types in the C language.
Now let's see the range for different data types formed as a result of the 5
primary data types along with the modifiers specified above.
In the table below we have the range for different data types in the C language.
Format
Typ Typical Size in Minimal Range
Specifier
e Bits
Char 8 -128 to 127 %c
unsigned char 8 0 to 255 %c
signed char 8 -128 to 127 %c
Int 16 or 32 -32,768 to 32,767 %d, %i
unsigned int 16 or 32 0 to 65,535 %u
signed int 16 or 32 Same as int %d, %i
30
short int 16 -32,767 to 32,767 %hd
unsigned short 16 0 to 65,535 %hu
int
signed short int 16 Same as short int %hd
long int 32 -2,147,483,648 to %ld, %li
2,147,483,647
-(263 - 1) to 263 - 1
long long int 64 %lld, %lli
(Added by C99
standard)
signed long int 32 Same as long int %ld, %li
unsigned long int 32 0 to 4,294,967,295 %lu
As you can see in the table above, with different combinations of the datatype
and modifiers the range of value changes.
31
When we want to print the value for any variable with any data type, we have
to use a format specifier in the printf() statement.
Well, if you try to assign a value to any datatype which is more than the allowed
range of value, then some C language compiler will give an error and others will
give a warning. Here is a simple code example to show this,
When a type modifier is used without any data type, then the int data type
is set as the default data type. So, unsigned means unsigned int, signed
means signed int, long means long int, and short means short int.
32
This is a little tricky to explain, but let's try.
In simple words, the unsigned modifier means all positive values, while the
signed modifier means both positive and negative values.
When the compiler gets a numeric value, it converts that value into a binary
number, which means a combination of 0 and 1. For example, 32767 in binary
is 01111111 11111111, and 1 in binary
is 01 (or 0001), 2 is 0010, and so on.
In the case of a signed integer, the Most Significant Bit(MSB) which is the
highest order bit or the first digit from left (in binary) is used as the sign flag. If
the sign flag is 0, the number is positive, and if it is 1, the number is
negative.
And because one bit is used for showing if the number is positive or negative,
hence there is one less bit to represent the number itself, hence the range is
less.
For signed int, 11111111 11111111 means -32,767 and because the first bit
is a sign flag to mark it as a negative number, and rest represent the number.
Whereas in the case of unsigned int, 11111111 11111111 means 65,535.
Some c Compiler obliged the variable initialization after during the declaration.
34
The following are the initial values to be given for best practices, even if they can
be changed depending on the problem to be solved.
int 0
char '\0'
float 0
double 0
void nothing
Derived data types are nothing but primary data types a little twisted or grouped
together like array, function types, structure, union, pointer etc.
As data type determines the type of data a variable can hold; Then I can confirm
that : “ If a variable x is declared as type int, then it means that x will only hold
integer values for its whole life !”. Every variable which is used in the program
must be declared as what data-type it is.
3.3.1. Arrays
For example,
35
int data[100];
states that ”data” is a variable capable of storing one hundred integer numbers.
So, it behaves like a collection of a hundred variables of the same type, int.
The size and type of arrays cannot be changed after its declaration.
For example, if we want an array of six integers (or whole numbers), we write:
You can also initialize as you declare. Just put the initial elements in
curly brackets separated by commas as the initial values:
36
type name[number of elements]={my comma-separated values}, please note that
values in an array are comma separated.
For example, if we want to initialize an array with six integers, with 0, 0, 1, 0, 0, 0
as the initial values then we will easily do it as bellow:
int point[6]={0,0,1,0,0,0};
Though when the array is initialized as in this case, the array dimension may be
omitted, and the array will be automatically sized to hold the initial data,interesting
that the size of an array can dynamically be determined at run time:
int point[]={0,0,1,0,0,0};
This is very useful in that the size of the array can be controlled by simply adding
or removing initialized elements from the definition without the need to adjust the
size.
If the size is specified, but not all elements in the array are initialized, the
remaining places will contain a default value of that data type like 0 in the above
case of integers. This is very useful, especially when we have very large arrays.
int numbers[2000]={25};
The above example sets the first value of the array of numbers to 25, and the rest
to 0 s.
How to initialize an array?
Suppose you declare an array called point as indicated below. The first element is
point[0], second element is point[1] and so on until when you reach the 6 th
37
element.
The compiler may not complain about the following (though the best compilers
do):
char point[6] = { 1, 2, 3, 4, 5, 6 };
38
//examples of accessing outside the array. A compile error is not always raised
y = point[15];//the array index out of bound is not thrown but really the error has
occurred
y = point[-4];//the array index out of bound is not thrown but really the error has
occurred
y = point[z];//the array index out of bound is not thrown but really the error has
occurred
Note: Your program will run but actually it is erroneous, so unexpected results.
If we want to access a variable stored in an array, for example with the above
declaration, the following code will store 3 in the variable x
int x;
During program execution, an out of bounds array access does not always cause a
runtime error. Your program may happily continue after retrieving a value from
point[-1]. To alleviate indexing problems, the sizeof() expression is commonly used
when coding loops that process arrays.
Many people use a macro that in turn uses sizeof() to find the number of elements
in an array, a macro variously named "lengthof()","MY_ARRAY_SIZE()" or
"NUM_ELEM()","SIZEOF_STATIC_ARRAY()",etc.
int ix;
Notice in the above example, the size of the array was not explicitly specified but
the compiler will know how to size it at 5 because of the five values in the
initialization.
39
Adding an additional value to the list will cause it to be sized to six, and because
of the sizeof expression in the for loop, the code automatically adjusts to this
change. Good programming practice is to declare a variable size , and let it store
the number of elements in the array.
40
Int size = sizeof(anArray)/sizeof(short) Few
key notes:
• Arrays have 0 as the first index not 1. In this example, marks[0]
• If the size of an array is n, to access the last element, n-1 index is used. In
this example, marks[1999] , ok n-1 is equal to 1999 as n was
C also supports multidimensional arrays (or, rather, arrays of arrays). The simplest
type is a two dimensional array.
Each row has the same number of columns and each column has the same
number of rows. For example to declare a char array with 3 rows and 5 columns
we write in C
char two_d[3][5];
two_d[0][0] = 'x'; // Array initialization ie. putting an element x at the row 0 and
column 0 indexes.
Similarly, a two-dimensional array can be initialized like this:
41
int two_d[2][3] = {
};
42
The amount of columns must be explicitly stated; however, the compiler will find
the appropriate amount of rows based on the initialized list.
Example 2:
float x[3][4];
Here, x is a two-dimensional (2d) array. The array can hold 12 elements. You can
think of the array as a table with 3 rows and each row has 4 columns as illustrated
below:
float y[2][4][3];
int c[2][3] = {
{1, 3, 0},
{-1, 5, 9}
};
43
int c[][3] = {
{1, 3, 0},
{-1, 5, 9}
};
int test[2][3][4] = {
3.3.1.1. STRINGS
Before you can work with strings, you need to declare them first. Since string is an
array of characters. You declare strings in a similar way like you do with character
arrays.
Here's how you declare a string s:
char s[5];
5 memory address locations are allocated from the size 5 of the array.
44
You can initialize strings in a number of ways.
All of the above four initialization statements will create a string c (character array )
to just hold 5 characters.
You can use the scanf() function from the stdio library to read a string.
#include <stdio.h>
int main()
{
45
char name[20];
printf("Enter name: ");
scanf("%s", name);
printf("Your name is %s.", name);
return 0;
}
Output:
Even though Dennis Ritchie was entered in the above program, only "Dennis"
was stored in the name string. It's because there was a space after Dennis.
3.3.1.1.3. Then How to read a line of text as it contains some white spaces?
And, you can use puts() or printf () functions to display the string on the console.
#include <stdio.h>
int main()
char name[30];
printf("\n");
46
return 0;
C has no string handling facilities built in; consequently, strings are defined as
arrays of characters; I repeat as arrays of characters OK. C allows a character
array to be represented as a character string rather than a list of characters, good!
With the null terminating character automatically added to the end. For example, to
store the string "MUKAJISTOS", we would write
In the first example, the string will have a null character ('\0') automatically
appended to the end by the compiler; by convention, library functions expect strings
to be terminated by a null character ('\0'). The latter declaration indicates individual
elements, and as such the null terminator ('\0') needs to be added manually.
Strings do not always have to be linked to an explicit variable. As you have
seen already, a string of characters can be created directly as an unnamed
string that is used directly (as with the printf functions.)
To create an extra long string, you will have to split the string into multiple sections,
by closing the first section with a quote, and recommencing the string on the next
line (also starting and ending in a quote):
char string[58] = "This is a very, very long " "string that requires two lines.";
While strings may also span multiple lines by putting the backslash character at
the end of the line, this method is deprecated.
There is a useful library of string handling routines which you can use by including
another header file.
47
#include <string.h> //new header file
This standard string library will allow various tasks to be performed on strings.
You need to often manipulate strings according to the need of a problem. Most, if not
all, of the time string manipulation can be done manually but, this makes
programming complex and large. To solve this, C supports a large number of string
handling functions in the standard library "string.h".
Classwork: Every student is requested to find a real word case each of those functions
is required and use them in a C program.
48
3.3.1.1.5. Passing Strings to Function
Strings can be passed to a function in a similar way as arrays.
Example
#include <stdio.h>
#include<string.h>
void displayString(char str[]);
int main(){
char str[50];
printf("Enter string: ");
fgets(str, sizeof str, stdin);
displayString(str);// Passing string to function return 0;
}
void displayString(char str[])
{
printf("The passed String was: ");
puts(str);
}
Sample output:
C has no string handling facilities built in; consequently, strings are defined
as arrays of characters; I repeat as arrays of characters OK. C allows a
character array to be represented as a character string rather than a list of
characters, good! With the null terminating character automatically added to
the end. For example, to store the string "MUKAJISTOS", we would write
char string[10] =
"MUKAJISTOS"; or
char string[10] = {'M', 'U', 'K', 'A', 'J', 'I', 'S', 'T', 'O', 'S', '\0'};
In the first example, the string will have a null character ('\0') automatically
appended to the end by the compiler; by convention, library functions expect
strings to be terminated by a null character ('\0'). The latter declaration
indicates individual elements, and as such the null terminator ('\0') needs to
be added manually.
49
Strings do not always have to be linked to an explicit variable. As you have
seen already, a string of characters can be created directly as an unnamed
string that is used directly (as with the printf functions.)
To create an extra long string, you will have to split the string into multiple
sections, by closing the first section with a quote, and recommencing the string
on the next line (also starting and ending in a quote):
char string[58] = "This is a very, very long " "string that requires two
lines.";
While strings may also span multiple lines by putting the backslash
character at the end of the line, this method is deprecated.
There is a useful library of string handling routines which you can use by
including another header file.
This standard string library will allow various tasks to be performed on strings.
50
3.3.1.2. Sorting an array
Computers are designed to quickly and merrily accomplish boring tasks, such as
sorting an array. In fact, they love doing it so much that “the sort” is a basic
computer concept upon which many theories and algorithms have been written.
The simplest sort is the bubble sort, which not only is easy to explain and
understand but also has a fun name(Bubble Sort). It also best shows the basic
array-sorting philosophy, which is to swap values between two elements. Goog now
we all know what sorting is really about!! It is about swapping elements: SIMPLE
Bubble Sort is a simple algorithm which is used to sort a given set of n elements
provided in the form of an array with n number of elements. Bubble Sort compares
all the elements one by one and sorts them based on their values.
If the given array has to be sorted in ascending order, then bubble sort will start by
comparing the first element of the array with the second element, if the first element
is greater than the second element, it will swap both the elements, and then move
on to compare the second and the third element, and so on.
51
If we have total of n elements, then we need to repeat this process for n-1
times.
It is known as bubble sort, because with every complete iteration the largest
element in the given array, bubbles up towards the last place or the highest index,
just like a water bubble rises up to the water surface.
Sorting takes place by stepping through all the elements one-by-one and comparing
it with the adjacent element and swapping them if required.
Implementing Bubble Sort Algorithm
Following are the steps involved in bubble sort(for sorting a given array in ascending
order):
1. Starting with the first element(index = 0), compare the current element with
the next element of the array.
2. If the current element is greater than the next element of the array, swap
them.
3. If the current element is less than the next element, move to the next
element. Repeat Step 1.
Let's consider an array with values {5, 1, 6, 2, 4, 3}
Below, we have a pictorial representation of how bubble sort will sort the given
array.
52
So as we can see in the representation above, after the first iteration, 6 is placed at
the last index, which is the correct position for it.
Similarly after the second iteration, 5 will be at the second last index, and so on.
53
3.3.1.2.2. Selection sort
Selection sort is conceptually the most simplest sorting algorithm. This algorithm
will first find the smallest element in the array and swap it with the element in the
first position, then it will find the second smallest element and swap it with the
element in the second position, and it will keep on doing this until the entire array
is sorted. Not that now we are doing ascending order sorting; so, for
descending you will just change the direction of the comparison operator
It is called selection sort because it repeatedly selects the next-smallest /greatest
element and swaps it into the right place.
Following are the steps involved in selection sort(for sorting a given array in
ascending order):
1. Starting from the first element, we search the smallest element in the array,
and replace it with the element in the first position.
2. We then move on to the second position, and look for the smallest element
present in the sub array, starting from index 1, till the last index.
3. We replace the element at the second position in the original array, or
we can say at the first position in the sub array, with the second smallest
element.
4. This is repeated, until the array is completely sorted.
In the first pass, the smallest element will be 1, so it will be placed at the first
position.
Then leaving the first element, the next smallest element will be searched,
from the remaining elements. We will get 3 as the smallest, so it will be then
placed at the second position.
54
Then leaving 1 and 3(because they are at the correct position), we will search
for the next smallest element from the rest of the elements and put it at third
position and keep doing this until the array is sorted.
In the C program below, we have tried to divide the program into small
functions, so that it's easier for you to understand which part is doing
55
what.There are many different ways to implement selection sort algorithm, here
is the one that we like:
}
/* the function that prints the content of
any size array*/
void printArray(int array[], int size)
{
int i;
for(i = 0; i < size; i++)
{
printf("%d ", array[i]);
}
printf("\n");
}
int main()
{
int array[] = {46, 52, 21, 22, 11};
int n = sizeof(array)/sizeof(array[0]);
selectionSort(array, n);
57
printf("Sorted array: \n");
printArray(array, n);
return 0;
}
Note: Selection sort is an unstable sort i.e it might change the occurrence of
two similar elements in the list while sorting. But it can also work as a stable
sort when it is implemented using a linked list. Oohh my God yoyoooo !! What
are those Linked lists? I wish you would wait until when you do the course of
data structures and algorithms, I like C programming almost everything was
thought of..
58
3.3.1.2.3. Insertion sort
Consider you have 10 cards out of a deck of cards in your hand. And they are
sorted, or arranged in the ascending order of their numbers.
If I give you another card, and ask you to insert the card in just the right position, so
that the cards in your hand are still sorted. What will you do?
Well, let me guess : “ you will have to go through each card from the starting or the
back and find the right position for the new card, comparing its value with each
card” Right ? . Ok, Once you find the right position, you will insert the card
there,Right ! You have done insertion, but is it an insertion sort ?
Similarly, if more new cards are provided to you, you can easily repeat the same
process and insert the new cards and keep the cards sorted too.
This is exactly how insertion sort works. It starts from index 1(not 0), and each
index starting from index 1 is like a new card that you have to take from the right
sub array(unsorted) to the sorted sub array on the left.
1. It is efficient for smaller data sets, but very inefficient for large lists.
2. Insertion Sort is adaptive, that means it reduces its total number of steps if a
partially sorted array is provided as input, making it efficient.
3. It is better than Selection Sort and Bubble Sort algorithms.
4. Its space complexity is less. Like bubble Sort, insertion sort also requires a
single additional memory space.
5. It is a stable sorting technique, as it does not change the relative order of
elements which are equal
59
How Insertion Sort Works?
1. We start by making the second element of the given array, i.e. element at
index 1, the key. The key element here is the new card that we need to add to
our existing sorted set of cards(remember the example with cards above).
2. We compare the key element with the element(s) before it, in this case,
element at index 0:
• If the key element is less than the first element, we insert the key
• If the key element is greater than the first element, then we insert it
after the first element.
3. Then, we make the third element of the array as key and will compare it
with elements to its left and insert it at the right position.
4. And we go on repeating this, until the array is sorted.
Below, we have a pictorial representation of how bubble sort will sort the given
array.
60
As you can see in the diagram above, after picking a key, we start iterating over
the elements to the left of the key.
61
#include <stdio.h>
// main function
int main()
insertionSort(array, 8);
return 0;
int i, j, key;
j = i;
62
key = array[j];
array[j - 1] = key;
j--;
printArray(array, length);
int j;
printf(" %d ",array[j]);
printf("\n");
Now let's try to understand the above simple insertion sort algorithm.
We took an array with 8 integers. We took a variable key, in which we put each
element of the array, during each pass, starting from the second element, that is
63
a[1].
Then using the while loop, we iterate, until j becomes equal to zero or we find an
element which is greater than key, and then we insert the key at that position.
We keep on doing this, until j becomes equal to zero, or we encounter an element
which is smaller than the key, and then we stop. The current key is now at the
right position.
We then make the next element as key and then repeat the same process.
In the above array, first we pick 1 as key, we compare it with 5(element before 1), 1
is smaller than 5, we insert 1 before 5. Then we pick 6 as key, and compare it with
5 and 1, no shifting in position this time. Then 2 becomes the key and is compared
with 6 and 5, and then 2 is inserted after 1. And this goes on until the complete
array gets sorted.
64
We continue to move towards the left if the elements are greater than the key
element and stop when we find the element which is less than the key element.
And, insert the key element after the element which is less than the key element.
Implementing Insertion Sort Algorithm:
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 procedure or subroutine in other
programming languages.
Advantage of functions in C
- By using functions, we can avoid rewriting the same logic/code again and
again in a program.
- We can call C functions any number of times in a program and from any place
in a program.
- We can track a large C program easily when it is divided into multiple
functions.
- Reusability is the main achievement of C functions.
Function Aspects
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.
# Function Syntax
aspect
NB:
- In function declaration, parameters’ list can be replaced by the list of their
types only. For example the function declaration void myFunction(int i,
char c, float f); can be replaced by void myFunction(int, char, float);
- The function declaration is not mandatory for some c compilers
66
1. Library Functions: are the functions which are declared in the C header files such as
scanf(), printf(), gets(), puts(), ceil(), floor(), sin(), cos() etc. To use a function among these,
you must use the preprocessor directive having the header file in which that function is
defined.
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.
A function may or may not accept any argument. It may or may not return any
value. Based on these facts, There are four different aspects of function calls.
#include<stdio.h>
//Defining the function display()
void display(){
char names[50];
printf("Enter your names: \n");
fgets(names, sizeof (names), stdin);
printf("You said your names are: \n");
puts(names);
}
int main(){
display();//calling the function display()
return 0;
}
When you compile and run the above code, the result should look like this:
67
Example of a function without arguments and with return value
#include<stdio.h>
//Defining the function add()
void add(int a, int b){
printf("The sum of %d and %d is %d \n", a,b,a+b);
}
int main(){
int n1,n2;
printf("\n Enter two integers \n");
scanf("%d%d",&n1,&n2);
add(n1,n2);//calling the function add()
return 0;
}
And this is the sample execution of this program:
68
s=sum(n1,n2);//calling the function sum
printf("The calculated sum is %d ",s);
return 0;
}
with the following sample of output:
}
Which produce the following sample output:
The C programming language allows any of its functions to call itself multiple times
in a program. Here, any function that happens to call itself again and again (directly
69
or indirectly), unless the program satisfies some specific condition/subtask is called
a recursive function.
In C language, recursion refers to the process in which a function repeatedly calls
its multiple copies when working on some very small problem. Here, the functions
that keep calling themselves repeatedly in a program are known as the recursive
functions, and such types of functions in which the recursive functions call
themselves are known as recursive calls.
The process of recursion in the C language consists of multiple recursive calls. And,
it is also a prerequisite that you choose a termination condition for the recursive
function- or else, the program will be stuck in a loop.
if (base_test)
return given_value;
else if (another_base_test)
return other_given_value;
else
recursive call;
70
It is simple to understand how a recursive function works in the C language. It
involves certain tasks and divides them into various subtasks. Some of the subtasks
consist of termination conditions/conditions. These subtasks need to satisfy these
conditions to terminate the program. Else, as discussed above, a never-ending loop
will be created.
Next, the process of recursion finally stops, and we then get to derive the final result
from the recursive function. Here, we also have the concept of the base case. A base
case refers to the case where the function doesn’t recur, and thus, we have the base
case. There are various instances when the recursive function tries to perform a
subtask by repeatedly calling itself. It is known as the recursive case.
Let us take a look at the format used for writing the recursive function in C.
Examples
Here, we will write a C program that prints the 10th values of the Fibonacci series in
the form of output.
#include<stdio.h>
int numberfibonacci(int);
void main ()
int a,b,i;
printf("Please enter the value of the n number here (index on item in Fibonacci series) : ");
scanf("%d",&a);
b= numberfibonacci(a);
int numberfibonacci(int a)
71
if (a==0)
return 0;
else if (a == 1)
return 1;
else
The sample output generated here from the code mentioned above would be like this:
Let us take a look at another example. We will write a program in C that finds the factorial of
an available number using the recursive function and not loops.
#include<stdio.h>
if(n==0||n==1)
return 1;
72
else
return n*factorial(n-1);
int main(){
int number;
scanf("%d", &number);
return 0;
The sample output generated here from the code mentioned above would be:
Recursion makes the program elegant and more readable. However, if performance
is vital then, use loops instead as recursion is usually much slower.
Note that every recursion can be modeled into a loop.
Need performance, use loops, however, code might look ugly and hard to read
sometimes. Need more elegant and readable code, use recursion, however, you are
sacrificing some performance. Now you know both, it's up to you to let us know how
good a programming analyst you are.
Exercises:
1. Define a function rectangleArea which receives two sides (side1 and side2) of
73
a rectangle as arguments. The function should then return the area of that
rectangle.
N.B: The values of arguments are assigned at run time, which means that the
function rectangleArea will calculate the area of any rectangle.
2. Write a program in C to find the sum of the series 1+½!+ ⅓!+¼!+ ⅕!+...+1/n!
using the user defined function(s).
N.B: n is given at run time and passed to the function as argument
3. Define a function in a c program which swaps two numbers
Before you get into the concept of pointers, let's first get familiar with addresses
in C.
If you have a variable var in your program, &var will give you its address in the
memory, where & is commonly called the reference operator.
You must have seen this notation while using scanf() function. It was used in
the function to store the user inputted value in the address of var, I know you
have already seen the magic “&”.
Output
74
Note: You may obtain different values of address while using this code.
In above source code, value 5 is stored in the memory location 0x7ffcac23e854. var
is just the name given to that location.
In C, you can create a special variable that stores the address (rather than the
value). This variable is called a : “pointer variable” or simply a: ”pointer”.
Note: The * sign when declaring a pointer is not a dereference operator. It is just a
similar notation that creates a pointer.
#include <stdio.h>
int main()
{
int * pc, c;
c = 22;
75
printf("Address of c: %p\n", &c);
printf("Value of c: %d\n\n", c);
pc = &c;
printf("Address of c: %p\n", pc);
printf("Content pointed by pc: %d\n\n", *pc);
c = 11;
printf("Address of c: %p\n", pc);
printf("Content pointed by pc: %d\n\n", *pc);
1. int* pc, c;
Here, a pointer pc and a normal variable c, both of type int, is created. Since
pc and c are not initialized at first, pointer pc points to either no address or a
random address. And, variable c has an address but contains a random
76
garbage value.
2. c = 22;
3. pc = &c;
5. *pc = 2;
There are two methods to pass the data into the function in C language, i.e.,
call by value and call by reference.
Call by value
77
- In the call by value method, the value of the actual parameters is copied
into the formal parameters. In other words, we can say that the value of the
variable is used in the function call in the call by value method.
- In the call by value method, we can not modify the value of the actual
parameter by the formal parameter.
- The actual parameter is the argument which is used in the function call
whereas the formal parameter is the argument which is used in the function
definition.
Call by reference
Example 1:
#include <stdio.h>
78
* of variable num, which means the increment is actually done
*/
*var = *var+1;
int main()
int num=20;
*/
increment(&num);
return 0;
When the code above is compiled and executed, it produces the following result:
79
Example 2: Swapping Numbers
#include<stdio.h>
int tempnum ;
tempnum = *var1 ;
*var1 = *var2 ;
*var2 = tempnum ;
int main( )
printf("Before swapping:");
80
swapnum( &num1, &num2 );
printf("\nAfter swapping:");
return 0;
int a = 5;
int *ptr = NULL;
81
memory location of 0x8130 then the value of ptr will be 0x8130 after the
assignment. To dereference the pointer, an asterisk is used again:
*ptr = 8;
82
This means take the contents of ptr (which is 0x8130), "locate" that address in
memory and set its value to 8. If a is later accessed again, its new value will be
8. Which means :”A pointer can change the value of a variable!”
This example may be clearer if memory is examined directly. Assume that a is
located at address 0x8130 in memory and ptr at 0x8134; also assume this is a 32-
bit machine such that an int is 32-bits wide. The following is what would be in
memory after the following code snippet is executed:
int a = 5;
int *ptr = NULL;
Address Contents
0x8130 0x00000005
0x8134 0x00000000
(The NULL pointer shown here is 0x00000000.) By assigning the address of a to ptr:
ptr = &a;
yields the following memory values:
Address Contents
0x8130 0x00000005
0x8134 0x00008130
Clearly, accessing a will yield the value of 8 because the previous instruction
modified the contents of a by way of the pointer ptr.
Common mistakes when working with pointers
Suppose, you want a pointer pc to point to the address of c. Then,
83
int c, *pc;
// Wrong! pc is address whereas,
// c is not an address.
pc = c;
// Wrong! *pc is the value pointed by address whereas,
// &c is an address.
pc = &c;
// Correct! pc is an address and,
// &c is also an address.
ptr = &a;
// Correct! * ptr is the value pointed by address and,
// c is also a value (not address).
*pc = c;
Similarly like arrays, string names are "decayed" to pointers. Hence, you can use a
pointer with the same name as string to manipulate elements of the string.
#include <stdio.h>
int main(void) {
char name[] = "Harry Potter"; // A string initialization as a array of characters
char *namePtr;
namePtr = name;
84
}
Output:
In C, memory is allocated dynamically using standard library functions malloc(), calloc(), free()
and realloc() defined in the stdlib.h header file.
As you know, an array is a collection of a fixed number of values. Once the size of an array is
declared, you cannot change it.
Sometimes the size of the array you declared may be insufficient. To solve this issue, you can
allocate memory manually during run-time. This is known as dynamic memory allocation in C
programming.
C malloc()
The malloc() function reserves a block of memory of the specified number of bytes. And, it returns
a pointer of void which can be casted into pointers of any form.
Syntax of malloc()
Example
The above statement allocates 400 bytes of memory. It's because the size of the float is 4 bytes.
And, the pointer ptr holds the address of the first byte in the allocated memory.
85
C calloc()
The malloc() function allocates memory and leaves the memory uninitialized, whereas the calloc()
function allocates memory and initializes all bits to zero.
Syntax of calloc()
Example:
The above statement allocates contiguous space in memory for 25 elements of type float.
C free()
Dynamically allocated memory created with either calloc() or malloc() doesn't get freed on their
own. You must explicitly use free() to release the space.
Syntax of free()
free(ptr);
This statement frees the space allocated in the memory pointed by ptr.
#include <stdio.h>
#include <stdlib.h>
86
int main() {
int n, i, *ptr, sum = 0;
87
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i, *ptr, sum = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
C realloc()
If the dynamically allocated memory is insufficient or more than required, you can change the size
of previously allocated memory using the realloc() function.
88
Syntax of realloc()
Example 3: realloc()
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr, i , n1, n2;
printf("Enter size: ");
scanf("%d", &n1);
free(ptr);
89
return 0;
}
Sample Output
1504083730344972
1504083730345036
(Previously allocated )
and
1504083730344972
1504083730345036
1504083730345100
(Newly allocated)
90
3.3.3.6. Benefits of using pointers
91
3.3.4. STRUCTURES
Here is an example:
struct Person{
char name[50];
int citNo;
float salary;
};
Here, a derived data type Person is defined.
92
Here's how we create structure variables:
struct Person
{
char name[50];
int citNo;
float salary;
}person0, person2, Peter, Moses,Nina,Rwema;//one way
int main()
{
Person person1, person2, persons[20]; //variable declaration using Person
structure
return 0;
}
93
Another way of creating a structure variable is:
struct Person
{
char name[50]; int
citNo;
float salary;
} person1, person2, persons[20];
There are two types of operators used for accessing members of a structure.
1. Member operator(.)
2. Structure pointer operator(->) (this will be discussed in structure and
pointers)
Suppose, you want to access salary of person2. Here's how you can do it:
person2.salary // Very simple
Example:
// Program to add two distances which is in feet and inches
#include <stdio.h>
struct Distance
int feet;
float inch;
int main()
94
{
printf("1st distance\n");
scanf("%d", &dist1.feet);
scanf("%f", &dist1.inch);
printf("2nd distance\n");
scanf("%d", &dist2.feet);
scanf("%f", &dist2.inch);
// adding feet
// adding inches
++sum.feet;
95
sum.inch = sum.inch - 12;
return 0;
Sample Output
96
3.3.4.4. Keyword typedef In C
int feet;
float inch;
};
int main() {
Distance d1, d2;
}
is equivalent to
typedef struct Distance{
int feet;
float inch;
} distances;
int main() {
distances d1, d2, sum; // declaring variable using typedof
}
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.. Following is the general syntax for using typedef,
typedef <existing_name> <alias_name>
Let's take an example and see how typedef actually works.
typedef unsigned long ulong;
The above statement defines a term ulong for an unsigned long data type. Now
this ulong identifier can be used to define unsigned long type variables. ulong i, j;
Application of typedef
97
typedef can be used to give a name to user defined data type as well. Lets see its
use with structures.
typedef struct
{
type member1;
type member2;
type member3;
} type_name;
Here type_name represents the structure definition associated with it. Now this
type_name can be used to declare a variable of this structure type.
void main( )
{
emp e1;
printf("\nEnter Employee record:\n");
printf("\nEmployee name:\t");
fgets(e1.name, sizeof(e1.name),stdin);
printf("\nEnter Employee salary: \t");
scanf("%d", &e1.salary);
printf("\nstudent name is %s", e1.name);
printf("\nSalary is %d \n", e1.salary);
}
98
Simple output:
99
Access structures members using pointers
C program example:
#include <stdio.h>
struct person
{
int age;
float weight;
};
int main()
{
struct person *personPtr, person1;
personPtr = &person1;
printf("Displaying:\n");
printf("Age: %d\n", personPtr->age);
printf("weight: %f", personPtr->weight);
return 0;
}
Sample output
In this example, the address of person1 is stored in the personPtr pointer using personPtr
= &person1;
Now, you can access the members of person1 using the personPtr pointer.
100
Sometimes, the number of struct variables you declared may be insufficient. You may
need to allocate memory during run-time. Here's how you can achieve this in C
programming.
#include <stdio.h>
#include <stdlib.h>
struct person {
int age;
float weight;
char name[30];
};
int main()
{
struct person *ptr;
int i, n;
printf("Displaying Information:\n");
for(i = 0; i < n; ++i)
printf("Name: %s\tAge: %d\n", (ptr+i)->name, (ptr+i)->age);
return 0;
}
Sample output
101
3.3.4.5. Nested Structures
float real;
};
struct number
{
struct complex comp;
int integers;
} num1, num2;
Suppose, you want to set imag of num2 variable to 11. Here's how you can do it:
num2.comp.imag = 11;
What we know is that the size of a struct is the sum of all the data members. Like for the
following struct,
struct A{
int a;
int* b;
char c;
char *d;
102
};
Size of the struct should be sum of all the data member, which is: Size of int a+ size of
int* b +size of char c+ size of char* d
Let's see what the compiler is giving using the sizeof() operator.
#include <stdio.h>
struct A {
int a;
int* b;
char c;
char* d;
};
int main()
{
struct A a;
printf("Size of struct A: %lu\n", sizeof(struct A));
printf("Size of object a: %lu\n", sizeof(a));
return 0;
}
Output:
Size of struct A: 32
Size of object a: 32
It seems like the compiler took maximum size out of the data type and assigned the same
memory to all data types. Is it so?
Okay, it's quite like that, but not the same. Of course, the compiler adds padding and
tries to align the data members. So for the above structure, the data alignment looks like
below,
103
Above is the alignment of the structure A, and that's why the size of the struct is 32
Bytes. Also, the object a of type struct A is 32 Bytes.
Now the question is how does the compiler add padding and align? The method is
compiler dependent and kind of greedy. It aligns till the boundary of maximum memory
allocated. Here we find that max memory allocated is 8 Bytes, thus all the data members
acquire 8 Bytes and the total size is 32 Bytes. Now the question is will it happen every
time similarly?
The answer is no. Check the following structure which has the same members but the
ordering is different.
struct B{
int* b;
char c;
int a;
char *d;
};
#include <stdio.h>
struct B {
int* b;
char c;
int a;
char* d;
};
int main()
{
struct B b;
printf("Size of struct B: %lu\n", sizeof(struct B));
printf("Size of object b: %lu\n", sizeof(b));
return 0;
}
Output:
104
Size of struct B: 24
Size of object b: 24
In the above structure, we find that the size is 24 Bytes though the same data members
have been used. This is due to the change in the order of the member declaration. In this
case, the alignment and padding would be like below:
Above is the alignment for structure B and that's why size is 24 Bytes, instead of 32. We
saw that the compiler keeps aligning greedily and that's why it aligned char c & int a in
the same row. When it tried to align char* d, it could not as only 3 bytes were left. But
instead of char*, if it was char only then it would have aligned in the same line.
So, I hope it's clear how the compiler aligns a structure. A point to be noted is that the
compiler can't reorder the data members though it may have reduced size. Thus, struct A
will have size 32 Bytes, not 24 Bytes.
3.3.5 UNIONS IN C
105
This implies that although a union may contain many members of different
types, it cannot handle all the members at the same time. A union is
declared using the union keyword:
union [union name/tag]
{
// member variables goes here
}[union variable ];
Syntax for accessing any union member is similar to accessing structure members,
union test
{
int a;
float b;
char c;
}t;
#include <stdio.h>
union item
{
int a;
char ch;
};
int main( )
{
union item it;
it.a = 12;
printf("a: %d \n", it.a);
it.ch = 'z';
printf("c: %c\n", it.ch);
// Checking for corruption in memory
printf("a: %d\n", it.a);
printf("c: %c\n", it.ch);
return 0;
}
This declares a variable it of type union item. This union contains two members
each with a different data type. However, only one of them can be used at a time.
This is due to the fact that only one memory location is allocated for all the union
variables, irrespective of their size. The compiler allocates the storage that is large
enough to hold the largest variable type in the union.
In the union declared above the member requires 4 bytes which is largest
among-st the members. Other member(ch) of the union will share the same
memory address.
Check the result when this program is executed, we see that the last printf used
to output the value of a gives unexpected result because there is no longer a
107
memory space for it. The memory reserved for this union is now assigned to ch
as it’s the last to be assigned the value (‘z’) in the code.
3.3.6 ENUMERATIONS IN C
return 0;
}
108
4. APPLY ADVANCED PROGRAMING CONCEPTS WITH C
Every statement in a computer is executed based on pre-defined rules. The control flow
is also based on logic. At times, you find a necessity to execute a few customized logics.
Custom statements can be executed using control statements.
Here, the control enters the statements block and gets executed if the logic is satisfied.
Hence, they are called control statements. They are often used to determine the order in
which statements must be executed.
In simple words, Control statements in C help the computer execute a certain logical
statement and decide whether to enable the control of the flow through a certain set of
statements or not. Also, it is used to direct the execution of statements under certain
conditions.
109
4.1.1 Decision-Making Control Statements
Simple if Statement
Simple if statements are carried out to perform some operation when the condition is only
true. If the condition of the if statement is true then the statements under the if block is
executed else the control is transferred to the statements outside the if block.
Flowchart
110
Example: A C program which checks if the first number of two input numbers is greater
than the second.
If-else Statement
In some situations, you may have to execute statements based on true or false under certain
conditions, therefore; you use if-else statements. If the condition is true, then if block will be
executed otherwise the else block is executed.
111
Flowchart
The nested if-else statements consist of another if or else. Therefore; if the condition of “if”
is true (i.e., an outer if) then outer if’s if block is executed which contains another if (that is
inner if) and if the condition of if block is true, statements under if block will be executed
else the statements of inner if’s “else” block will be executed.
If the outer “if” condition is not true then the outer if’s “else” block is executed which
consists of another if. The outer else’s inner if the condition is true then the statement
under outer else’s inner if is executed else the outer else’s else block is executed.
112
Flowchart:
113
4.1.2 Conditional Control Statements in C
As per the value of the switch expression, the switch statement will allow multi-way
branching.
Depending on the expression, the control is transferred to that particular case label and
executes the statements under it. If none of the cases are matched with the switch
expression, then the default statement is executed.
While Loop
A while loop is also known as an entry loop because in a while loop the condition is tested
first then the statements underbody of the while loop will be executed.
If the while loop condition is false for the first time itself then the statements under the
114
while loop will not be executed even once.
Flowchart
do-while Loop
The do-while is also known as an exit loop because in the do-while loop, the statements
will be executed first and then the condition is checked.
If the condition of the while loop is true then the body of the loop will be executed again
and again until the condition is false. Once the condition is false, the control will transfer
outside the do-while loop and execute statements followed soon after the do-while loop.
115
Flowchart:
For Loop
The for loop is also known as a pre-test loop. From the following syntax, expression1 is an
initialization, expression2 is the conditional expression and expression3 is an updation. The
variables can be initialized for the statement itself.
116
In the for loop, expression1 is used to initialize the variable, expression2 is evaluated
and if the condition is true, then the body of the for loop will be executed and then the
statements under expression3 will be executed. This process is repeated as long as the
for loop condition is true, once the condition is false control will return to the
statements following the for loop and execute those statements.
Flowchart:
Branching statements allow the flow of execution to jump to a different part of the
program. The common branching statements used within other control structures
include: break, continue, return, and goto. The goto is rarely used in modular structured
programming. Additionally, we will add to our list of branching items a pre-defined
function commonly used in programming languages of: exit.
Examples
break
The break is used in one of two ways; with a switch to make it act like a case structure or
as part of a looping process to break out of the loop. The following gives the appearance
that the loop will execute 8 times, but the break statement causes it to stop during the
fifth iteration.
int counter = 0;
printf(“%d”, counter);
if (counter == 4)
break;
counter += 1; }
continue
118
The following gives the appearance that the loop will print to the monitor 8 times, but the
continue statement causes it not to print number 4.
for (counter = 0; counter < 8; counter += 1){
if (counter == 4)
continue;
printf(“%d”, counter); }
return
The return statement exits a function and returns to the statement where the function was
called.
function (parameters’ list and their types){
statements
goto
The goto structure is typically not accepted in good structured programming. However,
some programming languages allow you to create a label with an identifier name followed
by a colon. You use the command word goto followed by the label.
some lines of code;
119
some lines of code;
exit
Although exit is technically a pre-defined function, it is covered here because of its common
usage in programming. A good example is opening a file and then testing to see if the file
was actually opened. If not, we have an error that usually indicates that we want to
prematurely stop the execution of the program. The exit function terminates the running of
the program and in the process returns an integer value back to the operating system. It
fits the definition of branching which is to jump to some other place in the program.
Key Terms
Branching statements Allow the flow of execution to jump to a different part of the program.
break
A branching statement that terminates the existing structure.
continue
A branching statement that causes a loop to stop its current iteration and begin the next
one.
exit
A predefined function used to prematurely stop a program and return to the operating
system.
goto
An unstructured branching statement that causes the logic to jump to a different place in
the program.
return
A branching statement that causes a function to jump back to the function that called it.
120
Exercises:
Sample output:
Expected Output
121
122
9. C Program to check if the entered number is ZERO, POSITIVE or NEGATIVE. The program
should stop if he/she enters the character e.
11. C Program to find the sum of the first N natural number, N must be taken by the user.
13. Write a C program to print all even and odd numbers from 1 to N.
15. Write a C program to print square, cube and square root of all numbers from 1 to N.
17. Write a C program to print all upper case and lower case alphabets.
18. C program to read the age of 15 people and count total Baby age, School age and Adult age.
This the art of writing programs that generate various patterns of numbers and stars
or of any symbols. Such programs involve usage of nested for loops (a for loop inside
a for loop). A pattern of numbers, star or characters is a way of arranging these in
some logical manner or they may form a sequence. Some of these patterns are
triangles which have special importance in mathematics.
Some patterns are symmetrical while others are not.
Pattern : 1
123
#include<stdio.h>
int main(){
int i,j;
return 0;
}
Pattern : 2
Program 2:
#include<stdio.h>
int main(){
int i,j;
124
return 0;
}
Pattern : 3
Program 3:
#include<stdio.h>
void main(){
int i,j,k;
for (i=1; i<=5; i++) {
for (j=5; j>=i; j--) {
printf(" ");
}
for (k=1; k<=i; k++) {
printf("* ");
}
printf("\n");
}
Pattern : 4
Program 5:
#include <stdio.h>
int main() {
int i,j,k, rows=5;
125
// first loop for printing all rows
for ( i = 0; i < rows; i++) {
Program5:
#include <stdio.h>
int main() {
int i,j,k, rows=5;
// first loop to print all rows
for (i = 0; i < rows; i++) {
126
}
return 0;
}
Pattern 6:
Program 6:
#include <stdio.h>
int main() {
int i,j,k, rows=5;
// first loop for printing all rows
for ( i = 0; i < rows; i++) {
Pattern 7:
127
Program 7:
#include <stdio.h>
int main() {
int i,j,k, rows=5;
// first outer loop to iterate through each row
for ( i = 0; i < rows; i++) {
Program 8:
128
#include <stdio.h>
int main() {
int i,j,k, n=5;
// first outer loop to iterate through each row
for ( i = 0; i < 2 * n - 1; i++) {
129
Program 9:
#include <stdio.h>
int main() {
int rows = 5,i,j,k;
// assigning comparator
int comp;
if (i < rows) {
comp = 2 * i + 1;
}
else {
comp = 2 * (2 * rows - i) - 3;
}
130
printf("\n");
}
return 0;
}
Pattern 10:
Program 10:
#include <stdio.h>
int main() {
int rows = 5,i,j,k;
Program 11:
#include <stdio.h>
int main() {
int rows = 5,i,j,k;
132
Pattern 12:
Program 12:
#include <stdio.h>
int main() {
int rows = 5,i,j,k;
Pattern 13:
133
Program 13:
#include <stdio.h>
int main() {
int n = 5,i,j,k;
134
printf("* ");
}
else {
printf(" ");
}
}
printf("\n");
}
return 0;
}
Pattern 14:
Program 14:
#include <stdio.h>
int main() {
int n = 5,i,j,k;
// assigning comparator
int comp;
if (i < n) {
comp = 2 * i + 1;
}
else {
135
comp = 2 * (2 * n - i) - 3;
}
Program 15:
#include <stdio.h>
int main() {
int rows = 4;
136
int n = 1;
int i,j;
Program 16:
#include<stdio.h>
void main(){
int height, c,r, pt[10][10];
printf("Enter the height of triangle: ");
scanf("%d",&height);
for(r=0;r<height;r++){
for(c=0;c<height;c++){
if(c<=r){
if(c==r)
pt[r][c]=1;
else
137
pt[r][c]=pt[r-1][c]+pt[r-1][c-1];
printf(" %d ", pt[r][c]);
}
}
printf("\n");
}
}
As we know that we can create a pointer of any data type such as int, char, float, we can
also create a pointer pointing to a function. The code of a function always resides in
memory, which means that the function has some address. We can get the address of
memory by using the function pointer.
Example:
Output:
In the above output, we observe that the main() function has some address. Therefore, we
conclude that every function has some address.
Till now, we have seen that the functions have addresses, so we can create pointers that can
contain these addresses, and hence can point them.
Examples:
int (*ip)(int,int);
138
In the above declaration, *ip is a pointer that points to a function which returns an int value
and accepts two integer values as arguments.
foat (*fp)(float);
In this declaration, *fp is a pointer that points to a function that returns a float value and
accepts a float value as an argument.
Or
result = fp(a , b); /* Calling a function using function pointer, and indirection
operator can be removed.*/
The effect of calling a function by its name or function pointer is the same. If we are
using the function pointer, we can omit the indirection operator as we did in the
second case. Still, we use the indirection operator as it makes it clear to the user that
we are using a function pointer.
1. Unlike normal pointers, a function pointer points to code, not data. Typically a
function pointer stores the start of executable code.
2. Unlike normal pointers, we do not allocate or de-allocate memory using function
pointers.
3. A function’s name can also be used to get functions’ addresses. For example, in the
below program, we have removed the address operator ‘&’ in assignment. We have
also changed function call by removing *, the program still works.
139
Output:
4. Like normal pointers, we can have an array of function pointers. Below example in
point 5 shows syntax for array of pointers.
5. Function pointer can be used in place of a switch case. For example, in the below
program, the user is asked for a choice between 0 to 2 to do different tasks.
140
Sample output
6. Like normal data pointers, a function pointer can be passed as an argument and
can also be returned from a function.
For example, consider the following C program where wrapper() receives a void
fun() as parameter and calls the passed function.
141
This point in particular is very useful in C. In C, we can use function pointers to
avoid code redundancy. For example a simple qsort() function can be used to sort
arrays in ascending order or descending or by any other order in case of array of
structures. Not only this, with function pointers and void pointers, it is possible to
use qsort for any data type.
142
The output is
Similar to qsort(), we can write our own functions that can be used for any data
type and can do different tasks without code redundancy. Below is an example
search function that can be used for any data type. In fact we can use this search
function to find close elements (below a threshold) by writing a customized
compare function.
143
#include <stdio.h>
#include <stdbool.h>
// array
// element ele_size
int i;
144
return i;
return -1;
int main()
int n = sizeof(arr)/sizeof(arr[0]);
int x = 7;
return 0;
Output:
The above search function can be used for any data type by writing a separate
customized compare().
7. Many object oriented features in C++ are implemented using function pointers in C.
C also allows to return a pointer from a function. To do so, you would have to declare
a function returning a pointer as in the following example:
}
145
From the syntax above, functionName returns a pointer to dataType.
But it is not recommended to return the address of a local variable outside the
function as it goes out of scope after function returns.
4.2.3 Create your own header file in C and add user defined functions
As we all know that files with .h extension are called header files in C. These header
files generally contain function declarations which can be used in our main C
program, like for e.g. there is need to include stdio.h in our C program to use
function printf() in the program. So the question arises, is it possible to create your
own header file? The answer to the above is yes. header files are simply files in which
you can declare your own functions that you can use in your main program or these
can be used while writing large C programs.
Below is the short example of creating your own header file and using it accordingly.
1. Creating myHeadFile.h : Write the below code and then save the file as
myHeadFile.h or you can give any name but the extension should be .h indicating
its a header file.
Sample output
Introduction
A linked list is a data structure that consists of a sequence of nodes, where each node
contains a value and a pointer to the next node in the sequence. In C, you can
implement a linked list using structures and pointers.
To start, you would define a structure to represent a node in the linked list. This
structure would typically contain two members: one to hold the value of the node and
another to hold a pointer to the next node. Here's an example:
struct Node {
int data;
struct Node* next;
};
In this example, data represents the value stored in the node, and `next` is a pointer to
the next node in the list.
To create a linked list, you would declare a pointer to the first node, often called the
"head" of the list. Initially, the head would be set to `NULL` to indicate an empty list.
Here's an example:
struct Node* head = NULL;
To add a new node to the list, you would allocate memory for a new node using the
`malloc` function, assign the value to the `data` member, and update the `next` pointer
accordingly. Here's an example of adding a node to the beginning of the list:
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = 42;
newNode->next = head;
head = newNode;
To traverse the linked list, you would start at the head and follow the `next` pointers
until you reach the end of the list. Here's an example of printing the values of all nodes
in the list:
struct Node* current = head;
148
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
Remember to free the memory allocated for the nodes when you're done with the linked
list to avoid memory leaks. You can do this by traversing the list and using the `free`
function to deallocate each node.
This is just a basic overview of implementing a linked list in C. There are many
variations and additional operations you can perform on a linked list, such as inserting
or deleting nodes at specific positions. Let me know if you'd like more information on
any specific aspect!
1. Singly Linked List: In this type of linked list, each node contains a data element
and a reference (or link) to the next node in the sequence.
2. Doubly Linked List: In a doubly linked list, each node has two references - one to
the previous node and one to the next node. This allows for traversal in both directions.
3. Circular Linked List: In a circular linked list, the last node of the list points back to
the first node, creating a circular structure. This allows for continuous traversal of the
list.
4. Skip List: A skip list is a type of linked list that allows for faster searching by
including multiple layers of linked lists with different skip distances.
These are some of the commonly used types of linked lists, each with its own
advantages and use cases.
149
Here's an example of a singly linked list implementation in C language:
This implementation creates a singly linked list and inserts nodes at the beginning of
the list. The insertAtBeginning() function is used to insert a new node with the given
data at the beginning of the linked list. The printList() function is used to print the
elements of the linked list. In the main function, we initialize an empty linked list,
insert nodes, and then print the linked list.
Output
150
2. Doubly Linked List
152
This implementation creates a circular linked list where the last node points back to the
head node. The insert() function inserts a new node at the beginning of the list, and the
display() function prints the elements of the circular linked list.
Output:
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
153
file.
● Reusability: The data stored in the file can be accessed, updated, and deleted anywhere
and anytime providing high reusability.
● Portability: Without losing any data, files can be transferred to another in the computer
system. The risk of flawed coding is minimized with this feature.
● Efficient: A large amount of input may be required for some programs. File handling allows
you to easily access a part of a file using few instructions which saves a lot of time and
reduces the chance of errors.
● Storage Capacity: Files allow you to store a large amount of data without having to worry
about storing everything simultaneously in a program.
1. Text Files
A text file contains data in the form of ASCII characters and is generally used to store a stream of
characters.
2. Binary Files
A binary file contains data in binary form (i.e. 0’s and 1’s) instead of ASCII characters. They
contain data that is stored in a similar manner to how it is stored in the main memory.
● The binary files can be created only from within a program and their contents can only
be read by a program.
● More secure as they are not easily readable.
154
● They are generally stored with .bin file extension.
To create a new file or open an existing file, we need to create a file pointer of FILE type.
Following is the sample code for creating file pointer.
File *f_ptr ;
We use the pre-defined method fopen() to create a new file or to open an existing file.
There are different modes in which a file can be opened. Consider the following code...
File *f_ptr ;
*f_ptr = fopen("abc.txt", "w") ;
The above example code creates a new file called abc.txt if it does not exist otherwise it is
opened in writing mode.
In C programming language, there different modes are available to open a file and they are
shown in the following table.
155
6 a+ Opens a text file in both reading and
writing mode. The reading operation is
performed from beginning and writing
operation is performed at the end of the
file.
1. getc()
2. getw()
3. fscanf()
4. fgets()
5. fread()
getc( *file_pointer ) - This function is used to read a character from a specified file which is
opened in reading mode. It reads from the current position of the cursor. After reading the
character the cursor will be at the next character.
OUTPUT:
156
getw( *file_pointer ) - This function is used to read an integer value from the specified file
which is opened in reading mode. If the data in the file is set of characters then it reads ASCII
values of those characters.
OUTPUT
OUTPUT
158
OUTPUT
fread(): The fread() function in C reads the block of data from the stream. This function first,
reads the count number of objects, each one with a size of size bytes from the given input
stream.
The total amount of bytes reads if successful is (size*count). According to the no. of
characters read, the indicator file position is incremented. If the objects read are not trivially
copy-able, then the behavior is undefined and if the value of size or count is equal to zero,
then this program will simply return 0.
1. https://bournetocode.com/projects/GCSE_Computing_Fundamentals/pages/3-1-1-
rep_alg.html
2. https://www.bbc.co.uk/bitesize/guides/zpp49j6/revision/2#:~:text=There%20are
%20two%20main%20ways,be%20represented%20%E2%80%93%20pseudocode%20and
%20flowcharts%20.
3. https://byjus.com/gate/size-of-data-types-in-c/
4. https://www.programiz.com/c-programming
5. https://www.includehelp.com/c/size-of-struct-in-c-padding-alignment-in-struct.aspx
6. https://www.geeksforgeeks.org/pattern-programs-in-c/
7. https://www.educba.com/patterns-in-c-programming/
8. https://www.programiz.com/c-programming/examples/pyramid-pattern
160