2>Draw the flowchart of while and do-while iterative
statements in C
While loop:
The while loop is often called the entry verified loop, whereas the do-while loop is
an exit verified loop. The for loop, on the other hand, is an automatic loop.
Syntax:
while(expression){
statement(s);
}
Flowchart:
#include <stdio.h>
int main(){
// local variable definition
int a = 1;
// while loop execution
while(a <= 5){
printf("Hello World \n");
a++;
}
printf("End of loop");
return 0;
}
Do-while Loop:
The do-while is an exit-verified loop where the test condition is checked after
executing the loop's body. Whereas the while loop is an entry-verified. The for loop,
on the other hand, is an automatic loop.
Syntax:
do {
statement(s);
}
while(condition);
Flowchart:
#include <stdio.h>
int main(){
// local variable definition
int a = 1;
// while loop execution
do{
printf("Hello World\n");
a++;
}
while(a <= 5);
printf("End of loop");
return 0;
}
3=>Write a C function to print the Fibonacci sequence
using recursion. Draw the recursion tree for finding
Fibonacci
[Link]
Ways To Construct Fibonacci Series With &
Without Recursion In C
Constructing a Fibonacci series in the C language involves generating a sequence of
numbers where each number is the sum of the two preceding ones. There are two
primary approaches to constructing a Fibonacci series in C, i.e., using recursion and
using iteration (without recursion).
1. Fibonacci Series In C Using Recursion
Recursion is a programming technique where a function calls itself to solve smaller
instances of the same problem. In the case of the Fibonacci series, a recursive
function can be used to generate each Fibonacci number based on the values of the
preceding ones.
Here's how recursion works for generating a Fibonacci series in C:
1. Base Cases: Define base cases for the first two Fibonacci numbers (0 and 1).
2. Recursive Relation: Implement a function that calls itself with smaller inputs to
compute subsequent Fibonacci numbers.
How To Generate Fibonacci Series Using Recursion In C?
Recursion involves breaking a problem into smaller subproblems of the same type, solving each
recursively, and combining their solutions to get the final result(i.e. recursion tree). Generating a
Fibonacci series using recursion in C is an elegant way to finish the job.
In a recursive solution, a function calls itself with smaller inputs until reaching a base case, usually
when the input becomes 0 or 1. In the case of the Fibonacci series, the base cases are when n is
0 or 1, where the function returns n. Otherwise, the function recursively calls itself to calculate
Fibonacci(n-1) and Fibonacci(n-2) and adds their results to produce Fibonacci(n). This process
continues until the base cases are reached.
Here's a step-by-step explanation of the recursive algorithm:
Step 1- Base Case Initialization: We start by defining the base cases( initial terms) of the Fibonacci
sequence in the recursive function. When the input n is 0 or 1, we return n itself, as these are the
first two numbers in the Fibonacci series.
Step 2- Recursion: In the recursive step, if n is greater than 1, we recursively call the fibonacci()
function with n-1 and n-2. These calls continue until the base cases are reached.
Step 3- Add Results: When the base cases are reached (i.e., n is 0 or 1), we add the results of the
recursive calls for n-1 and n-2 to calculate the Fibonacci number for n.
Step 4- Return Result: Finally, we return the calculated Fibonacci number for the input n.
Step 5- Output: In the main() function, we prompt users to enter the number of current terms they
want in the Fibonacci series. Then, we call the recursive fibonacci() function for each term and
print the series as it's generated.
Fibonacci Series in C
Fibonacci Series in C: In case of fibonacci series, next number is the sum of previous two
numbers for example 0, 1, 1, 2, 3, 5, 8, 13, 21 etc. The first two numbers of fibonacci
series are 0 and 1.
There are two ways to write the fibonacci series program:
o Fibonacci Series without recursion
o Fibonacci Series using recursion
Fibonacci Series in C without recursion
Let's see the fibonacci series program in c without recursion.
1. #include<stdio.h>
2. int main()
3. {
4. int n1=0,n2=1,n3,i,number;
5. printf("Enter the number of elements:");
6. scanf("%d",&number);
7. printf("\n%d %d",n1,n2);//printing 0 and 1
8. for(i=2;i<number;++i)//loop starts from 2 because 0 and 1 are already printed
9. {
10. n3=n1+n2;
11. printf(" %d",n3);
12. n1=n2;
13. n2=n3;
14. }
15. return 0;
16. }
Output:
ADVERTISEMENT
Enter the number of elements:15
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Fibonacci Series using recursion in C
Let's see the fibonacci series program in c using recursion.
1. #include<stdio.h>
2. void printFibonacci(int n){
3. static int n1=0,n2=1,n3;
4. if(n>0){
5. n3 = n1 + n2;
6. n1 = n2;
7. n2 = n3;
8. printf("%d ",n3);
9. printFibonacci(n-1);
10. }
11. }
12. int main(){
13. int n;
14. printf("Enter the number of elements: ");
15. scanf("%d",&n);
16. printf("Fibonacci Series: ");
17. printf("%d %d ",0,1);
18. printFibonacci(n-2);//n-2 because 2 numbers are already printed
19. return 0;
20. }
Output:
Enter the number of elements:15
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
[Link]
4 Find the number of key comparisons involved in the Linear Search Algorithm for
searching key=29,17,16 and 50 in the following array
Linear Search Algorithm
The algorithm for linear search is relatively simple. The procedure starts at the
very first index of the input array to be searched.
Step 1 − Start from the 0th index of the input array, compare the key value with
the value present in the 0th index.
Step 2 − If the value matches with the key, return the position at which the value
was found.
Step 3 − If the value does not match with the key, compare the next element in the
array.
Step 4 − Repeat Step 3 until there is a match found. Return the position at which
the match was found.
Step 5 − If it is an unsuccessful search, print that the element is not present in the
array and exit the program.
Pseudocode
procedure linear_search (list, value)
for each item in the list
if match item == value
return the item's location
end if
end for
end procedure
Analysis
Linear search traverses through every element sequentially therefore, the best
case is when the element is found in the very first iteration. The best-case time
complexity would be O(1).
However, the worst case of the linear search method would be an unsuccessful
search that does not find the key value in the array, it performs n iterations.
Therefore, the worst-case time complexity of the linear search algorithm would
be O(n).
Example
Let us look at the step-by-step searching of the key element (say 47) in an array
using the linear search method.
Step 1
The linear search starts from the 0th index. Compare the key element with the
value in the 0th index, 34.
However, 47 ≠ 34. So it moves to the next element.
Step 2
Now, the key is compared with value in the 1st index of the array.
Still, 47 ≠ 10, making the algorithm move for another iteration.
Step 3
The next element 66 is compared with 47. They are both not a match so the
algorithm compares the further elements.
Step 4
Now the element in 3rd index, 27, is compared with the key value, 47. They are
not equal so the algorithm is pushed forward to check the next element.
Step 5
Comparing the element in the 4th index of the array, 47, to the key 47. It is figured
that both the elements match. Now, the position in which 47 is present, i.e., 4 is
returned.
The output achieved is “Element found at 4th index”.
Implementation
In this tutorial, the Linear Search program can be seen implemented in four
programming languages. The function compares the elements of input with the key
value and returns the position of the key in the array or an unsuccessful search
prompt if the key is not present in the array.
Open Compiler
#include <stdio.h>
void linear_search(int a[], int n, int key){
int i, count = 0;
for(i = 0; i < n; i++) {
if(a[i] == key) { // compares each element of the array
printf("The element is found at %d position\n", i+1);
count = count + 1;
}
}
if(count == 0) // for unsuccessful search
printf("The element is not present in the array\n");
}
int main(){
int i, n, key;
n = 6;
int a[10] = {12, 44, 32, 18, 4, 10};
key = 18;
linear_search(a, n, key);
key = 23;
linear_search(a, n, key);
return 0;
}
Output
The element is found at 4 position
The element is not present in the array
[Link]
[Link]
[Link]
5=>Indicate the step-by-step process for sorting the following
array of elements using selection sort.
Algorithm
1. SELECTION SORT(arr, n)
2.
3. Step 1: Repeat Steps 2 and 3 for i = 0 to n-1
4. Step 2: CALL SMALLEST(arr, i, n, pos)
5. Step 3: SWAP arr[i] with arr[pos]
6. [END OF LOOP]
7. Step 4: EXIT
8.
9. SMALLEST (arr, i, n, pos)
10. Step 1: [INITIALIZE] SET SMALL = arr[i]
11. Step 2: [INITIALIZE] SET pos = i
12. Step 3: Repeat for j = i+1 to n
13. if (SMALL > arr[j])
14. SET SMALL = arr[j]
15. SET pos = j
16. [END OF if]
17. [END OF LOOP]
18. Step 4: RETURN pos
Working of Selection sort Algorithm
Now, let's see the working of the Selection sort Algorithm.
To understand the working of the Selection sort algorithm, let's take an unsorted
array. It will be easier to understand the Selection sort via an example.
Let the elements of array are -
Now, for the first position in the sorted array, the entire array is to be scanned
sequentially.
At present, 12 is stored at the first position, after searching the entire array, it is
found that 8 is the smallest value.
So, swap 12 with 8. After the first iteration, 8 will appear at the first position in the
sorted array.
For the second position, where 29 is stored presently, we again sequentially scan the
rest of the items of unsorted array. After scanning, we find that 12 is the second
lowest element in the array that should be appeared at second position.
Now, swap 29 with 12. After the second iteration, 12 will appear at the second
position in the sorted array. So, after two iterations, the two smallest values are
placed at the beginning in a sorted way.
The same process is applied to the rest of the array elements. Now, we are showing
a pictorial representation of the entire sorting process.
Now, the array is completely sorted.
[Link]
PART =B
1=>Write a C program to find the roots of a quadratic equation.
# include<stdio.h>
# include<math.h>
int main () {
float a,b,c,r1,r2,d;
printf ("Enter the values of a b c: ");
scanf (" %f %f %f", &a, &b, &c);
d= b*b - 4*a*c;
if (d>0) {
r1 = -b+sqrt (d) / (2*a);
r2 = -b-sqrt (d) / (2*a);
printf ("The real roots = %f %f", r1, r2);
}
else if (d==0) {
r1 = -b/(2*a);
r2 = -b/(2*a);
printf ("Roots are equal =%f %f", r1, r2);
}
else
printf("Roots are imaginary");
return 0;
}
Testing
Case 1:
Enter the values of a b c: 1 4 3
The real roots = -3.000000 -5.000000
Case 2:
Enter the values of a b c: 1 2 1
Roots are equal =-1.000000 -1.000000
Case 3:
Enter the values of a b c: 1 1 4
Roots are imaginary
[Link]
[Link]
[Link]
2=> Define an Array. Write a C code for Matrix multiplication using
arrays
C Array
An array is defined as the collection of similar type of data items stored at
contiguous memory locations. Arrays are the derived data type in C programming
language which can store the primitive type of data such as int, char, double, float,
etc. It also has the capability to store the collection of derived data types, such as
pointers, structure, etc. The array is the simplest data structure where each data
element can be randomly accessed by using its index number.
C array is beneficial if you have to store similar elements. For example, if we want to
store the marks of a student in 6 subjects, then we don't need to define different
variables for the marks in the different subject. Instead of that, we can define an
array which can store the marks in each subject at the contiguous memory locations.
By using the array, we can access the elements easily. Only a few lines of code are
required to access the elements of the array.
[Link]
Matrix multiplication in C
Matrix multiplication in C: We can add, subtract, multiply and divide 2 matrices. To
do so, we are taking input from the user for row number, column number, first
matrix elements and second matrix elements. Then we are performing multiplication
on the matrices entered by the user.
In matrix multiplication first matrix one row element is multiplied by second matrix all
column elements.
Let's try to understand the matrix multiplication of 2*2 and 3*3 matrices by the
figure given below:
#include<stdio.h>
#include<stdlib.h>
int main(){
int a[10][10],b[10][10],mul[10][10],r,c,i,j,k;
system("cls");
printf("enter the number of row=");
scanf("%d",&r);
printf("enter the number of column=");
scanf("%d",&c);
printf("enter the first matrix element=\n");
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
scanf("%d",&a[i][j]);
}
}
printf("enter the second matrix element=\n");
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
scanf("%d",&b[i][j]);
}
}
printf("multiply of the matrix=\n");
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
mul[i][j]=0;
for(k=0;k<c;k++)
{
mul[i][j]+=a[i][k]*b[k][j];
}
}
}
//for printing result
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
printf("%d\t",mul[i][j]);
}
printf("\n");
}
return 0;
}
Output:
enter the number of row=3
enter the number of column=3
enter the first matrix element=
1 1 1
2 2 2
3 3 3
enter the second matrix element=
1 1 1
2 2 2
3 3 3
multiply of the matrix=
6 6 6
12 12 12
18 18 18
[Link]
3=> What is dynamic memory allocation? Why it is required?
Consider the following C declaration:
struct node {
int i;
float j;
};
struct node *s[10];
What does the above C declaration
defines?
What is Dynamic Memory Allocation?
Resources are always a premium. We have strived to achieve better utilization of
resources at all times; that is the premise of our progress. Related to this pursuit, is
the concept of memory allocation.
Memory has to be allocated to the variables that we create, so that actual variables
can be brought to existence. Now there is a constraint as how we think it happens,
and how it actually happens.
How computer creates a variable?
When we think of creating something, we think of creating something from the
very scratch, while this isn’t what actually happens when a computer creates a
variable ‘X’; to the computer, is more like an allocation, the computer just assigns
a memory cell from a lot of pre-existing memory cells to X. It’s like someone
named ‘RAJESH’ being allocated to a hotel room from a lot of free or empty pre-
existing rooms. This example probably made it very clear as how the computer
does the allocation of memory.
Now, what is Static Memory Allocation? When we declare variables, we actually
are preparing all the variables that will be used, so that the compiler knows that the
variable being used is actually an important part of the program that the user wants
and not just a rogue symbol floating around. So, when we declare variables, what
the compiler actually does is allocate those variables to their rooms (refer to the
hotel analogy earlier). Now, if you see, this is being done before the program
executes, you can’t allocate variables by this method while the program is
executing.
// All the variables in below program
// are statically allocated.
void fun()
{
int a;
}
int main()
{
int b;
int c[10]
}
Why do we need to introduce another allocation method if this just gets the
job done? Why would we need to allocate memory while the program is
executing? Because, even though it isn’t blatantly visible, not being able to allocate
memory during run time precludes flexibility and compromises with space
efficiency. Specially, those cases where the input isn’t known beforehand, we
suffer in terms of inefficient storage use and lack or excess of slots to enter data
(given an array or similar data structures to store entries). So, here we define
Dynamic Memory Allocation: The mechanism by which storage/memory/cells
can be allocated to variables during the run time is called Dynamic Memory
Allocation (not to be confused with DMA). So, as we have been going through it
all, we can tell that it allocates the memory during the run time which enables us to
use as much storage as we want, without worrying about any wastage.
Dynamic memory allocation is the process of assigning the memory space during
the execution time or the run time.
[Link]
For second part visit and understand
[Link]
4=> Differentiate call by value and call by reference with a suitable example
Difference Between Call by Value and Call by Reference in C
Functions can be invoked in two ways: Call by Value or Call by Reference.
These two ways are generally differentiated by the type of values passed to them as
parameters.
The parameters passed to the function are called actual parameters whereas the
parameters received by the function are called formal parameters.
Call By Value in C
In call by value method of parameter passing, the values of actual parameters are
copied to the function’s formal parameters.
There are two copies of parameters stored in different memory locations.
One is the original copy and the other is the function copy.
Any changes made inside functions are not reflected in the actual parameters of
the caller.
Example of Call by Value
The following example demonstrates the call-by-value method of parameter
passing
// C program to illustrate call by value
#include <stdio.h>
// Function Prototype
void swapx(int x, int y);
// Main function
int main()
{
int a = 10, b = 20;
// Pass by Values
swapx(a, b); // Actual Parameters
printf("In the Caller:\na = %d b = %d\n", a, b);
return 0;
}
// Swap functions that swaps
// two values
void swapx(int x, int y) // Formal Parameters
{
int t;
t = x;
x = y;
y = t;
printf("Inside Function:\nx = %d y = %d\n", x, y);
}
Output
Inside Function:
x = 20 y = 10
In the Caller:
a = 10 b = 20
Thus actual values of a and b remain unchanged even after exchanging the values
of x and y in the function.
Call by Reference in C
In call by reference method of parameter passing, the address of the actual
parameters is passed to the function as the formal parameters. In C, we use pointers
to achieve call-by-reference.
Both the actual and formal parameters refer to the same locations.
Any changes made inside the function are actually reflected in the actual
parameters of the caller.
Example of Call by Reference
The following C program is an example of a call-by-reference method.
// C program to illustrate Call by Reference
#include <stdio.h>
// Function Prototype
void swapx(int*, int*);
// Main function
int main()
{
int a = 10, b = 20;
// Pass reference
swapx(&a, &b); // Actual Parameters
printf("Inside the Caller:\na = %d b = %d\n", a, b);
return 0;
}
// Function to swap two variables
// by references
void swapx(int* x, int* y) // Formal Parameters
{
int t;
t = *x;
*x = *y;
*y = t;
printf("Inside the Function:\nx = %d y = %d\n", *x, *y);
}
Output
Inside the Function:
x = 20 y = 10
Inside the Caller:
a = 20 b = 10
Thus actual values of a and b get changed after exchanging values of x and y.
Difference between the Call by Value and Call by
Reference in C
The following table lists the differences between the call-by-value and call-by-
reference methods of parameter passing.
Call By Value Call By Reference
While calling a function, instead of passing the
While calling a function, we pass the
values of variables, we pass the address of
values of variables to it. Such functions
variables(location of variables) to the function
are known as “Call By Values”.
known as “Call By References.
In this method, the value of each variable
In this method, the address of actual variables
in the calling function is copied into
in the calling function is copied into the
corresponding dummy variables of the
dummy variables of the called function.
called function.
With this method, the changes made to
With this method, using addresses we would
the dummy variables in the called
have access to the actual variables and hence
function have no effect on the values of
we would be able to manipulate them.
actual variables in the calling function.
Call By Value Call By Reference
In call-by-values, we cannot alter the
In call by reference, we can alter the values of
values of actual variables through
variables through function calls.
function calls.
Values of variables are passed by the Pointer variables are necessary to define to
Simple technique. store the address values of variables.
This method is preferred when we have
This method is preferred when we have to
to pass some small values that should
pass a large amount of data to the function.
not change.
Call by value is considered safer as Call by reference is risky as it allows direct
original data is preserved modification in original data
Note In C, we use pointers to achieve call-by-reference. In C++, we can either use
pointers or references for pass-by-reference. In Java, primitive types are passed
as values and non-primitive types are always references.
[Link]
[Link]
[Link]
5=> Write a C program to concatenate two files.
#include <stdio.h>
#include <stdlib.h>
int main()
{
// Open two files to be merged
FILE *fp1 = fopen("[Link]", "r");
FILE *fp2 = fopen("[Link]", "r");
// Open file to store the result
FILE *fp3 = fopen("[Link]", "w");
char c;
if (fp1 == NULL || fp2 == NULL || fp3 == NULL)
{
puts("Could not open files");
exit(0);
}
// Copy contents of first file to [Link]
while ((c = fgetc(fp1)) != EOF)
fputc(c, fp3);
// Copy contents of second file to [Link]
while ((c = fgetc(fp2)) != EOF)
fputc(c, fp3);
printf("Merged [Link] and [Link] into [Link]");
fclose(fp1);
fclose(fp2);
fclose(fp3);
return 0;
}
Output:
Merged [Link] and [Link] into [Link]
[Link]
[Link]
file/
[Link]
[Link]
6=> What is Time complexity? Find the time Complexity of the
Merge Sort Algorithm
Time and Space Complexity Analysis of
Merge Sort
Last Updated : 14 Mar, 2024
The Time Complexity of Merge Sort is O(n log n) in both the average and worst
cases. The space complexity of Merge sort is O(n).
Aspect Complexity
Time Complexity O(n log n)
Aspect Complexity
Space Complexity O(n)
Time Complexity Analysis of Merge Sort:
Consider the following terminologies:
T(k) = time taken to sort k elements
M(k) = time taken to merge k elements
So, it can be written
T(N) = 2 * T(N/2) + M(N)
= 2 * T(N/2) + constant * N
These N/2 elements are further divided into two halves. So,
T(N) = 2 * [2 * T(N/4) + constant * N/2] + constant * N
= 4 * T(N/4) + 2 * N * constant
...
= 2k * T(N/2k) + k * N * constant
It can be divided maximum until there is one element left. So, then N/2k = 1. k =
log2N
T(N) = N * T(1) + N * log2N * constant
= N + N * log2N
Therefore the time complexity is O(N * log2N).
So in the best case, the worst case and the average case the time complexity is the
same.
Space Complexity Analysis of Merge Sort:
Merge sort has a space complexity of O(n). This is because it uses an auxiliary
array of size n to merge the sorted halves of the input array. The auxiliary array is
used to store the merged result, and the input array is overwritten with the sorted
result.
Three 90 Challenge is back on popular demand! After processing refunds worth INR
1CR+, we are back with the offer if you missed it the first time. Get 90% course fee
refund in 90 days. Avail now!
Are you looking to bridge the gap from Data Structures and Algorithms (DSA)
to Software Development? Dive into our DSA to Development - Beginner to
Advance Course on GeeksforGeeks, crafted for aspiring developers and seasoned
programmers alike. Explore essential coding skills, software engineering
principles, and practical application techniques through hands-on projects and
real-world examples. Whether you're starting your journey or aiming to refine your
skills, this course empowers you to build robust software solutions. Ready to
advance your programming prowess? Enroll now and transform your coding
capabilities!
[Link]
[Link]
[Link]