C Unit 1 and 2 Notes (1) - 91-181
C Unit 1 and 2 Notes (1) - 91-181
Array Definition:
Syntax: Data_type Array_name[Size]; // Declaration syntax
Data_type : Specifies the type of the element that will be contained in the array
Size: Indicates the maximum number of elements that can be stored inside the array
Array_name: Identifier to identify a variable.
Subscripts in array can be integer constant or integer variable or expression that yields
integer
C performs no bound checking – care should be taken to ensure that the array indices
are within the declared limits
Examples:
float average [6]: // Can contain 6 floating point elements, 0 to 5 are valid array
indices
char name[20]; // Can contain 20 char elements, 0 to 19 are valid array indices
double x[15]; // Can contain 15 elements of type double, 0 to 14 are valid array
indices.
Address of the first element is called the Base address of the array. Address of ith element of
the array can be found using formula: Address of ith element = Base address + (size of each
element * i)
Array Initialization:
• After an array is declared it must be initialized.
• An Uninitialized array will contain undefined values/junk values.
• An array can be initialized at either compile time or at runtime
Partial Initialization:
Consider int a3[10] = {44,33,10,25,78,33,89};
Size of the array is specified. But only few elements are stored. Now, the size of the array is
10*4 = 40 bytes of memory in a contiguous manner. All uninitialized memory locations in
the array are filled with default value 0.
printf("size of array is %d\n", sizeof(a3)); //40 bytes
printf("%p %p\n",a3, &a3); // Must be different. But shows same address
Above code prints initialized values when i is between 0 to 5. When i becomes 6, a2[6] is
outside bound as the size of a2 is fixed at compile time and it is 6*4(size of int is
implementation specific) = 24 bytes
Anytime accessing elements outside the array bound is an undefined behavior.
Coding Example_1: Let us consider the program to read 10 elements from the user and
display those 10 elements.
#include<stdio.h>
int main()
{ int arr[100]; int n;
printf("enter the number of elements\n");
scanf("%d",&n);
printf("enter %d elements\n",n);
int i = 0;
while(i<n)
{ scanf("%d",&arr[i]); i++;
}
printf("entered elements are\n");
i = 0;
while(i<n)
{ printf("%d\n",arr[i]); i++;
}
return 0;
}
Output:
Coding Example_2: Let us consider the program to find the sum of the elements of an
array.
int arr[] = {-1,4,3,1,7}; int i; int sum = 0;
int n = sizeof(arr)/sizeof(arr[0]);
for(i = 0; i<n; i++)
{ sum += arr[i]; }
printf("sum of elements of the array is %d\n", sum);
Introduction to 2D Arrays in C
A multi-dimensional array is an array with more than one level or dimension. It might
be 2-Dimensional and 3-Dimensional and so on.
1D array may be used to store single dimension data or information. When we want to
manipulate the arrays by rearranging the elements by using functions like reshape, squeeze
and so on, which may be very challenging to visualize using a 1D array. Then, 2D array can
come into play we may have to store complex data which has rows and columns. Likewise,
we may want to store three dimensions of data as well. Then we go for 3D array and so on.
Consider the example of storing marks of 5 students in some particular subject A. We can
define, int A_marks[ ] = {90,95,99,100,89};
Now, rather than storing marks this way in One - Dimensional Array, we can use Two -
Dimensional array as we have two dimensions involved in this particular example: student
and subject marks
Definition of a 2D Array:
data_type array_name[size_1][size_2];
arr
X X X X X X X X
2000 2004 2008 2012 2016 2020 2024 2028
If the size of the integer is 4 bytes, 8 contiguous locations allocated
Initialization of a 2D Array:
Compiler knows the array size based the array elements and allocates memory
data_type array_name[size_1][size_2] = {elements separated by comma};
int arr[][] = {11,22,33,44,55,66}; // Error. Column size is compulsory
Without knowing the number of columns in each row – it is impossible to locate an element
in 2D array.
int arr[3][2] = {{11,22},{33,44},{55,66}};
int arr[3][2] = {11,22,33,44,55,66};
// Allocate 6 contiguous memory locations and assign the values
int arr[][2] = {11,22,33,44,55,66};
Row major Ordering: All elements of one row are stored followed by all elements of the next
row and so on.
Column Major Ordering: All elements of one column are stored followed by all elements of
the next column and so on.
Consider, int arr[3][4] = {11, 22, 33, 44, 55, 66, 77, 88, 99, 100, 111, 121};
If the size of integer is 4 bytes in the system and the base address is 5000, then address of
arr[1][5] can be found by 5000+((1*4)+5)*4 = 5000+9*4 = 5000+36 = 5036.
Think about finding the address of a[0][5] and a[1][3]. Is this same as a[5][0] and a[3][1]
respectively?
Level-1: Banana
1. Given the array, build an application to find the sum of all elements of the array.
int arr1[ ] = {5, 10, 15, 20, 25};
2. Seven friends decided to have a race in the park. After the race, they recorded their
running times in seconds: [12, 15, 10, 18, 9, 14, 11]
Implement the logic in C to find out the running time for a fastest runner?
3. Develop a C Application to Count the number of elements in the given array and
print the count.
int arr1[ ] = {5, 10, 15, 20, 25, 12, 99, 56, 33, 29, 10};
4. Build an application in C to find the count of even and odd integers in a given array.
int arr1[ ] = {5, 10, 15, 20, 25, 12, 99, 56, 33, 29, 10};
6. Given an array, count how many numbers are positive and how many are negative.
int arr[] = {-5, 10, -15, 20, -25, 12, -99, 56, 33, -29, 10};
Expected output:
Count of positive numbers: 6
Count of negative numbers: 5
7. Given an array and a number X, count how many numbers are greater than X and print
them.
int arr[] = {5, 10, 15, 20, 25, 12, 99, 56, 33, 29, 10};
int x = 20;
Expected output:
Count of numbers greater than 20: 5
Numbers greater then 20 are - 25, 99, 56, 33, 29
8. Emma wanted to find out which stickers were repeated in her collection. She carefully
arranged all the stickers and noted down their numbers in sequence:
[12, 25, 30, 12, 45, 60, 25, 30, 75, 90, 45]. Now, she faced a challenge: Can you figure
out how many stickers appeared more than once?
9. Given an array, count how many numbers end with a specific digit X(e.g., 5).
int arr[] = {5, 15, 25, 30, 45, 50, 60, 75};
X=5
Expected output: Count of numbers ending with 5: 5
10. A young programmer, Alex, found a magical book that contained an ancient spell to
reverse time. The spell was hidden in a sequence of numbers, and to unlock its power,
Alex needed to reverse the sequence. Help Alex to decode the spell by implementing
an application using C.
Level-2: Orange
11. Write a program that checks and prints if the given array of integers is a Palindrome
or not. Receive all inputs from the user.
[1,3,2,2,3,1] -> Palindrome
[1,3,2,3,1] -> Palindrome
[10,32,25,32,10] -> Palindrome
[1,4,6,3,1] ->Not A Palindrome
12. Write a Program to create an Array of n integers and check if the array is “Really
Sorted” , “Sorted”,“Not Sorted”
Example #1 : [1,2,5,7,10] -> Really Sorted
Example #2 : [1,2,5,5,10] -> Sorted
Example #3 : [1,12,5,45,10] -> Not Sorted
13. Given the array of n integers, count the number of Unique Elements in the
Array(not repeated elements) and store these elements in a new array.
int arr[] = {5, 7, 3, 4, 5, 6, 8, 9, 10, 3};
Expected Input and Output:
Given Array -> [5,7,3,4,5,6,8,9,10,3]
New array -> [7,4,6,8,9,10]
Number of Unique Elements -> 6
14. Write a C Program that should rotate the given array by N positions at the left.
Expected Input and Output:
Input: [5,4,7,3]
If N = 2
After left Rotation -> [7,3,5,4]
15. Given a list of N integers, representing height of mountains. Find the height of the
tallest mountain and the second tallest mountain. Handle edge cases by displaying
appropriate messages.
Example #1 : [4,7,6,3,1]
7 -> height of the tallest mountain
6 -> height of the second tallest mountain
Level-3: Jackfruit
16. Write a C program to input N integers to the array and find the median of sorted array
of integers. Median is calculated using the below formulae:
17. Abhi is a salesman. He was given two types of candies, which he is selling
in N different cities. In his excitement, Abhi wrote down the prices of both the candies
on the same page and in random order instead of writing them on different pages. Now
he is asking for your help to find out if the prices he wrote are valid or not. You are
given an array A of size 2N. Find out whether it is possible to split A into two arrays,
each of length N, such that both arrays consist of distinct elements.
18. Given an array A of size N, your task is to find and print all the peak elements in the
array. A peak element is one that is strictly greater than its neighboring elements. For
the first and last elements, only consider their single adjacent element. If no peak
element exists in the array, print -1.
19. Develop an application that calculates and prints the largest sum of two Adjacent
Elements in the array. Display appropriate message for handling the edge cases.
Example #1 : [1,4,3,7,1] ->10
Example #2 : [5,7,1,5,2] ->12
20. Our James has some students in his coding class who are practicing problems. Given
the difficulty of the problems that the students have solved in order, help
the James identify if they are solving them in non-decreasing order of difficulty. Non-
decreasing means that the values in an array is either increasing or remaining the
same, but not decreasing. That is, the students should not solve a problem with
difficulty d1, and then later a problem with difficulty d2, where d1>d2. Output “Yes” if
the problems are attempted in non-decreasing order of difficulty rating and “No” if not.
Introduction
• Pointer is a variable which contains the address. This address is the location of
another object in the memory.
• Pointers can be used to access and manipulate data stored in memory.
• Pointer of particular type can point to address any value of that particular type.
• Size of pointer of any type is same /constant in that system.
• Not all pointers actually contain an address
Example: NULL pointer // Value of NULL pointer is 0.
Note: A pointer is a variable that stores the memory address of another variable as its
value. The address of the variable we are working with is assigned to the pointer.
We can get the value of the variable the pointer currently points to, by dereferencing pointer
by using the * operator. When used in declaration like int* ptr, it creates a pointer variable.
When not used in declaration, it act as a dereference operator w.r.t pointers
Pointer Definition:
Syntax: Data-type *name;
Example: int *p; // Compiler assumes that any address that it holds points to an
integer type.
p= ∑ // Memory address of sum variable is stored into p.
Coding Example_1:
int *p; // p can point to anything where integer is stored. int* is the type. Not just int.
int a = 100;
p=&a;
printf("a is %d and *p is %d", a,*p);
Pointer Arithmetic:
Below arithmetic operations are allowed on pointers
Add an int to a pointer
Subtract an int from a pointer
Difference of two pointers when they point to the same array.
Note:
Integer is not same as pointer.
We get warning when we try to compile the code where integer is stored in variable
of int* type.
Coding Example_3:
int arr[ ] = {12,33,44};
int *p2 = arr;
printf("before increment %p %d\n",p2, *p2); // Some address 12
p2++; //same as p2 = p2+1
// This means 5000+sizeof(every element)*1 if 5000 is the base address
//increment the pointer by 1. p2 is now pointing to next location.
printf("after increment %p %d\n",p2, *p2); // 33
Coding Example_5:
int main()
{
int *p;
int a = 10;
p = &a;
Coding Example_6:
int main()
{
int *p;
int a = 10;
p = &a;
printf("%d\n",*p);//10
printf("%d\n",(*p)++);// 10 value of p is used and then value of p is incremented
printf("%d\n",*p); // 11
return 0;
}
Version 3:
for(i = 0;i<5;i++)
printf("%d \t",*p3++); // 12 44 22 33 55
// Use p3, then increment, every iteration p3 is incremented.
Version 5:
for(i = 0;i<5;i++)
printf("%d \t",(*p3)++); // 12 13 14 15 16
// every iteration value at p3 is used and then incremented.
Version 6:
for(i = 0;i<5;i++,p3++)
printf("%d \t",*p3); // 12 44 22 33 55
// every iteration value at p3 is used and then p3 is incremented.
Version 7: p3 and arr has same base address of the array stored in it. But array is a constant
pointer. It cannot point to anything in the world.
for(i = 0;i<5;i++)
printf("%d \t", *arr++); // Compile Time Error
Note: If variable i is used in loop for the traversal, a[i], *(a+i), p[i], *(p+i), i[a], i[p] are all
same.
3. String literal initialization of a character array – Will be discussed in detail in next lecture
• char array[] = “abc” sets the first four elements in array to ‘a’, ‘b’, ‘c’, and ‘\0’
• char *pointer = “abc” sets pointer to the address of the “abc” string (which may
be stored in read-only memory and thus unchangeable)
• Pointer variable can be assigned a value whereas array variable cannot be.
4. Pointer variable can be assigned a value whereas array variable cannot be.
int a[10];
int *p;
p=a; //allowed
a=p; //not allowed
Array name is a pointer to a row. The expression a + 3 is a pointer to the third row. *(a + 3)
becomes a pointer to the zeroth element of that row. Then +1 becomes a pointer to the next
element in that row. To get the element in that location, dereference the pointer.
Note : The pointer that points to the 0th element of array and the pointer that points to the
whole array are totally different.
Introduction
An array of pointers is a collection where each element is a pointer that stores the
address of another variable (typically of the same type). It is commonly used in scenarios
where multiple variables or memory locations need to be dynamically referenced. Array and
pointers are closely related to each other. The name of an array is considered as a pointer, i.e.,
the name of an array contains the address of an element.
Applications:
Array of pointers to integers offers several benefits in terms of memory efficiency,
flexibility, and computational performance.
Saves memory, especially when dealing with sparse data structures.
Useful when data sizes vary, such as in jagged arrays.
Supports implementation of complex data structures like trees and graphs.
Makes handling pointers to pointers more structured.
Used in hash tables where each index points to a linked list.
Coding Example_1:
#include<stdio.h>
int main()
{
int i;
int a[10] = {12,34,66,4,16,18,19,15};
int *p[10]; // p is created with the intention of storing an array of addresses
// Think about the size of p???
p[0] = &a[0];
p[1] = &a[1];
p[2] = &a[2];
for(i = 0 ; i<4;i++){
printf("%p %p\n",p[i],&a[i]); // same address for all 3 pairs except the last iteration as
we have not assigned.
}
// printing array elements using p
for(i = 0 ; i<4;i++) {
printf("%d\t",*p[i]); // dereference every element of the array of pointer
}
return 0;
}
Note: *arr[i] dereferences the pointer to access the actual value.
Coding Example_2: Program to print the elements of the array using array of pointers
#include<stdio.h>
int main()
{ int a[5] = {12,33,45,66,17}; // a is an array
printf("Using original array\n");
for(int i = 0;i<5;i++)
{ printf("%d ",a[i]); }
printf("\n");
int *p[5]; // p is an array of pointers.
for(int i = 0;i<5;i++)
{ p[i] = &a[i]; // address of a[i] stored in p[i] }
printf("Using array of pointers\n");
for(int i = 0;i<5;i++)
{ printf("%d ",*p[i]);
// content at p[i] is displayed. All elements are displayed
}
Department of CSE, PESU 4
Feb – May,2025
printf("\n");
return 0;
}
Introduction to Functions
In case we want to repeat the set of tasks or instructions, we may have two options:
Use the same set of statements every time we want to perform the task
Create a function to perform that task, and just call it every time when we need to
perform that task. This is usually a good practice and a good programmer always uses
functions while writing code in C.
Functions break large computing tasks into smaller ones and enable people to build on what
others have done instead of starting from scratch. In programming, Function is a
subprogram to carry out a specific task. A function is a self-contained block of code that
performs a particular task. Once the function is designed, it can be treated as a black box.
The inner details of operation are invisible to rest of the program. Functions are useful
because of following reasons:
○ To improve the readability of code.
○ Improves the reusability of the code, same function can be used in any program
rather than writing the same code from scratch.
○ Debugging of the code would be easier if we use functions, as errors are easily traced.
○ Reduces the size of the code, redundant set of statements are replaced by function
calls.
Types of functions
C functions can be broadly classified into two categories:
Library Functions
Functions which are defined by C library. Examples include printf(), scanf(),
strcat() etc. We just need to include appropriate header files to use these functions. These are
already declared and defined in C libraries.
User-defined Functions
Functions which are defined by the developer at the time of writing program.
Developer can make changes in the implementation as and when he/she wants. It reduces the
complexity of a big program and optimizes the code, supporting Modular Programming
Paradigm. In order to make use of user defined functions, we need to understand three key
terms associated with functions: Function Definition, Function call and Function
Declaration.
Function Definition
Each function definition has the form
return_type function_name(parameters) // parameters optional
{
// declarations and statements
}
A function definition should have a return type. The return type must match with what that
function returns at the end of the function execution. If the function is not designed to return
anything, then the type must be mentioned as void. Like variables, function name is also an
identifier and hence must follow the rules of an identifier. Parameters list is optional. If more
than one parameter, it must be comma separated. Each parameter is declared with its type
and parameters receive the data sent during the function call. If function has parameters or
not, but the parentheses is must. Block of statements inside the function or body of the
function must be inside { and }. There is no indentation requirement as far as the syntax of C
is considered. For readability purpose, it is a good practice to indent the body of the function.
Function definitions can occur in any order in the source file and the source program can
be split into multiple files. One must also notice that only one value can be returned from
the function, when called by name. There can also be side effects while using functions in
c.
int sum(int a, int b)
{ return a+b; }
int decrement(int y)
{ return y-1; }
Function Call
Function-name(list of arguments); // semicolon compulsory and Arguments depends
on the number of parameters in the function definition
A function can be called by using function name followed by list of arguments (if any)
enclosed in parentheses. The function which calls other function is known to be Caller and
the function which is getting called is known to be the Callee. The arguments must match
the parameters in the function definition in it’s type, order and number. Multiple
arguments must be separated by comma. Arguments can be any expression in C. Need
not be always just variables. A function call is an expression. When a function is called,
Activation record is created. Activation record is another name for Stack Frame. It is
composed of:
• Local variables of the callee
• Return address to the caller
• Location to store return value
• Parameters of the callee
• Temporary Variables
The order in which the arguments are evaluated in a function call is not defined and is
determined by the calling convention(out of the scope of this notes) used by the compiler. It
is left to the compiler Writer. Always arguments are copied to the corresponding
parameters. Then the control is transferred to the called function. Body of the function gets
executed. When all the statements are executed, callee returns to the caller. OR when there is
return statement, the expression of return is evaluated and then callee returns to the caller. If
the return type is void, function must not have return statement inside the function.
Coding Example_1:
#include<stdio.h>
int main()
{
int x = 100;
int y = 10;
int answer = sum(x,y);
printf("sum is %d\n",answer);
answer = decrement(x);
printf("decremented value is %d\n",answer);
disp_hello();
double ans = use_pow(x);
printf("ans is %lf\n",ans);
answer = sum(x+6,y);
printf("answer is %d\n", answer);
printf("power : %lf\n", use_power(5));
return 0;
}
The parameters list must be separated by commas. The parameter names do not need
to be the same in declaration and the function definition. The types must match the type
of parameters in the function definition in number and order. Use of identifiers in the
declaration is optional. When the declared types do not match with the types in the
function definition, compiler will produce an error.
Parameter Passing in C
Parameter passing is always by Value in C. Argument is copied to the corresponding
parameter. The parameter is not copied back to the argument. It is possible to copy back the
parameter to argument only if the argument is l- value. Argument is not affected if we
change the parameter inside a function.
Coding Example_2:
void fun1(int a1); // declaration
void main()
{
int a1 = 100;
printf("before function call a1 is %d\n", a1); // a1 is 100
fun1(a1); // call
printf("after function call a1 is %d\n", a1); // a1 is 100
return 0;
}
void fun1(int a1)
{ printf("a1 in fun1 before changing %d\n", a1); //100 a1 = 200;
printf("a1 in fun1 after changing %d\n", a1); //200
}
a1 has not changed in main function. The parameter a1 in fun1 is a copy of a1 from main
function. Refer to the below diagram to understand activation record creation and deletion to
know this program output in detail.
Coding Example_3:
void fun1(int *a1);
int main()
{ int a1 = 100;
printf("before function call a1 is %d\n", a1); // 100
fun1(&a1); // call
printf("after function call a1 is %d\n", a1); // 200
return 0;
}
void fun1(int *a1)
{ printf("*a1 in fun1 before changing %d\n", *a1); //100
*a1 = 200;
printf("*a1 in fun1 after changing %d\n", *a1); //200
}
Coding Example_3:
void fun1(int *a1);
int main()
{
int a1 = 100;
printf("before function call a1 is %d\n", a1); // 100
fun1(&a1); // call
printf("after function call a1 is %d\n", a1); // 100
return 0;
}
void fun1(int *a1)
{
int b = 200;
printf("*a1 in fun1 before changing %d\n", *a1); //100
a1 = &b;
printf("*a1 in fun1 after changing %d\n", *a1); //200
}
Version 2:
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{ int a = 100;
int b = 200;
printf("before call a is %d and b is %d\n", a, b); // a is 100 and b is 200
swap(&a, &b);
printf("after call a is %d and b is %d\n", a, b); // a is 100 and b is 200
return 0;
}
Coding Example_5:
void f1(int); void f2(int*); void f3(int); void f4(int*);int* f5(int* ); int* f6();
int main()
{ int x = 100;
f1(x);
printf("x is %d\n", x); // 100
double y = 6.5;
f1(y); // observe what happens when double value is passed as argument to integer
parameter?
printf("y is %lf\n", y); // 6.500000
int *p = &x; // pointer variable
f2(p);
printf("x is %d and *p is %d\n", x, *p); // 100 100
f3(*p);
printf("x is %d and *p is %d\n", x, *p); // 100 100
f4(p);
printf("x is %d and *p is %d\n", x, *p, p);
int z= 10;
p =f 5(&z); printf("z is %d and %d\n", *p, z); // 10 10
p = f6(); printf("*p is %d \n", *p);
return 0;
}
void f1(int x)
{ x = 20; }
void f2(int* q)
{
int temp = 200;
q = &temp;
}
void f3(int t)
{ t = 200; }
void f4(int* q)
{
int temp = 200;
*q = temp;
}
int* f5(int* x)
{ return x; }
When there is function call to f6, Activation Record gets created for that and deleted when
the function returns. p points to a variable which is not available after the function execution.
This problem is known as Dangling Pointer. The pointer is available. But the location it is
not available which is pointed by pointer. Applying dereferencing operator(*) on a dangling
pointer is always undefined behaviour.
int* f6()
{
int a = 22; // We should never return a pointer to a local variable
return &a; // Compile time Error
}
When there is function call to f6, Activation Record gets created for that and deleted when
the function returns. p points to a variable which is not available after the function execution.
This problem is known as Dangling Pointer. The pointer is available. But the location it is
not available which is pointed by pointer. Applying dereferencing operator(*) on a dangling
pointer is always undefined behaviour.
Note: We use void as an argument to function, when the function does not accept any
argument.
Introduction
An array is a a data structure that stores multiple values of the same type in
contiguous memory locations, enabling efficient indexing and manipulation. Functions in C
allow modular programming by encapsulating logic into reusable blocks, improving code
organization and reusability. When combined, arrays and functions enable efficient data
processing without unnecessary duplications. In C, care must be taken to avoid exceeding
array bounds, as C does not perform automatic boundary checks. Overall, combining arrays
and functions in C enhances modularity, efficiency, and structured learning.
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
printArray(numbers, size); // Passing array to function
return 0;
}
Note:
o arr[] in the function is equivalent to int *arr, meaning it holds a reference to the array.
o The actual values in numbers are not copied; only the address of the first element is
passed.
o Arrays in C do not carry size information, so we must explicitly pass it to prevent out-
of-bounds errors.
o printArray function can modify the elements of the array. If yiyou want to ensure that
the function does not modify the array, use the const keyword.
Coding Example_2:
void printArray(const int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d\t ", arr[i]);
}
}
Note: Use const, when the function is only reading values from the array and not modify it.
Coding Example_3:
void printArray(int *arr, int size) { ... }
Coding Example_4: Create functions to read n elements into an array and display n
elements of the array. Also include a function to find the sum of all the elements of the
array.
{ sum = sum+a[i]; }
return sum;
}
Version 2: As the array becomes pointer at runtime, finding the size of the passed argument
to any function is same as finding the size of the pointer.
void read_array(int a[])
{
printf("inside read_array sizeof a is %d\n",sizeof(a));
//4 bytes or constant value for any pointer
for(int i= 0; i<n;i++)
{ scanf("%d",&a[i]); }
}
Think!!! -> If n is local to main function, can other functions access n? It throws Compile
time Error. So use version3 code if n is local to main().
read_array(a,n);
printf("entered elements are\n");
display_array(a,n);
printf("\nsum is %d\n",find_sum(a,n));
increment(a,n);
printf("array with updated elements are\n");
display_array(a,n);
return 0;
}
void read_array(int a[],int n)
{
for(int i= 0; i<n;i++)
{ scanf("%d",&a[i]); }
}
void display_array(int a[],int n)
{
for(int i= 0; i<n;i++)
{ printf("%d\t",a[i]); }
}
int find_sum(int a[],int n)
{
int sum = 0;
for(int i= 0; i<n;i++)
{ sum = sum+a[i]; }
return sum;
}
Version 4: Using the pointer in the parameter makes more sense as array become pointer
at runtime during function call.
#include<stdio.h>
void read_array(int*,int);
void display_array(int*,int);
int find_sum(int*,int); // observe this
int main()
{ … }
void read_array(int *a,int n) // this too
{ … }
void display_array(int *a,int n)
{ … }
int find_sum(int *a,int n)
{ … }
Note: Functions like display_array() and find_sum() should not be allowed to make any
changes to the array. But allowed in the above code.
void display_array(int *a,int n)
{ a[4] = 8989; // allowed }
Case 2: Declaration and definition of the function with column size not same as what is
given in the declaration of the array in the client code
void read(int[][3],int m,int n); // warning but code works
void display(int[][3],int m,int n);
Case 3: Declaration and definition of the function with column size same as what is given in
the declaration of the array in the client code
void read(int[][100],int m,int n); // fine.
void display(int[][100],int m,int n);
// But can we say void read(int[][n],int m,int n ) ? Think !!!!
Case 4: If the order of parameters is changed as below in declaration and definition of the
function, we need to change the client code. Changing the client code is not a good
programmer’s habit. Because interface cannot be changed. Implementation can change. So
refer to case 5.
void read(int m,int n,int a[][n]);
void display(int m,int n,int a[][n]);
Case 6: Array degenerates to a pointer at run time. So think about using pointer to an array
as a parameter.
void read(int n; int(*)[n],int m,int n);
void display(int n; int(*)[n],int m,int n);
Level-1: Banana
1. John wants to calculate and display the area of a circular garden with radius 5.5
meters. Use a function to find the area.
2. Emma is learning about factorials in her math class. She wants to find the factorial of a
whole number n. Create a function to calculate it. Display appropriate message if the
input is not valid.
3. Mark wants to check if the entered integer is a prime number for his math homework.
Write a function to determine if it's prime. Display appropriate message for valid and
invalid inputs.
5. Seven friends decided to have a race in the park. After recording their running times in
seconds: [12, 15, 10, 18, 9, 14, 11], find the fastest runner's time.
6. A grocery store recorded the prices of 8 different fruits: [45, 60, 35, 25, 55, 70, 85,
30]. Write a function to find the most expensive fruit's price.
7. Sarah bought 6 items from a store with prices: [120, 85, 200, 35, 40, 75]. Create a
function to calculate the total amount she spent. Show the total amount spent by Sarah
on the terminal.
8. A teacher recorded the scores of 5 students in a test: [85, 92, 78, 90, 88]. Implement a
function to calculate the average score. Display the average.
9. A coach recorded the heights (in cm) of 8 basketball players: [185, 192, 188, 195, 190,
187, 182, 193]. Implement a function to find the second tallest player's height.
10. Emily is a weather analyst who records the daily temperatures of a city for a week at
different times of the day (morning, afternoon, evening, and night). She stores the
temperatures in a 2D array and wants to find the highest temperature recorded during
the week. Write a function that takes this 2D array as input and returns the maximum
temperature.
Level-2: Orange
11. A shopkeeper, Mr. Smith, keeps track of his daily sales for five products over seven
days in a 2Darray. He wants to find out the total sales for each product over the
week. Write a function that takes the 2D array as input and modifies a 1D array
containing the total sales of each product.
13. Write a program to remove the duplicate elements from a sorted array. Fill the
implementation of remove_duplicates function.
Expected output: [1, 2, 3, 4, 5, 6]
Client code is as below:
int arr[] = {1, 1, 2, 2, 3, 4, 4, 5, 6, 6};
int n = sizeof(arr)/sizeof(arr[0]);
remove_duplicates(arr, n);
14. Implement a function that takes the array and the array size. This function must
calculate and display the largest sum of two Adjacent Elements (Neighbours) in
the array. If the array size is less than 2, display appropriate message.
Example #1 : [1,4,3,7,1] ->10
Example #2 : [5,7,1,5,2] ->12
15. Given an array A of length N, implement a function to find the element which
repeats maximum number of times and update the corresponding
frequency_count. In case of a tie, choose the smaller element.
Expected output:
Given array => {2,2,2,1,1,1,1,2,2,31,32,32,32};
The element 2 repeats maximum number of times
Frequency of this element is 5
16. Emma visited a grocery store for fresh supplies. There are N items in the store where
the ith item has a freshness value Ai and cost Bii. Emma has decided to
purchase all the items having a freshness value greater than equal to X. Find the
total cost of the groceries Emma buys.
17. A teacher, Mrs. Patel, maintains a 2D array containing the scores of five students in
four subjects. She wants to compute the average score of each student to determine
their performance. Write a function that takes this 2D array as input and updates
the 1D array with the average score of each student.
Given, int marks[5][4] = { {80, 85, 78, 90}, {70, 75, 88, 85},
{90, 92, 89, 94}, {60, 65, 70, 68}, {85, 88, 82, 86} };
Expected output:
Average marks of each student:
Student 1: 83.25
Student 2: 79.50
Student 3: 91.25
Student 4: 65.75
Student 5: 85.25
18. Alice, a data scientist, is analyzing a 4×4 dataset and wants to find the sum of all
diagonal elements in a square matrix. Implement a function that takes an n×n matrix
and returns the sum of its main diagonal elements. Display the sum of diagonal
elements in the client code.
Level-3: Jackfruit
19. You are given two integer arrays A and B of size N and M respectively. You need to
merge these two arrays using a function. Print the merged array using another function.
20. David is working on a game where he represents a chessboard as an 8×8 2D array, with
0 representing white squares and 1 representing black squares. He wants to rotate the
board 90 degrees clockwise to generate a new pattern. Write separate functions to
rotate the 2D array and print the new board configuration respectively.
21. Emma, a restaurant manager, records daily sales for different sections of her restaurant
in a 5×4 sales matrix (5 sections, 4 days). She wants to identify which section had the
highest total sales. Write separate functions to do the following.
A. Function that takes a sales data from the user for each day for each section as a 2D
array (sales matrix) of size M×N.
B. Function that returns the index of the row (section) with the highest total sum.
22. A group of explorers discovers a sunken ship filled with treasure. The ocean floor is
represented as a 5x5 grid, where each cell contains a number representing the amount
of gold in that location. Some locations have traps (-1 value).
Consider,
int ocean[5][5] = {{5, 3, -1, 4, 10},
{2, 6, 9, -1, 8},
{-1, 7, 12, 15, 1},
{3, -1, 4, 5, 2},
{11, 8, 6, -1, 9}
};
Write functions to do the following.
Find the total treasure collected if the explorers move from the top-left corner
(0,0) to the bottom-right corner (4,4) while avoiding traps.
Expected output:
Total Treasure Collected: 130
Identify the cell with the highest gold. Specify the row and column number.
Expected output:
Highest gold is 15 at cell (3, 4)
Level-1: Banana
1. John is a mathematician who loves to work with collection of integers. He has an
integer array of size N, and wants to calculate the sum of all the numbers in that
array. However, he decides to use an array of pointers to access the elements of the
array as he believes that, it will help him understand memory management better.
Develop a C program which makes John happy by taking N integers from the user and
find the sum of elements using the array of pointers.
2. Mrs. Smith is a teacher who wants to find the average height of her students. She
measures the heights of N students and stores them in an array. To make her program
more efficient, she decides to use an array of pointers to access the heights.
Implement a C function that receives the array of pointers and help Smith to
calculate the average height of her students. Test this function the client code.
3. David has two unique integer values, and he wants to store these in an array of
pointers whose size is 2 blocks. Swap them using an array of pointers using a
function. Print the results before and after calling the function.
5. Alex is a mathematician who wants to calculate the product of all the numbers
stored in an array of pointers to very long integers. He believes using an array of
pointers will make the program more efficient. Write a C program to help Alex
calculate the product of all the numbers in the array. She uses long long as return
type for helper function to find the product.
Level-2: Orange
6. Sarah is a data analyst who has an integer array of size N. She wants to find the
maximum and minimum values in the array. To make her program more efficient, she
decides to use an array of pointers to access the integers. Help Sarah find the
maximum and minimum integer in the array using an array of pointers to
integers by sending this array to findMinMax function.
Prototype of the function is as below with min and max as two variables in the
infterface code.
void findMinMax(int *arr[], int size, int *min, int *max);
Function call: findMinMax(ptrArr, n, &min, &max);
7. Mike is a mathematician who wants to calculate the sum of the squares of N numbers.
He decides to use an array of pointers to access the numbers and perform the
calculation. Implement the C code to help Mike calculate the sum of the squares
of N numbers using an array of pointers. Prototype: int calculateSumOfSquares(int
*arr[], int size);
8. Bob is a programmer who has an array of pointers that point to N numbers stored in the
array. He wants to reverse the order of these numbers and then print the reversed
list of integers using an array of pointers to to make the program more efficient. Write
a C function implementation to do this and test this function in the client code.
Prototype of function => void reverseArray(int *arr[], int size);
9. Emily is a mathematician who wants to calculate the product of all prime numbers
stored in an array of pointers to integers. Implement the C function to help Emily
calculate the product of all prime numbers in the array using array of pointers.
Prototype of function => int calculateProductOfPrimes(int *arr[], int size)
10. Alice is a programmer who has two fixed integer values, A and B. She wants to
calculate their GCD (Greatest Common Divisor) and LCM (Least Common Multiple).
Client code is as below.
int a, b;
printf("Enter two integers (A B): ");
scanf("%d %d", &a, &b);
int *ptrArr[2] = {&a, &b};
int gcdResult, lcmResult;
calculateGCDAndLCM(ptrArr, &gcdResult, &lcmResult);
printf("GCD: %d\nLCM: %d\n", gcdResult, lcmResult);
Level-3: Jackfruit
11. During a severe storm that knocked out power to Seoul University, Professor Ji-hoon's
electronic grade book became corrupted. The only working computer had limited
RAM and could only process data through pointer arrays. A group of students trapped
in the dark library had to:
Calculate the total marks using candlelight.
Find the highest score to determine the scholarship recipient.
Identify the count of failing students (scores <50) needing extra classes
Input :
int storm_grades[] = {68, 42, 95, 33, 57}
Output:
Emergency Results:
Total Marks: 295
Top Student Score: 95
Count of Students Needing Help: 2
12. When the Han River overflowed during monsoon season, librarian Mrs. Park had 30
minutes to save rare books from the rising waters. The library's flood control system
showed:
3 floors with 5 sections each
Sensors (1=dry, 0=flooded)
Using an ancient DOS-based system requiring pointer arrays, she needed to:
a) Find safe sections to move books to
b) Identify worst-hit floor
Input:
sensors[3][5] = {
{1,0,1,1,0},
{0,0,0,1,1},
{1,1,1,0,0}
};
Output :
Crisis Report:
Safe Sections: 8
Most Flooded Floor: 2
Introduction
Storage Classes are used to describe the features of a variable/function. These features
basically include the scope(visibility) and life-time which help us to trace the existence of a
particular variable during the runtime of a program. The following storage classes are
most often used in C programming. Storage classes in C are used to determine the lifetime,
visibility, memory location, and initial value of a variable.
Automatic Variables
A variable declared inside a function without any storage class specification is by
default an automatic variable. They are created when a function is called and are destroyed
automatically when the function execution is completed. Automatic variables can also be
called local variables because they are local to a function. By default, they are assigned to
undefined values.
Coding Example_1:
#include<stdio.h>
int main()
{ int i=90; // by default auto because defined inside a function
auto float j=67.5;
printf("%d %f\n",i,j);
}
Department of CSE, PESU 3
Feb – May,2025
int f1()
{
int a; // by default auto because defined inside a function f1()
// Not accessible outside this function.
}
External variables
The extern keyword is used before a variable to inform the compiler that the
variable is declared somewhere else. The extern declaration does not allocate storage for
variables. All functions are of type extern. The default initial value of external integral
type is 0 otherwise NULL. We can only initialize the extern variable globally, i.e., we
cannot initialize the external variable within any block or method.
Note: An external variable can be declared many times but can be initialized at only
once. The extern modifier is most commonly used when there are two or more files
sharing the same global variables or functions.
int main() {
count = 5;
write_extern();
return 0;
}
Sample1.c
#include <stdio.h>
extern int count;
void write_extern(void)
{
printf("count is %d\n", count);
}
Here, extern is being used to declare count in the second file, where as it has its definition in
the first file, main.c.
// please check the execution steps below
gcc Sample.c Sample1.c –c
gcc Sample.o Sample1.o
Output - count is 5
Static variables
A static variable tells the compiler to persist the variable until the end of program.
Instead of creating and destroying a variable every time when it comes into and goes out of
scope, static is initialized only once and remains into existence till the end of program. A static
variable can either be local or global depending upon the place of declaration.
Scope of local static variable remains inside the function in which it is defined but
the life time of local static variable is throughout that program file. Global static variables
remain restricted to scope of file in each they are declared and life time is also restricted to that
file only. All static variables are assigned 0 (zero) as default value.
int main()
{
int *res = f1();
printf("Res is %p %d\n",res,*res); //same address in all three outputs. Then 11
res = f1();
printf("Res is %p %d\n",res,*res); // 12
res = f1();
printf("Res is %p %d\n",res,*res); // 13
return 0;
}
in t* f1()
{
static int a= 10;// memory is shared. This line is ignored after first function call
a++ ;
return &a; // valid because life time of static variable is throughout the file execution
}
Coding Example_5: Understand the differences between local and global static variable.
#include<stdio.h>
void f1();
static int j=20; // global static variable: cannot be used outside this program file
int k=23; //global variable: can be used anywhere by linking with this file.
//By default has extern with it.
int main( )
{
f1(); // 0 20
f1(); // 0 21
f1(); // 0 22
return 0;
}
void f1()
{ int i=0; printf("%d %d\n",i,j); i++; j++; }
Register variables
Registers are faster than memory to access, so the variables which are most
frequently used in a C program can be put in registers using register keyword. The keyword
register hints to compiler that a given variable can be put in a register. It’s compiler’s choice
to put it in a register or not.
Register is an integral part of the processor. It is a very fast memory of computer
mainly used to execute the programs and other main operation quite efficiently. They are
used to quickly store, accept, transfer, and operate on data based on the instructions that will
be immediately used by the CPU. Main operations are fetch, decode and execute. Numerous
fast multiple ported memory cells are the atomic part of any register. Generally, compilers
themselves do optimizations and put the variables in register. If a free register is not
available, these are then stored in the memory only. If & operator is used with a register
variable then compiler may give an error or warning (depending upon the compiler used ),
because when a variable is a register, it may be stored in a register instead of memory and
accessing address of a register is invalid. The access time of the register variables is faster
than the automatic variables.
Mostly used cpu registers are Accumulator, Flag Register, Address Register (AR),
Data Register (DR), Program Counter (PC), Instruction Register (IR), Stack Control
Register (SCR), Memory Buffer Register (MBR) and Index register (IR).
Coding Example_6:
#include<stdio.h>
int main()
{
register int i = 10;
int* a = &i; // error
printf("%d", *a); getchar();
return 0;
}
Coding Example_7: We can store pointers into the register, i.e., a register can store the
address of a variable.
#include<stdio.h>
int main()
{
int i = 10;
register int* a = &i; // fine
printf("%d", *a); getchar();
return 0;
}
Note: Static variables cannot be stored into the register since we cannot use more than
one storage specifier for the same variable.
Global variables
The variables declared outside any function are called global variables. They are not
limited to any function. Any function can access and modify global variables. Global
variables are automatically initialized to 0 at the time of declaration.
Coding Example_8:
#include<stdio.h>
int i = 100; int j;
int main()
{ printf("%d\n",i); // 100
i=90; printf("%d\n",i); // 90
f1(); printf("%d\n",i); // 40
int f1()
{ i = 40; // Any function can modify the global variable.
}
Introduction
In computer programming, a callback is also known as a "call-after function". The
callback execution may be immediate or it might happen at a later point in time. Programming
languages support call backs in different ways, often implementing them with subroutines,
lambda expressions, blocks, or function pointers. In C, a callback function is a function that
is called through a function pointer/pointer to a function. A callback function has a specific
action which is bound to a specific circumstance. It is an important element of GUI in C
programming.
Coding Example_1:
int what(int x, int y, int z, int (*op)(int, int,int))
{
return op(x, y, z);
}
Observe the third argument op. It is a pointer to a function which takes three int arguments and
returns an int. The return statement in turn calls the function with three arguments. This
function does not know which function is getting called. It depends on the value of op.
Compiler knows the type and not the value. The value of a variable is a runtime
mechanism.
int add(int x, int y, int z)
{ return x + y + z; }
int mul(int x, int y, int z)
{ return x * y * z; }
int main()
{ int (*p)(int, int, int);
Coding Example_2: If you are aware of Python’s Functional programming constructs such as
map, reduce and filter, we will be implementing those here in C using callback functions.
// Mimic map, filter and reduce function of python
#include<stdio.h>
void mymap(int *a,int *b,int n,int (*p)(int));
void disp(int *a, int n);
int myfilter(int *a,int *b,int n,int (*p)(int));
int myreduce(int *a, int n, int (*op)(int, int));
int incr(int x)
{ return x+1; }
int is_even(int x)
{ return x%2 == 0; }
int is_greater_than_22(int x)
{ return x > 22; }
int add(int x,int y)
{ return x+y; }
int main()
{ int a[] = {11,22,33,44,55};
int n = sizeof(a)/sizeof(*a);
int b[100];
printf("a is: \n"); disp(a,n);
mymap(a,b,n,incr);
printf("\nAfter incrementing using map, b is: \n"); disp(b,n);
int c = myfilter(a,b,n,is_even);
printf("\nAfter filtering only even, b is: \n"); disp(b,c);
c = myfilter(a,b,n,is_greater_than_22);
printf("\nAfter filtering only number greater than 22, b is:\n"); disp(b,c);
Introduction
A function may call itself directly or indirectly. The function calling itself with the
termination/stop/base condition is known as recursion. Recursion is used to solve various
problems by dividing it into smaller problems. We can opt if and recursion instead of looping
statements. In recursion, we try to express the solution to a problem in terms of the
problem itself, but of a smaller size.
Key Characteristics:
Base Case – A condition that stops the recursion to prevent infinite recursion.
Recursive Case – The function calls itself with a smaller or simpler input.
Coding Example_1:
int main()
{
printf("Hello everyone\n");
main();
return 0;
}
Execution starts from main() function. ‘Hello everyone’ gets printed. Then call to main()
function. Again, ‘Hello everyone’ gets printed and these repeats. We have not defined any
condition for the program to exit, results in Infinite Recursion. In order to prevent
infinite recursive calls, we need to define proper base condition in a recursive function.
Common Applications:
Factorial Calculation
Fibonacci Sequence
Tree Traversals (Binary Trees)
Graph Traversal (DFS)
Backtracking Problems (Sudoku Solver, N-Queens)
Sorting Algorithms (Merge Sort, Quick Sort)
Let us write Iterative and Recursive functions to find the Factorial of a given number.
Coding Example_2:
int fact(int n);
int main()
{ int n = 6;
printf("factorial of %d is %d\n",fact(n));
return 0;
}
Iterative Implementation:
int fact(int n)
{ int result = 1;
int i;
for (i = 1; i<=n; i++)
{ result = result * i; }
return result;
}
Recursive Implementation:
Logic: If n is 0 or n is 1, result is 1 Else, result is n*(n-1)!
int fact(int n)
{ if (n==0)
return 1;
else
{ return n*fact(n-1); }
}
Pictorial representation:
When n is 6
Activation Record
Each function call generates an instance of that function containing memory for each
parameter, memory for each local variable and memory for return values. This chunk of
memory is called as an activation record.
To support recursive function calls, the run-time system treats memory as a stack of
activation record.
Computing the factorial (n) requires allocation of ‘n’ activation records on the stack.
What does the below code do? Write the activation record for each.
#include<stdio.h>
int what2_v1(int n); Finds the count of 1s in the binary
int what2_v2(int n);
representation of the number.
int main()
{ int n = 10;
printf("%d",what2_v1(n));
printf("%d",what2_v2(n));
return 0;
}
Department of CSE, PESU 6
Feb – May,2025
int what2_v2(int n)
{
if(!n) return 0;
else if (!(n%2)) return what2_v2(n/2);
else{ return 1+what2_v2(n/2); }
}
int what2_v1(int n)
{
if(n==0) return 0;
else return (n&1)+ what2_v1(n>>1);
}
Level-1:Banana
1. A young programmer is learning recursion. His mentor gives him a challenge: Can you
add two integers without using the + operator directly? Instead of normal addition,
he must use recursion by incrementing one number while decrementing the other until
one of them becomes zero.
Input: 4 3 Expected Output: 7
2. Fibonacci numbers appear in nature, such as the arrangement of leaves, flowers, and
shells. Develop an application for biologists to analyze these patterns using a recursive
function Fibonacci(n) to generate the nth Fibonacci number. Display appropriate
message for the negative value of n and 0.
Input: n = 6 Expected Output: 5
Explanation:
0,1,1,2,3,5,8,13,21,34... Fibonacci sequence is a sequence in which each number is the
sum of the two preceding numbers. First two numbers are fixed in the series.
3. A bank's security team discovered that fraudsters were tampering with account
numbers. To prevent this, they introduced a checksum verification system. Each
account number must pass a test where the sum of its digits is calculated to ensure
authenticity. Can you help the bank by writing a recursive function to compute the sum
of digits in an account number?
Input: 1234 Expected Output: Sum of digits: 10
Input: -1234 Expected Output: Sum of digits: 10
4. In a secret agency, messages including positive integers are encrypted using a special
formula: ab. The spies need to quickly compute large powers to send secure codes.
Using recursion, they can break down the calculation into smaller steps, making it
faster and more efficient. Implement a recursive function to help them encrypt their
messages?
Input: a = 2, b = 5
Expected Output: 2^5 = 32
Input: a = 0, b = 0
Expected Output: 0^0 = 1
Input: a = 0, b = 1
Expected Output: 0^1 = 0
Input: a = 1, b = 0
Expected Output: 1^0 = 1
Level-2:Orange
6. NASA scientists are working on decoding signals from an alien spacecraft. The signals
are sent in binary format, and they need to be converted to decimal numbers to
understand the coordinates of the spacecraft. Since binary numbers can be of any
length, recursion is a natural choice for conversion.
Input: 1011
Expected Output: Decimal equivalent: 11
7. One day, Rahul went to an ATM to deposit money. Due to system error, the ATM
processed his transaction in reverse order. Now, the bank's software needs to reverse
the digits of the transaction ID to verify the correct transaction. Since numbers can
have varying lengths, recursion is an efficient way to solve this problem without using
strings.
Input: 1234
Expected Output: Reversed number: 4321
9. A digital wallet app needs a fraud detection system that checks if a positive transaction
ID is too large. To simplify the ID, they sum up all its digits recursively until they
get a single-digit number. This is similar to how some banking checksum algorithms
work. Handle negative inputs with a proper message.
Input: 9875
Expected Output: Single digit id is 2
Explanation:
9 + 8 + 7 + 5 = 29
2 + 9 = 11
1 + 1 = 2 (Final output)
Level-3:Jackfruit
10. A mathematician named Aryan discovered an ancient manuscript containing a
numerical pattern known as Pascal’s Triangle. The legend says that a hidden treasure
can be unlocked if he deciphers the number at a specific position in the triangle.
According to the manuscript, the 0th row starts with 1, and each number in the next
row is formed by adding the two numbers directly above it. Aryan needs to find the
element at a given row N and column M to move forward in his quest. However, the
calculations become tricky for large values, and he decides to use recursion to solve the
problem efficiently.
Can you help Aryan find the treasure by writing a recursive function that determines
the number at the Nth row and Mth column of Pascal’s Triangle? Handle negative
values accordingly with a proper message.
Pascal’s Triangle
Input: 4 2
Expected Output: Pascal's Triangle value at (4, 2) is 6
Explanation: The 4th row of Pascal’s Triangle is [1, 4, 6, 4, 1].
The element at the 2nd column (0-based index) in the 4th row is 6.
11. A monk in a temple follows an ancient tradition where he moves a stack of 3 disks
from one rod to another using a helper rod. The rule is that only one disk can be
moved at a time, and no larger disk can be placed on a smaller one. This is a
perfect example of recursion because solving it for n disks depends on solving it for n-
1 disks. Implement the function hanoi to do the requirement.
Input: 3
Client code: int n = 3;
hanoi( n, 'A', 'C', 'B' );
Function declaration: void hanoi (int n, char from, char to, char aux);
Expected Output:
Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C
12. A mobile app developer is working on a numeric password generator. The challenge is
to generate all possible 3-digit numbers using the digits available on a mobile
keypad (0-9). Since there are 10 digits (0-9), the system should recursively form all
unique 3-digit combinations where each digit can be used multiple times.
Expected output:
000
001
002
...
997
998
999
Introduction
Even a single day does not pass without we searching for something in our day to day
life. Might be car keys, books, pen, mobile charger and what not. Same is the life of a
computer. There is so much data stored in it and whenever user asks for some data, computer
has to search it's memory to look for the data and make it available to the user. And the
computer has it's own techniques to search through it's memory in a faster way.
Why Searching?
We often need to find one particular item of data amongst many hundreds, thousands,
millions or more. For example, if one wants to find someone’s phone number in your phone,
or a particular business’s address from address book.
A searching algorithm can be used to find the data without spending much time. What
if you want to write a program to search a given integer in an array of integers? Two popular
algorithms available: Linear Search and Binary Search
Linear Search
A linear search, also known as a sequential search, is a method of finding an element
within a collection. It checks each element of the list sequentially until a match is found or the
whole list has been searched. It returns the position of the element in the array, else it
return -1. Linear Search can be applied on any unordered or ordered collection of elements.
Binary Search
Binary Search is used to search an element in a SORTED ARRAY. The following
steps are applied to search an element.
1. Start by comparing the element to be searched with the element in the middle of the
array.
2. If we get a match, we return the index of the middle element.
3. If we do not get a match, we check whether the element to be searched is less or
greater than in value than the middle element.
4. If the element/number to be searched is greater in value than the middle number, then
we pick the elements on the right side of the middle element(as the array is sorted,
hence on the right, we will have all the numbers greater than the middle number), and
Note: Between 2,3,5,7 and 7, write diagrams for missing two iterations. Drawing
these two iterations might help you to understand better.
Explanation
The iterative binary search algorithm works on the principle of "Divide and Conquer".
First it divides the large array into smaller sub-arrays and then finding the solution for one sub-
array. It finds the position of a key or target value within an array and compares the target
value to the middle element of the array, if they are unequal, the half in which the target cannot
lie is eliminated. The search continues on the remaining half until it is successful.
Explanation
In recursive approach, the function BinarySerach is recursively called to search the
element in the array. It accepts the input from the user and store it in m. The array elements are
declared and initialized.In the recursive call to function the array, the lower index, higher
index and the number are passed as arguments to be searched again and again until element
is found. If not found, then it returns -1.
Introduction
There are so many things in our real life that we need to search for, like a particular
record in the database, roll numbers in the merit list, a particular telephone number in a
telephone directory, a particular page in a book etc. The concept of sorting came into
existence, making it easier for everyone to arrange data in order to make sure that the
searching process is easy and efficient. Arranging the data in ascending or descending
order is known as sorting.
Why Sorting?
Think about searching for something in a sorted drawer and unsorted drawer. If the
large data set is sorted based on any of the fields, then it becomes easy to search for a
particular data in that set. Sometimes in real world applications, it is necessary to arrange the
data in a sorted order to make the searching process easy and efficient.
Example: Candidates selection process for an Interview- Arranging candidates for the
interview involves sorting process (sorting based on qualification, Experience, skills or age
etc.
Sorting Algorithms
Sorting algorithm specifies the way to arrange data in a particular order. Most
common orders are in numerical or lexicographical order. Depending on the data set, Sorting
algorithms exhibit different time and space complexity.
Following are samples of sorting algorithms.
1. Bubble Sort
2. Insertion Sort
3. Quick Sort
4. Merge Sort
5. Radix Sort
6. Selection Sort -- Dealt in detail
7. Heap Sort
Selection sort
A simple sorting algorithm that works by repeatedly selecting the smallest (or
largest) element from the unsorted portion of the array and swapping it with the first
unsorted element. It follows an in-place and comparison-based approach. The algorithm
maintains two subarrays in a given array.
1) The subarray which is already sorted.
2) Remaining subarray which is unsorted.
The sorted part of the array is empty and unsorted part is the given array. Sorted part is placed
at the left, while the unsorted part is placed at the right. If it is used to arrange data in an
ascending order, the smallest number is selected and placed at the beginning of the collection.
When the next pass takes place the second minimum number is selected and placed in the
second position. The process is repeated until all the elements are placed in the correct order.
With each pass the elements are reduced by 1 as one element is sorted and placed in a position.
Algorithm (Step-by-Step)
1. Start with the first element as the minimum.
2. Traverse through the remaining unsorted elements to find the actual minimum.
3. Swap the minimum found with the first element of the unsorted part.
4. Move the boundary of the sorted region by one position to the right.
5. Repeat until the entire array is sorted.
Pictorial Representation
Coding Exampe_2: Sort the elements of the array given by the user
#include<stdio.h>
void sort(int *a, int n);
void swap(int *x, int *y);
void disp(int *a, int n);
void read(int *a, int n);
int main()
{ int a[100]; int n;
printf("enter the number of elements u want to sort\n");
scanf("%d",&n);
printf("enter %d elements\n",n); read(a,n);
printf("before sorting\n"); disp(a,n);
sort(a,n);
printf("after sorting\n"); disp(a,n);
return 0;
}
Introduction
Counting, sorting, and searching are fundamental operations in computer science.
Counting involves tracking occurrences or frequencies, such as counting the appearances in a
collection of elements. Sorting arranges data in a specific order (ascending or descending)
using algorithms like Bubble Sort, Selection sort, Merge Sort, or Quick Sort, improving
efficiency in later operations. Searching finds specific elements within data using methods
like Linear Search (checking each item sequentially) or Binary Search (dividing sorted data for
faster lookup). These operations are essential for data processing, optimization, and
efficient retrieval in real-world applications like databases, search engines, and analytics.
Counting
In C, counting elements in an array based on specific conditions can be efficiently
handled using callback function. This method allows us to apply different conditions
dynamically without modifying the counting function itself.
Coding Example_1: Counting the number of positive and negative elements, even and odd
elements using a generic function.
#include <stdio.h>
int (*ConditionFunc)(int);
// Function to count elements in an array based on a callback condition
int countElements(int *arr, int size, int (*ConditionFunc)(int)) {
int count = 0;
for (int i = 0; i < size; i++) {
if (ConditionFunc(arr[i])) { // Apply the callback condition
count++; }
}
return count;
}
// Callback function: Check if a number is even
int isEven(int num) { return num % 2 == 0; }
// Callback function: Check if a number is odd
int isOdd(int num) { return num % 2 != 0; }
int main() {
int numbers[] = {1, -3, 4, 6, -8, 9, 11, 15, 2, -7};
int size = sizeof(numbers) / sizeof(numbers[0]);
// Using different callbacks to count based on conditions and display the counts
int evenCount = countElements(numbers, size, isEven);
int oddCount = countElements(numbers, size, isOdd);
int greaterCount = countElements(numbers, size, isGreaterThanFive);
int negativeCount = countElements(numbers, size, isNegative);
printf("Count of even numbers: %d\n", evenCount);
printf("Count of odd numbers: %d\n", oddCount);
printf("Count of numbers greater than 5: %d\n", greaterCount);
printf("Count of negative numbers: %d\n", negativeCount);
return 0;
}
Sorting
Sorting is a fundamental operation in problem-solving and algorithm design. Different
scenarios require different sorting orders—ascending, descending, or even custom
sorting based on specific criteria. Instead of writing separate sorting logic for each case,
callback functions provide a powerful way to make sorting flexible and reusable. For example,
in Selection Sort, we can use a callback function to compare two elements dynamically. If
sorting in ascending order, the callback ensures smaller elements come first; if sorting in
descending order, it ensures larger elements come first. By leveraging callback functions,
we can solve a variety of sorting-related problems efficiently, making the code more adaptable
and scalable. This approach is especially useful in real-world applications where sorting
criteria may change based on user preferences, data structures, or optimization
requirements.
Coding Example_2: Sorting a collection of integers in ascending and descending order using
callback mechanism
#include<stdio.h>
// Callback function for ascending order
int ascending(int a, int b) {
return a > b; // Swap if a is greater than b
}
//Client code
int main()
{ int a[ ] = {22,19,14,25,99,81};
int n = sizeof(a)/sizeof(*a);
printf("Before sorting\n");
printArray(a, n);
// Sorting in ascending order
sort(a, n, ascending);
printf("Ascending Order: ");
printArray(a, n);
// Sorting in descending order
sort(a, n, descending);
printf("Descending Order: ");
printArray(a, n);
return 0;
}
Searching
In C, searching involves finding specific elements in an array based on a given
condition. By using callback functions, we can make the search process more flexible and
reusable. A callback function allows us to define different search criteria dynamically
without modifying the core search function.
Coding Example_3: Implement the Binary Search on a sorted array of integers using a
callback with the below constraints.
A. Search for a number if the number is even .
B. Search for a number if the number is less than 22.
#include<stdio.h>
int my_search(int *a,int low, int high,int key,int(*p)(int));
int is_even(int x);
int is_less_than_22(int x);
int main()
{ int a[] = {11,13,18,19,22,33,44,53,56,101};
int n = sizeof(a)/sizeof(*a);
printf("enter the element to be searched\n");
int key;
scanf("%d",&key);
else
printf("Not less than 22. So not found\n");
return 0;
}
int is_even(int x)
{ return x%2 == 0;}
int is_less_than_22(int x)
{ return x<22;}
int my_search(int a[],int low,int high,int key,int(*p)(int))
{ int pos = -1; int mid;
if (low>high) return pos;
else
{ mid = (low+high)/2;
if(a[mid]==key && p(key)) // very important
{ pos = mid; }
else if(a[mid]>key)
{ return my_search(a,low,mid-1,key,p); }
else
{ return my_search(a,mid+1,high,key,p); }
}
return pos;
}
1. A teacher wants to sort a list of students based on their marks. The sorting should be
flexible, allowing sorting in ascending (lowest to highest marks) or descending
(highest to lowest marks) order based on user preference. Your task is to implement a
sorting function using a callback to dynamically decide the sorting order.
2. Write a generic function that can compute the maximum value, minimum value and
the sum of all numbers using a callback function. Test this generic function by
passing an array of integers.
3. Given an array of integers, filter out only even or odd numbers dynamically based on a
callback function. Define a function filterArray() that applies a callback function to
filter numbers.