CDS
CDS
1
consider the following example
#include <stdio.h>
void func1(void) {
printf("%sn",__func__);
return;
}
int main() {
myfunc();
}
The output would be
func1
Keywords
Data Types
int:
2
• An unsigned int has the same memory requirements as a
short unsigned int. However, in case of an ordinary int, the
leftmost bit is reserved for the sign.
• A long unsigned int occupies 4 bytes of memory and stores
positive integers in the range of 0 to 4294967295.
• By default the int data type is signed.
• A long long int occupies 64 bits of memory. It may be
signed or unsigned. The signed long long int stores values
from −9,223,372,036,854,775,808 to
9,223,372,036,854,775,807 and the unsigned long long
ranges from 0 to 18,446,744,073,709,551,615.
char:
float:
double:
void:
It is used to specify an empty set containing no values. Hence,
it occupies 0 bytes of memory.
_Bool:
A boolean data type, which is an unsigned integer type, that can
3
store only two values, 0 and 1. Include the
file <stdbool.h> when using _Bool.
_Complex:
Arrays:
Constants:
There are four basic types of constants inC. They are integer
constants, floating point constants, character constants and
string constants. Integer and floating point constants cannot
contain commas or blank spaces; but they can be prefixed by a
minus sign to indicate a negative quantity.
4
Integer Constants:
5
constant is appended by Fto indicate single precision and
by L to indicate a long floating point constant.
Character Constants:
String Literals:
6
multibyte character is a character whose bit representation fits
into one or more bytes.
Symbolic Constants:
7
an expression, higher precedence operators will be evaluated
first.
Example
Try the following example to understand operator precedence
in C –
8
#include <stdio.h>
main() {
int a = 20;
int b = 10;
int c = 15;
int d = 5;
int e;
e = (a + b) * c / d; // ( 30 * 15 ) / 5
printf("Value of (a + b) * c / d is : %d\n", e );
e = ((a + b) * c) / d; // (30 * 15 ) / 5
printf("Value of ((a + b) * c) / d is : %d\n" , e );
e = a + (b * c) / d; // 20 + (150/5)
printf("Value of a + (b * c) / d is : %d\n" , e );
return 0;
}
When you compile and execute the above program, it produces
the following result −
Value of (a + b) * c / d is : 90
Value of ((a + b) * c) / d is : 90
Value of (a + b) * (c / d) is : 90
Value of a + (b * c) / d is : 50
9
There are many IO Devices available, some of them are:
Input Devices
Keyboard
10
Joystick
11
Web Camera
Because it records a video image of the scene in front of it, a
webcam is an input device. It is either built inside the computer
(for example, a laptop) or attached through a USB connection.
A webcam is a computer-connected tiny digital video camera.
It’s also known as a web camera because it can take images and
record video. These cameras come with software that must be
installed on the computer in order to broadcast video in real-
time over the Internet. It can shoot images and HD videos,
however, the video quality isn’t as good as other cameras (In
Mobiles or other devices or normal cameras).
Output Devices
Monitor
Monitors, also known as Visual Display Units (VDUs), are a
computer’s primary output device. It creates images by
arranging small dots, known as pixels, in a rectangular pattern.
The amount of pixels determines the image’s sharpness.
The two kinds of viewing screen used for monitors are:
(1) Cathode-Ray Tube (CRT): Pixels are minuscule visual
elements that make up a CRT display. The higher the image
quality or resolution, the smaller the pixels.
(2) Flat-Panel Display Cathode-Ray Tube Monitor: In
comparison to the CRT, a flat-panel display is a type of video
display with less volume, weight, and power consumption.
They can be hung on the wall or worn on the wrist.
Flat-panel displays are currently used in calculators, video
games, monitors, laptop computers, and graphical displays.
Printer
Printers are output devices that allow you to print information
on paper.
There are two types of printers:
(a) Impact Printer:
Characters are printed on the ribbon, which is subsequently
crushed against the paper, in impact printers. The following
are the characteristics of impact printers:
• Exceptionally low consumable cost.
• Quite noisy
• Because of its low cost, it is ideal for large-scale
printing.
• To create an image, there is physical contact with the
paper.
12
(b) Non-Impact Printers:
Characters are printed without the need for a ribbon in non-
impact printers. Because these printers print a full page at a
time, they’re also known as Page Printers. The following are the
characteristics of non-impact printers:
• Faster
• They don’t make a lot of noise.
• Excellent quality
• Supports a variety of typefaces and character sizes
Control Structures:-
13
Sequential Control flow
• [Module A]
[End of If structure]
Implementation:
• C/C++ if statement with Examples
• Java if statement with Examples
• Double AlternativeThis structure has the form:
• If (Condition), then:
• [Module A]
• Else:
• [Module B]
• [End if structure]
Implementation:
• C/C++ if-else statement with Examples
• Java if-else statement with Examples
• Multiple AlternativesThis structure has the
form:
14
• If (condition A), then:
• [Module A]
• Else if (condition B), then:
• [Module B]
• ..
• ..
• Else if (condition N), then:
• [Module N]
• [End If structure]
Implementation:
• C/C++ if-else if statement with Examples
• Java if-else if statement with Examples
In this way, the flow of the program depends on the set
of conditions that are written. This can be more
understood by the following flow charts:
15
body of a loop.
The two types of these structures are:
• Repeat-For Structure
This structure has the form:
• Repeat for i = A to N by I:
• [Module]
• [End of loop]
Here, A is the initial value, N is the end value
and I is the increment. The loop ends when A>B.
K increases or decreases according to the
positive and negative value of I respectively.
Repeat-For Flow
Implementation:
• C/C++ for loop with Examples
• Java for loop with Examples
16
• Repeat-While Structure
It also uses a condition to control the loop. This
structure has the form:
• Repeat while condition:
• [Module]
• [End of Loop]
Implementation:
• C/C++ while loop with Examples
• Java while loop with Examples
In this, there requires a statement that initializes the
condition controlling the loop, and there must also be
a statement inside the module that will change this
condition leading to the end of the loop.
17
There can also be multiple conditions like in C if x occurs then
execute p, else if condition y occurs execute q, else execute r.
This condition of C else-if is one of the many ways of importing
multiple conditions. The Decision Making Statements are used
to evaluate the one or more conditions and make the decision
whether to execute set of statement or not.
18
{
// Statements to execute if
// condition is true
}
Here, the condition after evaluation will be either true or false.
C if statement accepts boolean values – if the value is true then
it will execute the block of statements below it otherwise not.
If we do not provide the curly braces ‘{‘ and ‘}’ after
if(condition) then by default if statement will consider the first
immediately below statement to be inside its block.
Example:
If Ram can having 100 GeekBits then he can redeem these
GeekBits and get the GFG T-shirt .
if(condition)
statement1;
statement2;
// Here if the condition is true, if block
// will consider only statement1 to be inside
// its block.
Flowchart
• C
• C++
19
// C program to illustrate If statement
#include <stdio.h>
int main()
{
int i = 10;
if (i > 15) {
printf("10 is greater than 15");
}
Output:
I am Not in if
As the condition present in the if statement is false. So, the
block below the if statement is not executed.
2. if-else in C/C++
The if statement alone tells us that if a condition is true it will
execute a block of statements and if the condition is false it
won’t. But what if we want to do something else if the condition
is false. Here comes the C else statement. We can use
the else statement with the if statement to execute a block of
code when the condition is false.
Syntax:
if (condition)
{
// Executes this block if
// condition is true
}
else
{
// Executes this block if
20
// condition is false
}
Flowchart:
Example:
The person who having correct 50 Geek Bits is redeem the gifts
otherwise they can’t redeem.
• C
• C++
// C program to illustrate If statement
#include <stdio.h>
21
int main()
{
int i = 20;
if (i < 15) {
Output:
i is greater than 15
The block of code following the else statement is executed as
the condition present in the if statement is false.
3. nested-if in C/C++
A nested if in C is an if statement that is the target of another
if statement. Nested if statements mean an if statement inside
another if statement. Yes, both C and C++ allow us to nested if
statements within if statements, i.e, we can place an if
statement inside another if statement.
Syntax:
if (condition1)
{
// Executes when condition1 is true
if (condition2)
{
// Executes when condition2 is true
22
}
}
Flowchart
Example:
If the person having more than 50 Geek Bits and less than 150
Geek Bits he won the GFG T-shirt.
23
if (i < 15)
printf("i is smaller than 15\n");
// Nested - if statement
// Will only be executed if statement above
// is true
if (i < 12)
printf("i is smaller than 12 too\n");
else
printf("i is greater than 15");
}
return 0;
}
Output:
i is smaller than 15
i is smaller than 12 too
4. if-else-if ladder in C/C++
Here, a user can decide among multiple options. The C if
statements are executed from the top down. As soon as one of
the conditions controlling the if is true, the statement
associated with that if is executed, and the rest of the C else-if
ladder is bypassed. If none of the conditions is true, then the
final else statement will be executed. if-else-if ladder is similar
to switch statement.
Syntax:
if (condition)
statement;
else if (condition)
statement;
else
statement;
24
Example:
If the person having the 50 Geek Bits then he get the GfG Course
Coupon otherwise he will having 100 Geek Bits then he get
the GfG T-shirt otherwise he will having the 200 Geek Bits then
he get the GfG Bag otherwise he will having less than 50 he
cant get anything.
• C
• C++
25
// C program to illustrate nested-if statement
#include <stdio.h>
int main()
{
int i = 20;
if (i == 10)
printf("i is 10");
else if (i == 15)
printf("i is 15");
else if (i == 20)
printf("i is 20");
else
printf("i is not present");
}
Output:
i is 20
5. Jump Statements in C/C++
These statements are used in C or C++ for the unconditional
flow of control throughout the functions in a program. They
support four types of jump statements:
A) break
This loop control statement is used to terminate the loop. As
soon as the break statement is encountered from within a loop,
the loop iterations stop there, and control returns from the
loop immediately to the first statement after the loop.
Syntax:
break;
Basically, break statements are used in situations when we are
not sure about the actual number of iterations for the loop or
we want to terminate the loop based on some condition.
26
Example:
• C
• C++
// C program to illustrate
// to show usage of break
// statement
#include <stdio.h>
27
}
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
// no of elements
int n = 6;
// key to be searched
int key = 3;
return 0;
}
Output:
Element found at position: 3
B) continue
This loop control statement is just like the break statement.
The continue statement is opposite to that of the
break statement, instead of terminating the loop, it forces to
execute the next iteration of the loop.
As the name suggests the continue statement forces the loop
to continue or execute the next iteration. When the continue
statement is executed in the loop, the code inside the loop
following the continue statement will be skipped and the next
iteration of the loop will begin.
Syntax:
continue;
28
Example:
• C
• C++
// C program to explain the use
// of continue statement
#include <stdio.h>
int main()
{
// loop from 1 to 10
for (int i = 1; i <= 10; i++) {
// If i is equals to 6,
// continue to next iteration
29
// without printing
if (i == 6)
continue;
else
// otherwise print the value of i
printf("%d ", i);
}
return 0;
}
Output:
1 2 3 4 5 7 8 9 10
If you create a variable in if-else in C/C++, it will be local to
that if/else block only. You can use global variables inside the
if/else block. If the name of the variable you created in if/else
is as same as any global variable then priority will be given to
`local variable`.
• C
• C++
#include <stdio.h>
int main()
{
30
}
printf("After if block %d", gfg);
return 0;
}
Output:
Before if-else block 0
if block 100
After if block 0
C) goto
The goto statement in C/C++ also referred to as the
unconditional jump statement can be used to jump from one
point to another within a function.
Syntax:
Syntax1 | Syntax2
----------------------------
goto label; | label:
. | .
. | .
. | .
label: | goto label;
In the above syntax, the first line tells the compiler to go to or
jump to the statement marked as a label. Here, a label is a user-
defined identifier that indicates the target statement. The
statement immediately followed after ‘label:’ is the destination
statement. The ‘label:’ can also appear before the ‘goto label;’
statement in the above syntax.
31
Examples:
• C
• C++
// C program to print numbers
// from 1 to 10 using goto
// statement
#include <stdio.h>
32
n++;
if (n <= 10)
goto label;
}
Output:
1 2 3 4 5 6 7 8 9 10
D) return
The return in C or C++ returns the flow of the execution to the
function from where it is called. This statement does not
mandatorily need any conditional statements. As soon as the
statement is executed, the flow of the program stops
immediately and returns the control from where it was called.
The return statement may or may not return anything for a void
function, but for a non-void function, a return value must be
returned.
Syntax:
return[expression];
Example:
• C
• C++
// C code to illustrate return
// statement
#include <stdio.h>
33
// function to calculate sum
int SUM(int a, int b)
{
int s1 = a + b;
return s1;
}
// returns void
// function to print
void Print(int s2)
{
printf("The sum is %d", s2);
return;
}
int main()
{
int num1 = 10;
int num2 = 10;
int sum_of = SUM(num1, num2);
Print(sum_of);
return 0;
}
Output:
The sum is 20
Monolithic programming
If, we write an entire program in a single function that is in main
function then, you call it as a monolithic type of programming.
But, it is not a good style of writing entire logic in a single
function.
34
Disadvantages
The disadvantages of monolithic programming include −
• Program seems to be very large and complex.
• Debugging, testing and maintenance of a program is
very difficult.
Modular Programming
If the program is divided into number of functional parts, then
we use to call it as modular programming.
If the main program is divided into sub programs, then we can
independently code each sub module later combine into single
unit. This type of individual modules is termed as functions.
Advantages
The advantages of modular programming include −
•It is easy to understand the program.
• Debugging and maintenance becomes easy.
• Saves programmers or user’s time.
• Reuse the code where ever necessary.
Example of modular programming
An example of modular programming is given below −
35
For Example: If we want to perform the addition of two
numbers then below is the program to illustrate the addition of
two numbers using user-defined functions:
• C
• C++
// Driver Code
int main()
{
// Given two numbers
int a = 3, b = 5;
// Function Call
findSum(a, b);
return 0;
}
Output:
Sum is: 8
36
program and #include<iostream> preprocessor directive
in C++ program.
• C
• C++
// Driver Code
int main()
{
// Print Statement
printf("GeeksforGeeks!");
return 0;
}
Output: GeeksforGeeks!
User-defined Library Functions
Functions
These functions are These functions are predefined in
not predefined in the the compiler of C language.
Compiler.
These function are These functions are not created by
created by user as per user as their own.
their own requirement.
User-defined functions Library Functions are stored in
are not stored in special library file.
library file.
There is no such kind In this if the user wants to use a
of requirement to add particular library function then the
the particular library. user have to add the particular
library of that function in header file
of the program.
Execution of the Execution of the program does not
program begins from begin from the library function.
the user-define
function.
Example: sum(), Example: printf(), scanf(),
fact(),…etc. sqrt(),…etc.
37
Difference Between Actual and Formal Parameters:-
#include <stdio.h>
int multiplication;
38
addition = x*y;
printf(“%d”,multiplication);
void main () {
multiplication (2,3);
multiplication (4,5);
Function category:-
Depending on whether arguments are present or not and
whether a value is returned or not, functions are categorized
into −
• Functions without arguments and without return
values
• Functions without arguments and with return values
• Functions with arguments and without return values
• Functions with arguments and with return values
39
Functions without arguments and without return values
Example
#include<stdio.h>
main (){
void sum ();
clrscr ();
sum ();
getch ();
}
void sum (){
int a,b,c;
printf("enter 2 numbers:
");
scanf ("%d%d", &a, &b);
c = a+b;
printf("sum = %d",c);
}
Output
Enter 2 numbers:
3
5
Sum=8
40
Functions without arguments and with return values
Example
#include<stdio.h>
main (){
int sum ();
int c;
c= sum ();
printf(“sum = %d”,c);
getch ();
}
int sum (){
int a,b,c;
printf(“enter 2 numbers”);
scanf (“%d%d”, &a, &b);
c = a+b;
return c;
}
Output
Enter two numbers 10 20
30
41
Functions with arguments and without return values
Example
#include<stdio.h>
main (){
void sum (int, int );
int a,b;
printf("enter 2 numbers");
scanf("%d%d", &a,&b);
sum (a,b);
getch ();
}
void sum ( int a, int b){
int c;
c= a+b;
printf (“sum=%d”, c);
}
Output
Enter two numbers 10 20
Sum=30
42
Functions with arguments and with return values
Example
#include<stdio.h>
main (){
int sum ( int,int);
int a,b,c;
printf("enter 2 numbers");
scanf("%d%d", &a,&b);
c= sum (a,b);
printf ("sum=%d", c);
getch ();
}
int sum ( int a, int b ){
int c;
c= a+b;
return c;
}
Output
Enter two numbers 10 20
Sum=30
function prototype:-
43
Function prototype tells the compiler about a number of
parameters function takes data-types of parameters, and return
type of function. By using this information, the compiler cross-
checks function parameters and their data type with function
definition and function call. If we ignore the function
prototype, a program may compile with a warning and may
work properly. But sometimes, it will give strange output and
it is very hard to find such programming mistakes. Let us see
with examples
• C
#include <errno.h>
#include <stdio.h>
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "%s\n", strerror(errno));
return errno;
}
printf("file exist\n");
fclose(fp);
return 0;
}
The above program checks the existence of a file, provided
from the command line, if a given file exists, then the program
prints “file exists”, otherwise it prints an appropriate error
message. Let us provide a filename, which does not exist in a
file system, and check the output of the program on x86_64
architecture.
44
Why this program crashed, instead it should show an
appropriate error message. This program will work fine on x86
architecture but will crash on x86_64 architecture. Let us see
what was wrong with the code. Carefully go through the
program, deliberately I haven’t included the prototype of the
“strerror()” function. This function returns “pointer to the
character”, which will print an error message which depends
on errno passed to this function. Note that x86 architecture is
an ILP-32 model, which means integer, pointers and long are
32-bit wide, that’s why the program will work correctly on this
architecture. But x86_64 is the LP-64 model, which means long
and pointers are 64 bit wide. In C language, when we don’t
provide a prototype of a function, the compiler assumes that
function returns an integer. In our example, we haven’t
included the “string.h” header file (strerror’s prototype is
declared in this file), that’s why the compiler assumed that
function returns an integer. But its return type is a pointer to a
character. In x86_64, pointers are 64-bit wide and integers are
32-bits wide, that’s why while returning from a function, the
returned address gets truncated (i.e. 32-bit wide address,
which is the size of integer on x86_64) which is invalid and
when we try to dereference this address, the result is a
segmentation fault.
Now include the “string.h” header file and check the output,
the program will work correctly.
45
• Modes:
IN: Passes info from caller to callee.
•
• OUT: Callee writes values in caller.
• IN/OUT: Caller tells callee value of variable,
which may be updated by callee.
Important methods of Parameter Passing
1. Pass By Value: This method uses in-mode semantics.
Changes made to formal parameter do not get
transmitted back to the caller. Any modifications to the
formal parameter variable inside the called function or
method affect only the separate storage location and
will not be reflected in the actual parameter in the
calling environment. This method is also called as call
by value.
o C
o CPP
// C program to illustrate
// call by value
#include <stdio.h>
// Passing parameters
func(x, y);
printf("In main, x = %d y = %d\n", x, y);
return 0;
}
Output:
In func, a = 12 b = 7
In main, x = 5 y = 7
Languages like C, C++, Java support this type of
parameter passing. Java in fact is strictly call by value.
Shortcomings:
o Inefficiency in storage allocation
46
o For objects and arrays, the copy semantics are
costly
2. Pass by reference(aliasing): This technique
uses in/out-mode semantics. Changes made to formal
parameter do get transmitted back to the caller through
parameter passing. Any changes to the formal
parameter are reflected in the actual parameter in the
calling environment as formal parameter receives a
reference (or pointer) to the actual data. This method is
also called as call by reference. This method is
efficient in both time and space.
o C
o CPP
// C program to illustrate
// call by reference
#include <stdio.h>
int main(void)
{
int a = 10, b = 20;
// passing parameters
swapnum(&a, &b);
47
oPrograms are difficult to understand sometimes
Other methods of Parameter Passing
These techniques are older and were used in earlier
programming languages like Pascal, Algol and Fortran. These
techniques are not applicable in high level languages.
1. Pass by Result:This method uses out-mode semantics.
Just before control is transferred back to the caller, the
value of the formal parameter is transmitted back to the
actual parameter. This method is sometimes called call
by result. In general, pass by result technique is
implemented by copy.
2. Pass by Value-Result: This method uses in/out-
mode semantics. It is a combination of Pass-by-Value
and Pass-by-result. Just before the control is
transferred back to the caller, the value of the formal
parameter is transmitted back to the actual parameter.
This method is sometimes called as call by value-result
3. Pass by name : This technique is used in programming
language such as Algol. In this technique, symbolic
“name” of a variable is passed, which allows it both to
be accessed and update.
Example:
To double the value of C[j], you can pass its name (not
its value) into the following procedure.
4. procedure double(x);
5. real x;
6. begin
7. x:=x*2
8. end;
In general, the effect of pass-by-name is to textually
substitute the argument in a procedure call for the
corresponding parameter in the body of the procedure.
Implications of Pass-by-Name mechanism:
• The argument expression is re-evaluated each
time the formal parameter is passed.
• The procedure can change the values of
variables used in the argument expression and
hence change the expression’s value.
Recursion:-
48
Recursion is the process of repeating items in a self-similar way.
In programming languages, if a program allows you to call a
function inside the same function, then it is called a recursive
call of the function.
void recursion() {
recursion(); /* function calls itself */
}
int main() {
recursion();
}
The C programming language supports recursion, i.e., a
function to call itself. But while using recursion, programmers
need to be careful to define an exit condition from the function,
otherwise it will go into an infinite loop.
Recursive functions are very useful to solve many mathematical
problems, such as calculating the factorial of a number,
generating Fibonacci series, etc.
Number Factorial
The following example calculates the factorial of a given
number using a recursive function −
#include <stdio.h>
if(i <= 1) {
return 1;
}
return i * factorial(i - 1);
}
int main() {
int i = 12;
printf("Factorial of %d is %d\n", i, factorial(i));
return 0;
}
When the above code is compiled and executed, it produces the
following result −
Factorial of 12 is 479001600
49
Fibonacci Series
The following example generates the Fibonacci series for a given
number using a recursive function −
#include <stdio.h>
int fibonacci(int i) {
if(i == 0) {
return 0;
}
if(i == 1) {
return 1;
}
return fibonacci(i-1) + fibonacci(i-2);
}
int main() {
int i;
return 0;
}
When the above code is compiled and executed, it produces the
following result −
0
1
1
2
3
5
8
13
21
34
Storage Classes:-
Storage Classes are used to describe the features of a
variable/function. These features basically include the scope,
50
visibility and life-time which help us to trace the existence of a
particular variable during the runtime of a program.
C language uses 4 storage classes, namely:
51
termination of the program. Thus, no new memory is
allocated because they are not re-declared. Their scope
is local to the function to which they were defined.
Global static variables can be accessed anywhere in the
program. By default, they are assigned the value 0 by
the compiler.
C auto:-
1 void some_function()
52
2{
3 auto int count = 0;
4 int count2 = 0;
5}
1 int main()
2 {
3 auto int number = 5;
4 {
5 auto int number = 20;
6 printf("inner number: %d", number);
7 }
8 printf("\n");
9 printf("outer number: %d", number);
10 return 0;
11 }
inner number: 20
outer number: 5
extern:-
53
• Coming to the definition, when we define a variable or
function, in addition to everything that a declaration
does, it also allocates memory for that variable or
function. Therefore, we can think of definition as a
superset of the declaration (or declaration as a subset
of definition).
• Extern is a short name for external.
• used when a particular files need to access a variable
from another file.
• C
#include <stdio.h>
int main()
{
printf("%d", a);
return 0;
}
When
• we write extern some_data_type
some_variable_name; no memory is allocated. Only
property of variable is announced.
• Multiple declarations of extern variable is allowed
within the file. This is not the case with automatic
variables.
• Extern variable says to compiler ” go outside my scope
and you will find the definition of the variable that I
declared.”
• Compiler believes that whatever that extern variable
said is true and produce no error. Linker throws an
error when it finds no such variable exists.
• When an extern variable is initialized, then memory for
this is allocated and it will be considered defined.
A variable or function can be declared any number of times,
but it can be defined only once. (Remember the basic principle
that you can’t have two locations of the same variable or
function).
Now back to the extern keyword. First, Let’s consider the use
of extern in functions. It turns out that when a function is
54
declared or defined, the extern keyword is implicitly assumed.
When we write.
int foo(int arg1, char arg2);
The compiler treats it as:
extern int foo(int arg1, char arg2);
Since the extern keyword extends the function’s visibility to
the whole program, the function can be used (called) anywhere
in any of the files of the whole program, provided those files
contain a declaration of the function. (With the declaration of
the function in place, the compiler knows the definition of the
function exists somewhere else and it goes ahead and compiles
the file). So that’s all about extern and functions.
Example 2:
• c
Global:-
The variables that are declared outside the given function are
known as global variables. These do not stay limited to a
specific function- which means that one can use any given
function to not only access but also modify the global variables.
The initialization of these variables occurs automatically to 0
55
during the time of declaration. Also, we generally write the
global variables before the main() function.
56
}
void func_b()
{
int x = 5;
printf(“Inside the func_b() x is = %d\n”, x);
}
Output
The output obtained here will be:
The Global x is = 0
The Global y is = 10
From the func_a() the Global x is = 0
From the func_a() the Global y is = 10
Inside the func_b() x is = 5
57
}
Now, if the above code is compiled then an error is obtained i.e
“undefined reference to staticFunc()”. This happens as the
function staticFunc() is a static function and it is only visible in
its object file.
A program that demonstrates static functions in C is given as
follows −
Example
#include <stdio.h>
int main()
{
staticFunc();
return 0;
}
Output
The output of the above program is as follows −
Inside the static function staticFunc()
In the above program, the function staticFunc() is a static
function that prints ”Inside the static function staticFunc()”.
The main() function calls staticFunc(). This program works
correctly as the static function is called only from its own
object file
58
Remember that EOF normally has the value –1 and that some
hardware architectures do not allow negative values to be stored
in char variables. Therefore, the character-handling functions
manipulate characters as integers.
The following table summarizes the functions of the character-
handling library. When using functions from the character-
handling library, include the <cctype> header.
S.No. Prototype & Description
1 int isdigit( int c )
Returns 1 if c is a digit and 0 otherwise.
2 int isalpha( int c )
Returns 1 if c is a letter and 0 otherwise.
3 int isalnum( int c )
Returns 1 if c is a digit or a letter and 0 otherwise.
4 int isxdigit( int c )
Returns 1 if c is a hexadecimal digit character and 0
otherwise.
(See Appendix D, Number Systems, for a detailed
explanation of binary, octal, decimal and hexadecimal
numbers.)
5 int islower( int c )
Returns 1 if c is a lowercase letter and 0 otherwise.
6 int isupper( int c )
Returns 1 if c is an uppercase letter; 0 otherwise.
7 int isspace( int c )
Returns 1 if c is a white-space character—newline ('\n'),
space
(' '), form feed ('\f'), carriage return ('\r'), horizontal tab
('\t'), or vertical tab ('\v')—and 0 otherwise.
8 int iscntrl( int c )
Returns 1 if c is a control character, such as newline
('\n'), form feed ('\f'), carriage return ('\r'), horizontal
59
tab ('\t'), vertical tab ('\v'), alert ('\a'), or backspace
('\b')—and 0 otherwise.
9 int ispunct( int c )
Returns 1 if c is a printing character other than a space,
a digit, or a letter and 0 otherwise.
10 int isprint( int c )
Returns 1 if c is a printing character including space ('
') and 0 otherwise.
11 int isgraph( int c )
Returns 1 if c is a printing character other than space ('
') and 0 otherwise.
Examples
The following example demonstrates the use of the
functions isdigit, isalpha, isalnum and isxdigit.
Function isdigit determines whether its argument is a digit (0–
9). The function isalpha determines whether its argument is an
uppercase letter (A-Z) or a lowercase letter (a–z). The
function isalnum determines whether its argument is an
uppercase, lowercase letter or a digit.
Function isxdigit determines whether its argument is a
hexadecimal digit (A–F, a–f, 0–9).
String Handling Functions in C:-
C programming language provides a set of pre-defined
functions called string handling functions to work with string
values. The string handling functions are defined in a header
file called string.h. Whenever we want to use any string
handling function we must include the header file
called string.h.
The following table provides most commonly used string
handling function and their use:
60
strlen() strlen(string1) returns total number of characters
in string1
61
strset() strset(string1, 'B') Sets all the characters of string1 to
given character 'B'.
Pointers:-
Pointers in C are used to store the address of variables or a
memory location. This variable can be of any data type i.e,
int, char, function, array, or any other pointer. Pointers are
one of the core concepts of C programming language that
provides low-level memory access and facilitates dynamic
memory allocation.
62
Types of Pointers:-
Pointers can be classified into many different types based on
the parameter on which we are defining their types. If we
consider the type of variable stored in the memory location
pointed by the pointer, then the pointers can be classified into
the following types:
1. Integer Pointers
As the name suggests, these are the pointers that point to the
integer values.
Syntax of Integer Pointers
int *pointer_name;
These pointers are pronounced as Pointer to Integer.
Similarly, a pointer can point to any primitive data type. The
syntax will change accordingly. It can point also point to
derived data types such as arrays and user-defined data types
such as structures.
2. Array Pointer
Pointers and Array are closely related to each other. Even the
array name is the pointer to its first element. They are also
known as Pointer to Arrays. We can create a pointer to an array
using the given syntax.
Syntax of Array Pointers
char *pointer_name = &array_name;
Pointer to Arrays exhibits some interesting properties which we
discussed later in this article.
3. Structure Pointer
63
4. Function Pointers
5. Double Pointers
6. NULL Pointer
The Null Pointers are those pointers that do not point to any
memory location. They can be created by assigning a NULL
value to the pointer. A pointer of any type can be assigned the
NULL value.
Syntax of NULL Pointer in C
data_type *pointer_name = NULL;
or
pointer_name = NULL
It is said to be good practice to assign NULL to the pointers
currently not in use.
64
7. Void Pointer
8. Wild Pointers
The Wild Pointers are pointers that have not been initialized
with something yet. These types of C-pointers can cause
problems in our programs and can eventually cause them to
crash.
Example of Wild Pointers
int *ptr;
char *str;
9. Constant Pointers
Structures in C:-
65
What is Structure data type?
A structure is a keyword that creates user-defined data types
in C/C++. A structure creates a data type that can be used to
group items of possibly different types into a single type.
How to declare structure variables?
A structure variable can either be declared with structure
declaration or as a separate declaration like basic types.
• C
// A variable declaration with structure declaration.
struct Point
{
int x, y;
} p1; // The variable p1 is declared with 'Point'
int main()
{
struct Point p1; // The variable p1 is declared like a
normal variable
}
66
Where to use the Structure data type?
We can use this data type to store data of different attributes
of different data types.
For example, If we want to store data on multiple patients such
as patient name, age, and blood group.
How to create a structure?
‘struct’ keyword is used to create a structure. Following is an
example.
• C
struct address
{
char name[50];
char street[100];
char city[50];
char state[20];
int pin;
Limitations of C Structures:-
In C language, Structures provide a method for packing
together data of different types. A Structure is a helpful tool to
handle a group of logically related data items. However, C
structures have some limitations.
• The C structure does not allow the struct data type to
be treated like built-in data types:
• We cannot use operators like +,- etc. on Structure
variables. For example, consider the following code:
• C
struct number {
float x;
};
int main()
{
struct number n1, n2, n3;
67
n1.x = 4;
n2.x = 3;
n3 = n1 + n2;
return 0;
}
/*Output:
*/
Unions:-
A union is a special data type available in C that allows to
store different data types in the same memory location. You
can define a union with many members, but only one member
can contain a value at any given time. Unions provide an
efficient way of using the same memory location for
multiple-purpose.
To define a union, you must use the union statement in the
same way as you did while defining a structure. The union
statement defines a new data type with more than one member
for your program. The format of the union statement is as
follows −
union [union tag] {
member definition;
member definition;
...
member definition;
} [one or more union variables];
The union tag is optional and each member definition is a
normal variable definition, such as int i; or float f; or any other
68
valid variable definition. At the end of the union's definition,
before the final semicolon, you can specify one or more union
variables but it is optional. Here is the way you would define a
union type named Data having three members i, f, and str −
union Data {
int i;
float f;
char str[20];
} data;
Now, a variable of Data type can store an integer, a floating-
point number, or a string of characters. It means a single
variable, i.e., same memory location, can be used to store
multiple types of data. You can use any built-in or user defined
data types inside a union based on your requirement.
The memory occupied by a union will be large enough to hold
the largest member of the union. For example, in the above
example, Data type will occupy 20 bytes of memory space
because this is the maximum space which can be occupied by a
character string. The following example displays the total
memory size occupied by the above union −
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
char str[20];
};
int main( ) {
return 0;
}
When the above code is compiled and executed, it produces the
following result −
Memory size occupied by data : 20
69
File Handling:-
70
r Searches file. If the file is opened successfully
fopen( ) loads it into memory and sets up a pointer
that points to the first character in it. If the file
cannot be opened fopen( ) returns NULL.
rb Open for reading in binary mode. If the file does
not exist, fopen( ) returns NULL.
w Searches file. If the file exists, its contents are
overwritten. If the file doesn’t exist, a new file is
created. Returns NULL, if unable to open the file.
wb Open for writing in binary mode. If the file exists,
its contents are overwritten. If the file does not
exist, it will be created.
a Searches file. If the file is opened successfully
fopen( ) loads it into memory and sets up a pointer
that points to the last character in it. If the file
doesn’t exist, a new file is created. Returns NULL,
if unable to open the file.
ab Open for append in binary mode. Data is added to
the end of the file. If the file does not exist, it will
be created.
r+ Searches file. It is opened successfully fopen( )
loads it into memory and sets up a pointer that
points to the first character in it. Returns NULL, if
unable to open the file.
rb+ Open for both reading and writing in binary mode.
If the file does not exist, fopen( ) returns NULL.
w+ Searches file. If the file exists, its contents are
overwritten. If the file doesn’t exist a new file is
created. Returns NULL, if unable to open the file.
wb+ Open for both reading and writing in binary mode.
If the file exists, its contents are overwritten. If the
file does not exist, it will be created.
a+ Searches file. If the file is opened successfully
fopen( ) loads it into memory and sets up a pointer
that points to the last character in it. If the file
doesn’t exist, a new file is created. Returns NULL,
if unable to open the file.
ab+ Open for both reading and appending in binary
mode. If the file does not exist, it will be created.
Pointers and its importance:-
71
without using pointers. So it becomes necessary to learn
pointers to become a perfect C programmer. Let's start learning
them in simple and easy steps.
As you know, every variable is a memory location and every
memory location has its address defined which can be accessed
using ampersand (&) operator, which denotes an address in
memory. Consider the following example, which prints the
address of the variables defined −
#include <stdio.h>
int main () {
int var1;
char var2[10];
return 0;
}
When the above code is compiled and executed, it produces the
following result −
Address of var1 variable: bff5a400
Address of var2 variable: bff5a3f6
What are Pointers?
A pointer is a variable whose value is the address of another
variable, i.e., direct address of the memory location. Like any
variable or constant, you must declare a pointer before using it
to store any variable address. The general form of a pointer
variable declaration is −
type *var-name;
Here, type is the pointer's base type; it must be a valid C data
type and var-name is the name of the pointer variable. The
asterisk * used to declare a pointer is the same asterisk used for
multiplication. However, in this statement the asterisk is being
used to designate a variable as a pointer. Take a look at some of
the valid pointer declarations −
int *ip; /* pointer to an integer */
double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */
72
The actual data type of the value of all pointers, whether
integer, float, character, or otherwise, is the same, a long
hexadecimal number that represents a memory address. The
only difference between pointers of different data types is the
data type of the variable or constant that the pointer points to.
How to Use Pointers?
There are a few important operations, which we will do with the
help of pointers very frequently. (a) We define a pointer
variable, (b) assign the address of a variable to a pointer
and (c) finally access the value at the address available in the
pointer variable. This is done by using unary operator * that
returns the value of the variable located at the address specified
by its operand. The following example makes use of these
operations −
#include <stdio.h>
int main () {
return 0;
}
When the above code is compiled and executed, it produces the
following result −
Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20
NULL Pointers
It is always a good practice to assign a NULL value to a pointer
variable in case you do not have an exact address to be assigned.
73
This is done at the time of variable declaration. A pointer that
is assigned NULL is called a null pointer.
The NULL pointer is a constant with a value of zero defined in
several standard libraries. Consider the following program −
#include <stdio.h>
int main () {
return 0;
}
When the above code is compiled and executed, it produces the
following result −
The value of ptr is 0
In most of the operating systems, programs are not permitted
to access memory at address 0 because that memory is reserved
by the operating system. However, the memory address 0 has
special significance; it signals that the pointer is not intended
to point to an accessible memory location. But by convention, if
a pointer contains the null (zero) value, it is assumed to point
to nothing.
To check for a null pointer, you can use an 'if' statement as
follows −
if(ptr) /* succeeds if p is not null */
if(!ptr) /* succeeds if p is null */
Pointers in Detail
Pointers have many but easy concepts and they are very
important to C programming. The following important pointer
concepts should be clear to any C programmer −
1 Pointer arithmetic
There are four arithmetic operators that can be used
in pointers: ++, --, +, -
74
2 Array of pointers
You can define arrays to hold a number of pointers.
3 Pointer to pointer
C allows you to have pointer on a pointer and so on.
75
it will points to 1004. While if a float type pointer is
incremented then it will increment by 4(size of a float) and the
new address will be 1004.
Decrement: It is a condition that also comes under subtraction.
When a pointer is decremented, it actually decrements by the
number equal to the size of the data type for which it is a
pointer.
For Example:
If an integer pointer that stores address 1000 is decremented,
then it will decrement by 4(size of an int) and the new address
it will points to 996. While if a float type pointer is
decremented then it will decrement by 4(size of a float) and
the new address will be 996.
Below is the program to illustrate pointer
increment/decrement:
Pointers can be outputted using %p, since, most of the
computers store the address value in hexadecimal form using
%p gives the value in that form. But for simplicity and
understanding we can also use %u to get the value in Unsigned
int form.
• C
#include <stdio.h>
// pointer increment and decrement
//pointers are incremented and decremented by the size
of the data type they point to
int main()
{
int a = 22;
int *p = &a;
printf("p = %u\n", p); // p = 6422288
p++;
printf("p++ = %u\n", p); //p++ = 6422292 +4 // 4
bytes
p--;
printf("p-- = %u\n", p); //p-- = 6422288 -4 //
restored to original value
float b = 22.22;
float *q = &b;
printf("q = %u\n", q); //q = 6422284
q++;
76
printf("q++ = %u\n", q); //q++ = 6422288 +4 // 4
bytes
q--;
printf("q-- = %u\n", q); //q-- = 6422284 -4 //
restored to original value
char c = 'a';
char *r = &c;
printf("r = %u\n", r); //r = 6422283
r++;
printf("r++ = %u\n", r); //r++ = 6422284 +1 // 1
byte
r--;
printf("r-- = %u\n", r); //r-- = 6422283 -1 //
restored to original value
return 0;
}
Output
p = 1441900792
p++ = 1441900796
p-- = 1441900792
q = 1441900796
q++ = 1441900800
q-- = 1441900796
r = 1441900791
r++ = 1441900792
r-- = 1441900791
Addition
When a pointer is added with a value, the value is first
multiplied by the size of data type and then added to the
pointer.
• C
77
// Driver Code
int main()
{
// Integer variable
int N = 4;
// Pointer to an integer
int *ptr1, *ptr2;
// Addition of 3 to ptr2
ptr2 = ptr2 + 3;
printf("Pointer ptr2 after Addition: ");
printf("%p \n", ptr2);
return 0;
}
Output
Pointer ptr2 before Addition: 0x7ffca373da9c
Pointer ptr2 after Addition: 0x7ffca373daa8
Subtraction
When a pointer is subtracted with a value, the value is first
multiplied by the size of the data type and then subtracted
from the pointer.
Below is the program to illustrate pointer Subtraction:
• C
// Driver Code
int main()
{
// Integer variable
78
int N = 4;
// Pointer to an integer
int *ptr1, *ptr2;
// Subtraction of 3 to ptr2
ptr2 = ptr2 - 3;
printf("Pointer ptr2 after Subtraction: ");
printf("%p \n", ptr2);
return 0;
}
Output
Pointer ptr2 before Subtraction: 0x7ffd718ffebc
Pointer ptr2 after Subtraction: 0x7ffd718ffeb0
Subtraction of Two Pointers
The subtraction of two pointers is possible only when they
have the same data type. The result is generated by calculating
the difference between the addresses of the two pointers and
calculating how many bits of data it is according to the pointer
data type. The subtraction of two pointers gives the increments
between the two pointers.
For Example:
Two integer pointers
say ptr1(address:1000) and ptr2(address:1004) are
subtracted. The difference between address is 4 bytes. Since
the size of int is 4 bytes, therefore the increment between
ptr1 and ptr2 is given by (4/4) = 1.
Below is the implementation to illustrate the Subtraction of
Two Pointers:
• C
79
// of two pointers
#include <stdio.h>
// Driver Code
int main()
{
int x = 6; // Integer variable declaration
int N = 4;
// Pointer declaration
int *ptr1, *ptr2;
return 0;
}
Output
ptr1 = 2715594428, ptr2 = 2715594424
Subtraction of ptr1 & ptr2 is 1
Pointer Arithmetic on Arrays:
Pointers contain addresses. Adding two addresses makes no
sense because there is no idea what it would point to.
Subtracting two addresses lets you compute the offset between
the two addresses. An array name acts like a pointer constant.
The value of this pointer constant is the address of the first
element. For Example: if an array named arr then arr and
&arr[0] can be used to reference array as a pointer.
80
Below is the program to illustrate the Pointer Arithmetic on
arrays:
Program 1:
• C
// Driver Code
int main()
{
int N = 5;
// An array
int arr[] = { 1, 2, 3, 4, 5 };
81
#include <stdio.h>
int i, j;
// Driver Code
int main()
{
int N = 3, M = 2;
// A 2D array
int arr[][2] = { { 1, 2 },
{ 3, 4 },
{ 5, 6 } };
// Function Call
traverseArr((int*)arr, N, M);
return 0;
}
Output
12
34
56
82
Declaration structure:-
The structure is a collection of different datatype variables,
grouped together under a single name. It is a heterogeneous
collection of data items that share a common name.
Features of structure
• It is possible to copy the contents of all structural
elements of different data types to another structure
variable of its type by using an assignment operator.
• To handle complex datatypes, it is possible to create
a structure within another structure, which is called
nested structures.
• It is possible to pass an entire structure, individual
elements of structure, and address of structure to a
function.
• It is possible to create structure pointers.
The general form of structure declaration is as follows −
datatype member1;
struct tagname{
datatype member2;
datatype member n;
};
Here,
struct is the keyword.
•
• tagname specifies the name of a structure
• member1, member2 specifies the data items that
makeup structure.
For example,
struct book{
int pages;
char author [30];
float price;
};
Structure variables
There are three ways of declaring structure variables, which are
as follows −
Type 1
83
struct book{
int pages;
char author[30];
float price;
}b;
Type 2
struct{
int pages;
char author[30];
float price;
}b;
Type 3
struct book{
int pages;
char author[30];
float price;
};
struct book b;
Pointer to Pointer:-
A pointer to a pointer is a form of multiple indirection, or a
chain of pointers. Normally, a pointer contains the address of a
variable. When we define a pointer to a pointer, the first pointer
contains the address of the second pointer, which points to the
location that contains the actual value as shown below.
84
#include <stdio.h>
int main () {
int var;
int *ptr;
int **pptr;
var = 3000;
return 0;
}
When the above code is compiled and executed, it produces the
following result −
Value of var = 3000
Value available at *ptr = 3000
Value available at **pptr = 3000
pointers to structures:-
Pointer to structure holds the add of the entire structure.
It is used to create complex data structures such as linked lists,
trees, graphs and so on.
The members of the structure can be accessed using a special
operator called as an arrow operator ( -> ).
Declaration
Following is the declaration for pointers to structures in C
programming −
struct tagname *ptr;
For example − struct student *s −
85
Accessing
It is explained below how to access the pointers to structures.
Ptr-> membername;
For example − s->sno, s->sname, s->marks;
Example Program
The following program shows the usage of pointers to
structures −
#include<stdio.h>
struct student{
int sno;
char sname[30];
float marks;
};
main ( ){
struct student s;
struct student *st;
printf("enter sno, sname, marks:");
scanf ("%d%s%f", & s.sno, s.sname, &s. marks);
st = &s;
printf ("details of the student are");
printf ("Number = %d
", st ->sno);
printf ("name = %s
", st->sname);
printf ("marks =%f
", st ->marks);
getch ( );
}
Output
Let us run the above program that will produce the following
result −
enter sno, sname, marks:1 Lucky 98
details of the student are:
Number = 1
86
name = Lucky
marks =98.000000
Pointer to function:-
In C, like normal data pointers (int *, char *, etc), we can have
pointers to functions. Following is a simple example that shows
declaration and function call using function pointer.
#include <stdio.h>
// A normal function with an int parameter
// and void return type
void fun(int a)
{
printf("Value of a is %d\n", a);
}
int main()
{
// fun_ptr is a pointer to function fun()
void (*fun_ptr)(int) = &fun;
return 0;
}
Output:
Value of a is 10
Following are some interesting facts about function
pointers.
87
For example, in the below program, we have removed address
operator ‘&’ in assignment. We have also changed function call
by removing *, the program still works.
#include <stdio.h>
// A normal function with an int parameter
// and void return type
void fun(int a)
{
printf("Value of a is %d\n", a);
}
int main()
{
void (*fun_ptr)(int) = fun; // & removed
fun_ptr(10); // * removed
return 0;
}
Output:
Value of a is 10
88
}
int main()
{
// fun_ptr_arr is an array of function pointers
void (*fun_ptr_arr[])(int, int) = {add, subtract, multiply};
unsigned int ch, a = 15, b = 10;
(*fun_ptr_arr[ch])(a, b);
return 0;
}
Enter Choice: 0 for add, 1 for subtract and 2 for multiply
2
Multiplication is 150
89
int main()
{
wrapper(fun1);
wrapper(fun2);
return 0;
}
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.
// An example for qsort and comparator
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int arr[] = {10, 5, 15, 12, 90, 80};
int n = sizeof(arr)/sizeof(arr[0]), i;
90
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.
#include <stdio.h>
#include <stdbool.h>
int i;
for (i=0; i<arr_size; i++)
if (compare(ptr + i*ele_size, x))
return i;
int main()
{
int arr[] = {2, 5, 7, 90, 70};
91
int n = sizeof(arr)/sizeof(arr[0]);
int x = 7;
printf ("Returned index is %d ", search(arr, n,
sizeof(int), &x, compare));
return 0;
}
Output:
Returned index is 2
The above search function can be used for any data type by
writing a separate customized compare().
1. malloc()
2. calloc()
3. realloc()
4. free()
Now let's have a quick look at the methods used for dynamic
memory allocation.
92
PlayNext
Unmute
Duration 18:10
Loaded: 0.37%
Â
Fullscreen
Backward Skip 10sPlay VideoForward Skip 10s
1. ptr=(cast-type*)malloc(byte-size)
1. #include<stdio.h>
2. #include<stdlib.h>
3. int main(){
4. int n,i,*ptr,sum=0;
5. printf("Enter number of elements: ");
6. scanf("%d",&n);
7. ptr=(int*)malloc(n*sizeof(int)); //memory allocated usi
ng malloc
8. if(ptr==NULL)
9. {
10. printf("Sorry! unable to allocate memory");
11. exit(0);
12. }
13. printf("Enter elements of array: ");
93
14. for(i=0;i<n;++i)
15. {
16. scanf("%d",ptr+i);
17. sum+=*(ptr+i);
18. }
19. printf("Sum=%d",sum);
20. free(ptr);
21. return 0;
22. }
Output
calloc() function in C
1. ptr=(cast-type*)calloc(number, byte-size)
1. #include<stdio.h>
2. #include<stdlib.h>
3. int main(){
4. int n,i,*ptr,sum=0;
5. printf("Enter number of elements: ");
6. scanf("%d",&n);
7. ptr=(int*)calloc(n,sizeof(int)); //memory allocated usin
g calloc
8. if(ptr==NULL)
9. {
94
10. printf("Sorry! unable to allocate memory");
11. exit(0);
12. }
13. printf("Enter elements of array: ");
14. for(i=0;i<n;++i)
15. {
16. scanf("%d",ptr+i);
17. sum+=*(ptr+i);
18. }
19. printf("Sum=%d",sum);
20. free(ptr);
21. return 0;
22. }
Output
realloc() function in C
1. ptr=realloc(ptr, new-size)
free() function in C
1. free(ptr)
95
What is an Algorithm? Algorithm Basics:-
The word Algorithm means ” A set of finite rules or instructions
to be followed in calculations or other problem-solving
operations ” Or ” A procedure for solving a mathematical
problem in a finite number of steps that frequently involves
recursive operations”.
Therefore Algorithm refers to a sequence of finite steps to
solve a particular problem.
96
It can be understood by taking the example of cooking a new
recipe. To cook a new recipe, one reads the instructions and
steps and executes them one by one, in the given sequence.
The result thus obtained is the new dish is cooked perfectly.
Every time you use your phone, computer, laptop, or calculator
you are using Algorithms. Similarly, algorithms help to do a
task in programming to get the expected output.
The Algorithm designed are language-independent, i.e. they are
just plain instructions that can be implemented in any
language, and yet the output will be the same, as expected.
What is the need for algorithms:
1.Algorithms are necessary for solving complex problems
efficiently and effectively.
2.They help to automate processes and make them more
reliable, faster, and easier to perform.
3.Algorithms also enable computers to perform tasks that
would be difficult or impossible for humans to do manually.
4.They are used in various fields such as mathematics,
computer science, engineering, finance, and many others to
optimize processes, analyze data, make predictions, and
provide solutions to problems.
What are the Characteristics of an Algorithm?
97
As one would not follow any written instructions to cook the
recipe, but only the standard one. Similarly, not all written
instructions for programming is an algorithms. In order for
some instructions to be an algorithm, it must have the
following characteristics:
• Clear and Unambiguous: The algorithm should be clear
and unambiguous. Each of its steps should be clear in
all aspects and must lead to only one meaning.
• Well-Defined Inputs: If an algorithm says to take
inputs, it should be well-defined inputs. It may or may
not take input.
• Well-Defined Outputs: The algorithm must clearly
define what output will be yielded and it should be well-
defined as well. It should produce at least 1 output.
• Finite-ness: The algorithm must be finite, i.e. it should
terminate after a finite time.
• Feasible: The algorithm must be simple, generic, and
practical, such that it can be executed with the available
resources. It must not contain some future technology
or anything.
• Language Independent: The Algorithm designed must
be language-independent, i.e. it must be just plain
instructions that can be implemented in any language,
and yet the output will be the same, as expected.
• Input: An algorithm has zero or more inputs. Each that
contains a fundamental operator must accept zero or
more inputs.
• Output: An algorithm produces at least one
output.Every instruction that contains a fundamental
operator must accept zero or more inputs.
• Definiteness: All instructions in an algorithm must be
unambiguous, precise, and easy to interpret. By
referring to any of the instructions in an algorithm one
can clearly understand what is to be done. Every
fundamental operator in instruction must be defined
without any ambiguity.
• Finiteness: An algorithm must terminate after a finite
number of steps in all test cases. Every instruction
which contains a fundamental operator must be
terminated within a finite amount of time. Infinite loops
or recursive functions without base conditions do not
possess finiteness.
98
• Effectiveness: An algorithm must be developed by
using very basic, simple, and feasible operations so that
one can trace it out by using just paper and pencil.
Properties of Algorithm:
• It should terminate after a finite time.
• It should produce at least one output.
• It should take zero or more input.
• It should be deterministic means giving the same
output for the same input case.
• Every step in the algorithm must be effective i.e. every
step should do some work.
Types of Algorithms:
There are several types of algorithms available. Some
important algorithms are:
1. Brute Force Algorithm: It is the simplest approach for a
problem. A brute force algorithm is the first approach that
comes to finding when we see a problem.
2. Recursive Algorithm: A recursive algorithm is based
on recursion. In this case, a problem is broken into several sub-
parts and called the same function again and again.
3. Backtracking Algorithm: The backtracking algorithm
basically builds the solution by searching among all possible
solutions. Using this algorithm, we keep on building the
solution following criteria. Whenever a solution fails we trace
back to the failure point and build on the next solution and
continue this process till we find the solution or all possible
solutions are looked after.
4. Searching Algorithm: Searching algorithms are the ones
that are used for searching elements or groups of elements
from a particular data structure. They can be of different types
based on their approach or the data structure in which the
element should be found.
5. Sorting Algorithm: Sorting is arranging a group of data in a
particular manner according to the requirement. The
algorithms which help in performing this function are called
sorting algorithms. Generally sorting algorithms are used to
sort groups of data in an increasing or decreasing manner.
6. Hashing Algorithm: Hashing algorithms work similarly to
the searching algorithm. But they contain an index with a key
ID. In hashing, a key is assigned to specific data.
7. Divide and Conquer Algorithm: This algorithm breaks a
problem into sub-problems, solves a single sub-problem and
merges the solutions together to get the final solution. It
consists of the following three steps:
99
• Divide
• Solve
• Combine
8. Greedy Algorithm: In this type of algorithm the solution is
built part by part. The solution of the next part is built based
on the immediate benefit of the next part. The one solution
giving the most benefit will be chosen as the solution for the
next part.
9. Dynamic Programming Algorithm: This algorithm uses the
concept of using the already found solution to avoid repetitive
calculation of the same part of the problem. It divides the
problem into smaller overlapping subproblems and solves
them.
10. Randomized Algorithm: In the randomized algorithm we
use a random number so it gives immediate benefit. The
random number helps in deciding the expected outcome.
To learn more about the types of algorithms refer to the article
about “Types of Algorithms“.
Advantages of Algorithms:
• It is easy to understand.
• An algorithm is a step-wise representation of a solution
to a given problem.
• In Algorithm the problem is broken down into smaller
pieces or steps hence, it is easier for the programmer
to convert it into an actual program.
Disadvantages of Algorithms:
• Writing an algorithm takes a long time so it is time-
consuming.
• Understanding complex logic through algorithms can
be very difficult.
• Branching and Looping statements are difficult to show
in Algorithms(imp)
Algorithm in C Language
100
• Sort − Algorithm to sort items in a certain order.
• Insert − Algorithm to insert item in a data structure.
• Update − Algorithm to update an existing item in a data
structure.
• Delete − Algorithm to delete an existing item from a data
structure.
Characteristics of an Algorithm
Not all procedures can be called an algorithm. An algorithm
should have the following characteristics −
Example
Let’s try to learn algorithm-writing by using an example.
101
Problem − Design an algorithm to add two numbers and display
the result.
Step 1 − START
Step 6 − print c
Step 7 − STOP
Step 3 − c ← a + b
Step 4 − display c
Step 5 − STOP
102
Hence, many solution algorithms can be derived for a given
problem. The next step is to analyze those proposed solution
algorithms and implement the best suitable solution.
Algorithm Analysis
Efficiency of an algorithm can be analyzed at two different
stages, before implementation and after implementation. They
are the following −
Algorithm Complexity
Suppose X is an algorithm and n is the size of input data, the
time and space used by the algorithm X are the two main factors,
which decide the efficiency of X.
103
• Time Factor − Time is measured by counting the number
of key operations such as comparisons in the sorting
algorithm.
• Space Factor − Space is measured by counting the
maximum memory space required by the algorithm.
Space Complexity
Space complexity of an algorithm represents the amount of
memory space required by the algorithm in its life cycle. The
space required by an algorithm is equal to the sum of the
following two components −
Algorithm: SUM(A, B)
Step 1 – START
Step 2 – C ← A + B + 10
Step 3 – Stop
Time Complexity
Time complexity of an algorithm represents the amount of time
required by the algorithm to run to completion. Time
requirements can be defined as a numerical function T(n), where
104
T(n) can be measured as the number of steps, provided each
step consumes constant time.
Using Arrays:
2D array is used to represent a sparse matrix in which there are
three rows named as
• Row: Index of row, where non-zero element is located
• Column: Index of column, where non-zero element is
located
• Value: Value of the non zero element located at index –
(row,column)
105
Implementation:
• C++
• C
• Java
• Python3
• C#
• Javascript
int main()
{
// Assume 4x5 sparse matrix
int sparseMatrix[4][5] =
{
{0 , 0 , 3 , 0 , 4 },
{0 , 0 , 5 , 7 , 0 },
{0 , 0 , 0 , 0 , 0 },
{0 , 2 , 6 , 0 , 0 }
};
int size = 0;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 5; j++)
if (sparseMatrix[i][j] != 0)
size++;
106
// Making of new matrix
int k = 0;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 5; j++)
if (sparseMatrix[i][j] != 0)
{
compactMatrix[0][k] = i;
compactMatrix[1][k] = j;
compactMatrix[2][k] = sparseMatrix[i][j];
k++;
}
cout <<"\n";
}
return 0;
}
107
called push operation, and the deletion of an element from the
stack is called pop operation. In stack, we always keep track of
the last element present in the list with a pointer called top.
The diagrammatic representation of the stack is given below:
108
Stacks are based on the Queues are based on the FIFO
LIFO principle, i.e., the principle, i.e., the element
element inserted at the inserted at the first, is the first
last, is the first element to element to come out of the list.
come out of the list.
Stacks are often used for Queues are often used for tasks
tasks that require that involve processing elements
backtracking, such as in a specific order, such as
parsing expressions or handling requests or scheduling
implementing undo tasks.
functionality.
Insertion and deletion in Insertion and deletion in queues
stacks takes place only takes place from the opposite
from one end of the list ends of the list. The insertion
called the top. takes place at the rear of the list
and the deletion takes place from
the front of the list.
Insert operation is called Insert operation is called
push operation. enqueue operation.
Stacks are implemented Queues are implemented using
using an array or linked list an array or linked list data
data structure. structure.
Delete operation is called Delete operation is called
pop operation. dequeue operation.
In stacks we maintain only In queues we maintain two
one pointer to access the pointers to access the list. The
list, called the top, which front pointer always points to the
always points to the last first element inserted in the list
element present in the list. and is still present, and the rear
pointer always points to the last
inserted element.
Stack is used in solving Queue is used in solving
problems works problems having sequential
on recursion. processing.
Stacks are often used for Queues are often used in
recursive algorithms or for multithreaded applications,
maintaining a history of where tasks are added to a queue
function calls. and executed by a pool of worker
threads.
Stack does not have any Queue is of three types – 1.
types. Circular Queue 2. Priority queue
3. double-ended queue.
Can be considered as a Can be considered as a horizontal
vertical collection visual. collection visual.
109
Examples of stack-based Examples of queue-based
languages include algorithms include Breadth-First
PostScript and Forth. Search (BFS) and printing a binary
tree level-by-level.
Applications of stack:
• Some CPUs have their entire assembly language based
on the concept of performing operations on registers
that are stored in a stack.
• Stack structure is used in the C++ run-time system.
• A Stack can be used for evaluating expressions consisting
of operands and operators.
• Stacks can be used for Backtracking, i.e., to check
parenthesis matching in an expression.
• It can also be used to convert one form of expression to
another form.
• It can be used for systematic Memory Management.
Applications of queue:
• Queue data structure is implemented in the hardware
microinstructions inside a CPU.
• Queue structure is used in most operating systems
110
For example, The above expression can be written in the prefix
form as / * A + B C D. This type of expression cannot be simply
decoded as infix expressions.
Postfix: In postfix expression, an operator is written after its
operands. This notation is also known as “Reverse Polish
notation”.
For example, The above expression can be written in the postfix
form as A B C + * D /. This type of expression cannot be simply
decoded as infix expressions.
Refer to the table below to understand these expressions with
some examples:
Infix Prefix Postfix
A+B +AB AB+
Examples:
A * (B + C) / D ABC+*D/ /*A+BCD
A * (B + C / D) ABCD/+* *A+B/CD
Circular Queue:-
A Circular Queue is an extended version of a normal
queue where the last element of the queue is connected to the
first element of the queue forming a circle.
The operations are performed based on FIFO (First In First Out)
principle. It is also called ‘Ring Buffer’.
111
Operations on Circular Queue:-
• Front: Get the front item from the queue.
• Rear: Get the last item from the queue.
• enQueue(value) This function is used to insert an
element into the circular queue. In a circular queue, the
new element is always inserted at the rear position.
• Check whether the queue is full – [i.e., the rear
end is in just before the front end in a circular
manner].
• If it is full then display Queue is full.
• If the queue is not full then, insert an
element at the end of the queue.
• deQueue() This function is used to delete an element
from the circular queue. In a circular queue, the
element is always deleted from the front position.
• Check whether the queue is Empty.
• If it is empty then display Queue is empty.
• If the queue is not empty, then get the
last element and remove it from the
queue.
112
Advantages:-
Circular Queues offer a quick and clean way to store FIFO data
with a maximum size.
• Doesn’t use dynamic memory → No memory leaks
• Conserves memory as we only store up to our
capacity (opposed to a queue which could continue to
grow if input outpaces output.)
• Simple Implementation → easy to trust and test
• Never has to reorganize / copy data around
• All operations occur in constant time O(1)
Disadvantages:-
113
size() Determines the number of O(1)
elements in the deque.
Other operations performed on deques are explained as
follows:
clear(): Remove all the elements from the deque. It leaves the
deque with a size of 0.
erase(): Remove one or more elements from the deque. It takes
an iterator specifying the position of the first element to be
removed, and an optional second iterator specifying the
position of the last element to be removed.
swap(): Swap the contents of one deque with another deque.
emplace_front(): Insert a new element at the front of the deque.
It is similar to the insert operation, but it avoids the copy
constructor of the element being inserted.
emplace_back(): Insert a new element at the back of the deque.
It is similar to the insert operation, but it avoids the copy
constructor of the element being inserted.
resize(): Change the number of elements in the deque to a
specific number. If the new size is larger than the current size,
new elements are appended to the deque. If the new size is
smaller than the current size, elements are removed from the
deque.
assign(): Assign new values to the elements in the deque. It
replaces the current contents of the deque with new elements.
reverse(): Reverse the order of the elements in the deque.
sort(): Sort the elements in the deque in ascending order. It
uses the less-than operator to compare the elements.
Applications of Deque: Since Deque supports both stack and
queue operations, it can be used as both. The Deque data
structure supports clockwise and anticlockwise rotations in
O(1) time which can be useful in certain applications. Also, the
problems where elements need to be removed and or added to
both ends can be efficiently solved using Deque. For example
see the Maximum of all subarrays of size k problem., 0-1
BFS, and Find the first circular tour that visits all petrol pumps.
See the wiki page for another example of the A-Steal job
scheduling algorithm where Deque is used as deletions
operation is required at both ends.
Some Practical Applications of Deque:
• Applied as both stack and queue, as it supports both
operations.
• Storing a web browser’s history.
• Storing a software application’s list of undo operations.
• Job scheduling algorithm
114