0% found this document useful (0 votes)
2 views48 pages

Answers Pyq

The document provides an overview of various C programming concepts, including the use of the #define preprocessor directive for defining macros, the control flow statements break and continue, the declaration and initialization of two-dimensional arrays, and the differences between local and global variables. It also explains the distinction between pre-increment and post-increment operators, along with a summary of different types of operators in C. Each section includes code examples to illustrate the concepts discussed.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views48 pages

Answers Pyq

The document provides an overview of various C programming concepts, including the use of the #define preprocessor directive for defining macros, the control flow statements break and continue, the declaration and initialization of two-dimensional arrays, and the differences between local and global variables. It also explains the distinction between pre-increment and post-increment operators, along with a summary of different types of operators in C. Each section includes code examples to illustrate the concepts discussed.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 48

Ques1

The #define preprocessor directive in the C language is used to define macros, which are
essentially symbolic constants or macros for code replacement. It is a part of the preprocessor
commands in C that are executed before the actual compilation of the program begins.

Common Uses of #define:

1. Defining Constants: You can use #define to define constant values that will be
substituted throughout the program wherever the macro name appears.
2. #define PI 3.14159
3. printf("The value of PI is %f\n", PI);
4. Defining Function-like Macros: It can also be used to define macros that resemble
functions but are replaced directly by code during preprocessing.
5. #define SQUARE(x) ((x) * (x))
6. printf("The square of 5 is %d\n", SQUARE(5));
7. Code Simplification: It allows defining common code snippets, making the program
easier to read and maintain.
8. #define PRINT_HELLO() printf("Hello, World!\n")
9. PRINT_HELLO();
10. Conditional Compilation: Combined with other preprocessor directives (e.g.,
#ifdef, #ifndef, #else, #endif), it enables conditional compilation of code blocks.
11. #define DEBUG
12. #ifdef DEBUG
13. printf("Debug mode is enabled.\n");
14. #endif
15. Portability: #define can help make a program portable by abstracting system-
dependent details.
16. #ifdef _WIN32
17. #define CLEAR_SCREEN "cls"
18. #else
19. #define CLEAR_SCREEN "clear"
20. #endif
21. system(CLEAR_SCREEN);

Key Characteristics:

 Text Replacement: The preprocessor replaces the macro name with its definition
before the actual compilation.
 No Data Type: Macros do not have a data type, unlike constants defined using const.
 Global Scope: Once defined, the macro is valid across the entire file unless undefined
using #undef.

Limitations:

1. No Type Checking: Function-like macros do not perform type checking, which can
lead to unexpected results or bugs.
2. Debugging Difficulty: Since macros are replaced at compile-time, debugging issues
related to macros can be challenging.
3. Code Expansion: Excessive use of macros can increase the size of the compiled
code.

For more advanced use cases, it is often recommended to use const, inline functions, or
enum instead of macros to take advantage of type safety and better debugging.

Ques2

In C, break and continue are control flow statements used to manage loops and switch
cases. Their behavior can also be extended with labels in languages like Java, but C itself
doesn't support labeled break or labeled continue. However, I will include the general
explanation, mentioning labeled forms where relevant to other languages like Java. Here's a
breakdown:

1. break Statement

 Purpose: Terminates the nearest enclosing switch or loop (for, while, or do-while)
prematurely and transfers control to the next statement after the loop or switch.

Syntax:
break;

Example:
for (int i = 0; i < 10; i++) {
if (i == 5) {
break; // Exit the loop when i equals 5
}
printf("%d ", i);
}
// Output: 0 1 2 3 4

2. Labeled break

 Supported in: Not available in C, but languages like Java allow a break statement to
terminate specific outer loops using a label.
 Purpose: Exit a specific loop when nested loops are involved.

Syntax (Java):
label_name: for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (j == 2) {
break label_name; // Exit the labeled loop
}
}
}

3. continue Statement
 Purpose: Skips the remaining statements in the current iteration of the nearest enclosing
loop and proceeds with the next iteration.

Syntax:
continue;

Example:
for (int i = 0; i < 5; i++) {
if (i == 2) {
continue; // Skip the iteration when i equals 2
}
printf("%d ", i);
}
// Output: 0 1 3 4

4. Labeled continue

 Supported in: Not available in C, but in languages like Java, a continue statement can be
used to skip to the next iteration of a specific outer loop using a label.
 Purpose: Skips the current iteration of a labeled loop.

Syntax (Java):
outer: for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (j == 2) {
continue outer; // Skip to the next iteration of the outer loop
}
}
}

Key Differences Between break and continue:

Feature break continue

Skips the current iteration of the


Effect Terminates the loop entirely.
loop.

Loops (for, while, do-while) and switch


Applicable to Loops only.
cases.

Execution Flow Control moves out of the loop. Control jumps to the next iteration.

Use Cases:

1. break:
o Exiting a loop early based on a condition.
o Exiting a switch case block.
2. Labeled break (in Java):
o Exiting nested loops directly without additional conditions.

3. continue:
o Skipping unnecessary iterations.
o Avoiding specific logic under certain conditions.

4. Labeled continue (in Java):


o Skipping specific iterations of an outer loop in nested loops.

While C does not support labeled break and continue, understanding them can be useful
when transitioning to languages that do, such as Java or Python (which uses loop control with
labels in different forms).

Ques 3

In C, a two-dimensional array is essentially an array of arrays. Here's how you can declare
and initialize a two-dimensional array:

Basic Declaration
#include <stdio.h>

int main() {
// Declaring a 2D array with 3 rows and 4 columns
int array[3][4];

// Example: Assigning values


array[0][0] = 1;
array[0][1] = 2;
array[0][2] = 3;
array[0][3] = 4;

array[1][0] = 5;
array[1][1] = 6;
array[1][2] = 7;
array[1][3] = 8;

array[2][0] = 9;
array[2][1] = 10;
array[2][2] = 11;
array[2][3] = 12;

return 0;
}

Initialization at Declaration
#include <stdio.h>

int main() {
// Declaring and initializing a 2D array with 3 rows and 4 columns
int array[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

// Printing the array


for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", array[i][j]);
}
printf("\n");
}

return 0;
}

Partial Initialization

If fewer elements are provided, the remaining elements are initialized to 0.

int array[3][4] = {
{1, 2}, // Only two elements in this row, rest will be 0
{3, 4, 5}, // Three elements, the last will be 0
{6} // Only one element, others will be 0
};

Dynamic Memory Allocation for 2D Arrays

In cases where the dimensions are not fixed at compile time, you can allocate memory
dynamically (though this is not strictly a 2D array, it simulates one):

#include <stdio.h>
#include <stdlib.h>

int main() {
int rows = 3, cols = 4;

// Allocating memory for a 2D array dynamically


int **array = (int **)malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {
array[i] = (int *)malloc(cols * sizeof(int));
}

// Assigning values
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
array[i][j] = i * cols + j + 1;
}
}

// Printing the array


for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d ", array[i][j]);
}
printf("\n");
}

// Freeing memory
for (int i = 0; i < rows; i++) {
free(array[i]);
}
free(array);

return 0;
}

Key Notes:

 Syntax: data_type array[rows][columns];


 Accessing Elements: Use array[row_index][column_index] to access an element.
 Dynamic Allocation: Useful when the size of the array is determined at runtime.

Ques4

In C, local variables and global variables are two types of variables that differ in scope,
lifetime, and accessibility. Here's a detailed differentiation:

Aspect Local Variables Global Variables

Declared outside all functions (at the top


Definition Declared inside a function or a block ({})
level)

Limited to the function or block where it is Accessible throughout the entire


Scope
declared program

Exists only during the execution of the


Lifetime Exists for the lifetime of the program
function/block

Storage Usually stored in the stack Stored in the data segment of memory

Uninitialized variables contain garbage Automatically initialized to 0 (or


Default Value
values equivalent default)

Accessibility Not accessible outside the function/block Accessible by all functions in the program

Used for temporary storage and Used for sharing data across multiple
Usage
computations functions

Automatically initialized if not explicitly


Initialization Must be explicitly initialized
done

Name Can have the same name as other variables Must have unique names throughout the
Conflicts in different scopes program
Aspect Local Variables Global Variables

Less secure as they can be accessed and


Security More secure as they are limited in scope
modified globally

int x = 10; void func()


Example void func() { int x = 10; }
{ ... }

Examples:

Local Variable:
#include <stdio.h>

void localExample() {
int x = 10; // Local variable
printf("Local variable x = %d\n", x);
}

int main() {
localExample();
// printf("%d", x); // Error: x is not accessible here
return 0;
}

Output:

Local variable x = 10

Global Variable:
#include <stdio.h>

// Global variable
int x = 20;

void globalExample() {
printf("Global variable x = %d\n", x);
}

int main() {
printf("Global variable in main x = %d\n", x);
globalExample();
return 0;
}

Output:

Global variable in main x = 20


Global variable x = 20

Key Points:

1. Local Variables:
oUseful for temporary data within a specific function or block.
oAvoid unintended modifications by other parts of the program.
2. Global Variables:
o Useful when multiple functions need access to shared data.
o Overuse can make debugging difficult due to unintended modifications.

In general, prefer local variables unless global variables are absolutely necessary.

Ques 5

The difference between ++a (pre-increment) and a++ (post-increment) lies in when the
increment operation takes place in relation to the evaluation of the variable's value. Here's a
detailed explanation:

Feature ++a (Pre-Increment) a++ (Post-Increment)

Order of The value of a is incremented first, then the The value of a is used first, then it
Operation updated value is used in the expression. is incremented.

Value Returns the original (old) value of


Returns the incremented (new) value of a.
Returned a.

When you need the original value


When to Use When you need the updated value immediately.
before the increment.

Examples in Code

Pre-Increment (++a)
#include <stdio.h>

int main() {
int a = 5;
int b = ++a; // Increment `a` first, then assign to `b`
printf("a = %d, b = %d\n", a, b); // Output: a = 6, b = 6
return 0;
}

 Explanation: a is incremented to 6 before being assigned to b. So both a and b become 6.

Post-Increment (a++)
#include <stdio.h>

int main() {
int a = 5;
int b = a++; // Assign `a` to `b` first, then increment `a`
printf("a = %d, b = %d\n", a, b); // Output: a = 6, b = 5
return 0;
}

 Explanation: The original value of a (5) is assigned to b, and then a is incremented to 6.

Example in Expressions
#include <stdio.h>

int main() {
int a = 5;
printf("Pre-increment: %d\n", ++a); // Increments and prints the new
value (6)
printf("Post-increment: %d\n", a++); // Prints the current value (6),
then increments
printf("Final value of a: %d\n", a); // Prints the incremented value
(7)
return 0;
}

Output:

Pre-increment: 6
Post-increment: 6
Final value of a: 7

Key Points:

1. Pre-increment (++a):
o Use when you need the updated value immediately.
o Generally slightly faster in certain contexts because there's no need to hold the old
value temporarily.

2. Post-increment (a++):
o Use when the old value is needed before incrementing.

Both operators modify the variable, but the timing of the update determines their use cases.

Ques 2 a

C provides a wide range of operators categorized based on their functionality. Here’s an


overview of the types of operators in C along with examples:

1. Arithmetic Operators

Used for basic mathematical operations.


Operator Description Example Output

+ Addition a + b Sum of a and b

- Subtraction a - b Difference of a and b

* Multiplication a * b Product of a and b

/ Division a / b Quotient of a divided by b

% Modulus a % b Remainder of a divided by b

Example:
#include <stdio.h>
int main() {
int a = 10, b = 3;
printf("Addition: %d\n", a + b);
printf("Subtraction: %d\n", a - b);
printf("Multiplication: %d\n", a * b);
printf("Division: %d\n", a / b);
printf("Modulus: %d\n", a % b);
return 0;
}

2. Relational (Comparison) Operators

Used to compare two values and return a Boolean result (1 for true, 0 for false).

Operator Description Example Output

== Equal to a == b 1 if a equals b, else 0

!= Not equal to a != b 1 if a is not equal to b

> Greater than a > b 1 if a is greater than b

< Less than a < b 1 if a is less than b

>= Greater than or equal to a >= b 1 if a is greater than or equal to b

<= Less than or equal to a <= b 1 if a is less than or equal to b

Example:
#include <stdio.h>
int main() {
int a = 5, b = 3;
printf("a > b: %d\n", a > b);
printf("a < b: %d\n", a < b);
printf("a == b: %d\n", a == b);
return 0;
}
3. Logical Operators

Used for logical operations (combine or invert Boolean expressions).

Operator Description Example Output

&& Logical AND a && b 1 if both a and b are true

` ` Logical OR

! Logical NOT !a 1 if a is false, 0 if a is true

Example:
#include <stdio.h>
int main() {
int a = 1, b = 0;
printf("a AND b: %d\n", a && b);
printf("a OR b: %d\n", a || b);
printf("NOT a: %d\n", !a);
return 0;
}

4. Bitwise Operators

Operate at the bit level.

Operator Description Example Output

& Bitwise AND a & b Bitwise AND of a and b

` ` Bitwise OR `a

^ Bitwise XOR a ^ b Bitwise XOR of a and b

~ Bitwise NOT ~a One's complement of a

<< Left Shift a << 1 Shifts bits of a left by 1

>> Right Shift a >> 1 Shifts bits of a right by 1

5. Assignment Operators

Used to assign values to variables.


Operator Description Example Equivalent To

= Assign value a = b a = b

+= Add and assign a += b a = a + b

-= Subtract and assign a -= b a = a - b

*= Multiply and assign a *= b a = a * b

/= Divide and assign a /= b a = a / b

%= Modulus and assign a %= b a = a % b

6. Increment and Decrement Operators

Used to increase or decrease the value of a variable by 1.

Operator Description Example Effect

++ Increment ++a or a++ Adds 1 to a

-- Decrement --a or a-- Subtracts 1 from a

7. Special Operators

1. Comma Operator: Used to separate expressions, returns the value of the last
expression.
2. int a = (1, 2, 3); // a gets the value 3

3. Sizeof Operator: Returns the size (in bytes) of a data type.


4. printf("Size of int: %zu\n", sizeof(int)); // Output: Size of int: 4
(on most systems)

5. Pointer Operators: * (dereference) and & (address of).


6. int a = 5;
7. int *p = &a; // p stores the address of a
8. printf("Value of a: %d\n", *p); // Dereferences p to get the value of
a

Summary Table

Operator Type Example

Arithmetic a + b, a * b
Operator Type Example

Relational a < b, a == b

Logical a && b, !a

Bitwise a & b, a << 1

Assignment a = b, a += b

Increment/Decrement ++a, a--

Special sizeof(a), *p, a,b

Each operator serves a specific purpose and is essential for performing operations in C
programs.

Oues

In C programming, looping statements are used to execute a block of code repeatedly until a
certain condition is met. The main types of loops in C are:

1. for Loop

The for loop is used when the number of iterations is known in advance. It consists of three
parts:

 Initialization: Sets the starting value.


 Condition: Specifies the termination condition.
 Increment/Decrement: Updates the loop counter.

Syntax:

for (initialization; condition; increment/decrement) {


// code to be executed
}

Example:

#include <stdio.h>
int main() {
for (int i = 1; i <= 5; i++) {
printf("Iteration %d\n", i);
}
return 0;
}

Output:
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5

2. while Loop

The while loop is used when the number of iterations is not known in advance and depends
on a condition being true. The condition is checked before the loop body is executed.

Syntax:

while (condition) {
// code to be executed
}

Example:

#include <stdio.h>
int main() {
int i = 1;
while (i <= 5) {
printf("Iteration %d\n", i);
i++;
}
return 0;
}

Output:

Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5

3. do-while Loop

The do-while loop is similar to the while loop, but the condition is checked after executing
the loop body. This ensures the loop executes at least once.

Syntax:

do {
// code to be executed
} while (condition);

Example:

#include <stdio.h>
int main() {
int i = 1;
do {
printf("Iteration %d\n", i);
i++;
} while (i <= 5);
return 0;
}

Output:

Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5

4. nested Loops

Loops can be nested inside one another, such as a for loop inside another for loop.

Example:

#include <stdio.h>
int main() {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
printf("i = %d, j = %d\n", i, j);
}
}
return 0;
}

Output:

i = 1, j = 1
i = 1, j = 2
i = 2, j = 1
i = 2, j = 2
i = 3, j = 1
i = 3, j = 2

5. Infinite Loops

Loops can be made infinite if the termination condition is never met.

Example:

#include <stdio.h>
int main() {
for (;;) {
printf("This is an infinite loop.\n");
break; // Add a break to stop the loop
}
return 0;
}
Control Statements in Loops

 break: Exits the loop prematurely.


 continue: Skips the rest of the current iteration and proceeds to the next.

Example with break and continue:

#include <stdio.h>
int main() {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue; // Skip when i is 3
}
if (i == 5) {
break; // Exit the loop when i is 5
}
printf("i = %d\n", i);
}
return 0;
}

Output:

i = 1
i = 2
i = 4

By understanding these loops and control statements, you can handle repetitive tasks
effectively in C programming.

Ques 4

The scanf() and gets() functions are used for taking input in C, but they differ
significantly in their behavior and usage.

1. scanf() Function

 Purpose: Used to read formatted input (e.g., integers, floats, strings, etc.).
 Behavior: It stops reading input when it encounters a whitespace (space, tab, or
newline).
 Drawback: Cannot read multi-word strings directly because it stops at the first
whitespace.
 Syntax:
 scanf("format_specifier", &variable);

Example with scanf():

#include <stdio.h>
int main() {
char name[50];
printf("Enter your name: ");
scanf("%s", name); // Reads input until the first whitespace
printf("Hello, %s!\n", name);
return 0;
}

Input:

John Doe

Output:

Hello, John

 Explanation: Only "John" is captured because scanf() stops reading at the first
space.

2. gets() Function

 Purpose: Used to read an entire line of input, including spaces, until a newline is
encountered.
 Behavior: Captures the entire string (multi-word input) and stores it in the provided
character array.
 Drawback: It does not perform bounds checking, which can lead to buffer overflow
(deprecated in modern C standards in favor of fgets()).
 Syntax:
 gets(variable);

Example with gets():

#include <stdio.h>
int main() {
char name[50];
printf("Enter your name: ");
gets(name); // Reads the entire line of input
printf("Hello, %s!\n", name);
return 0;
}

Input:

John Doe

Output:

Hello, John Doe

 Explanation: The entire input "John Doe" is captured, including the space.
Key Differences

Feature scanf() gets()


Reads formatted input (e.g., integers,
Input Type Reads an entire line of text.
floats, strings).
Spaces Reads spaces and stops at a
Stops reading at the first whitespace.
Handling newline.
Bounds Prevents overflow with proper usage of No bounds checking; prone to
Checking width specifiers. buffer overflow.
Suitable for single-word input or
Use Case Suitable for multi-word strings.
formatted input.
Deprecated; fgets() is
Deprecation Not deprecated.
recommended instead.

Safe Alternative to gets()

Instead of gets(), use fgets() for safer input handling.

Example with fgets():

#include <stdio.h>
int main() {
char name[50];
printf("Enter your name: ");
fgets(name, sizeof(name), stdin); // Reads up to 49 characters and
includes spaces
printf("Hello, %s", name);
return 0;
}

This ensures the input does not exceed the buffer size and avoids buffer overflow.

Ques

In C, storage classes define the scope, lifetime, visibility, and memory location of variables.
There are four primary storage classes in C:

1. Automatic (auto)

 Default class for local variables.


 Scope: Limited to the block in which they are defined.
 Lifetime: Created when the block is entered, destroyed when the block exits.
 Storage: Stored in stack memory.
 Keyword: auto (optional; rarely used explicitly).
Example:

#include <stdio.h>
int main() {
auto int a = 10; // `auto` is optional
printf("The value of a: %d\n", a);
return 0;
}

Output:

The value of a: 10

2. External (extern)

 Used to declare a global variable or function that is defined elsewhere.


 Scope: Accessible throughout the program across multiple files.
 Lifetime: Exists for the duration of the program.
 Storage: Stored in global memory.
 Keyword: extern.

Example: File1: file1.c

#include <stdio.h>
int x = 10; // Global variable definition
void display() {
printf("Value of x: %d\n", x);
}

File2: file2.c

#include <stdio.h>
extern int x; // Declaration of global variable
void display();
int main() {
printf("Accessing x in main: %d\n", x);
display();
return 0;
}

Compilation and Execution:

gcc file1.c file2.c -o program


./program

Output:

Accessing x in main: 10
Value of x: 10
3. Static (static)

 Maintains the value of a variable across multiple function calls or limits the scope of a global
variable to the file.
 Scope:
o For local variables: Limited to the block.
o For global variables: Limited to the file.
 Lifetime: Retains value for the program's duration.
 Storage: Stored in global memory.

Static Local Variable Example:


#include <stdio.h>
void counter() {
static int count = 0; // Static variable retains its value
count++;
printf("Count: %d\n", count);
}
int main() {
counter();
counter();
counter();
return 0;
}

Output:

Count: 1
Count: 2
Count: 3

Static Global Variable Example:

File1: file1.c

#include <stdio.h>
static int x = 10; // Global static variable
void display() {
printf("Value of x: %d\n", x);
}

File2: file2.c

#include <stdio.h>
void display();
int main() {
// printf("Value of x: %d\n", x); // Error: x is not visible here
display();
return 0;
}

Output:

Value of x: 10
4. Register (register)

 Used to store variables in the CPU register for faster access.


 Scope: Limited to the block in which they are defined.
 Lifetime: Same as auto variables.
 Storage: Stored in CPU registers (if available; otherwise, in RAM).
 Keyword: register.

Note: You cannot take the address of a register variable using the & operator.

Example:

#include <stdio.h>
int main() {
register int i;
for (i = 0; i < 5; i++) {
printf("%d\n", i);
}
return 0;
}

Output:

0
1
2
3
4

Comparison Table
Storage Class Scope Lifetime Keyword Storage Location

auto Block Block duration auto (optional) Stack memory

extern Global Program duration extern Global memory

static Block (local) / File Program duration static Global memory

register Block Block duration register CPU register (if available)

By understanding storage classes, you can control variable behavior effectively for various
use cases in C programs.

Ques
Dynamic memory allocation in C allows memory to be allocated at runtime, enabling the
creation of flexible data structures like arrays, linked lists, and trees. The C standard library
provides four functions for dynamic memory allocation:

Dynamic Memory Allocation Functions in C

1. malloc() (Memory Allocation)

 Allocates a block of memory of specified size (in bytes).


 Returns a pointer to the beginning of the block.
 The allocated memory is uninitialized.
 Returns NULL if the allocation fails.

Syntax:

void* malloc(size_t size);

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
int *ptr;
int n = 5;

// Allocate memory for 5 integers


ptr = (int*)malloc(n * sizeof(int));

if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}

// Initialize and print the values


for (int i = 0; i < n; i++) {
ptr[i] = i + 1;
printf("%d ", ptr[i]);
}

// Free allocated memory


free(ptr);

return 0;
}

Output:

1 2 3 4 5

2. calloc() (Contiguous Allocation)


 Allocates memory for an array of elements, initializing all bytes to zero.
 Returns a pointer to the allocated memory.
 Returns NULL if the allocation fails.

Syntax:

void* calloc(size_t num, size_t size);

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
int *ptr;
int n = 5;

// Allocate memory for 5 integers and initialize to zero


ptr = (int*)calloc(n, sizeof(int));

if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}

// Print the values (all initialized to 0)


for (int i = 0; i < n; i++) {
printf("%d ", ptr[i]);
}

// Free allocated memory


free(ptr);

return 0;
}

Output:

0 0 0 0 0

3. realloc() (Reallocation)

 Resizes an already allocated memory block.


 If the new size is larger, the additional memory is uninitialized.
 If the new size is smaller, the remaining memory is freed.
 Returns a pointer to the new memory block, or NULL if the reallocation fails.

Syntax:

void* realloc(void* ptr, size_t new_size);

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
int *ptr;
int n = 5;

// Allocate memory for 5 integers


ptr = (int*)malloc(n * sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}

// Initialize the values


for (int i = 0; i < n; i++) {
ptr[i] = i + 1;
}

// Reallocate memory to hold 10 integers


ptr = (int*)realloc(ptr, 10 * sizeof(int));
if (ptr == NULL) {
printf("Memory reallocation failed\n");
return 1;
}

// Initialize the new elements


for (int i = n; i < 10; i++) {
ptr[i] = i + 1;
}

// Print the values


for (int i = 0; i < 10; i++) {
printf("%d ", ptr[i]);
}

// Free allocated memory


free(ptr);

return 0;
}

Output:

1 2 3 4 5 6 7 8 9 10

4. free() (Free Allocated Memory)

 Deallocates the memory previously allocated using malloc(), calloc(), or realloc().


 It makes the memory available for future allocations.
 Does nothing if the pointer is NULL.

Syntax:

void free(void* ptr);

Example:
#include <stdlib.h>
#include <stdio.h>

int main() {
int *ptr = (int*)malloc(5 * sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}

free(ptr); // Deallocate memory


ptr = NULL; // Avoid dangling pointer

return 0;
}

Comparison of malloc() and calloc()


Feature malloc() calloc()

Initialization Uninitialized memory Initializes all to 0

Syntax malloc(size) calloc(num, size)

Speed Faster Slightly slower (due to initialization)

Key Points:

1. Always check the return value of malloc(), calloc(), or realloc() to ensure memory
allocation succeeded.
2. Use free() to release dynamically allocated memory to avoid memory leaks.
3. Use realloc() carefully, as it may change the memory address of the block. Always assign
the result back to the same pointer.

By using dynamic memory allocation, you can efficiently handle varying memory
requirements in your programs.

Ques

What is a Pointer?

A pointer in C is a variable that stores the memory address of another variable. Pointers
allow for efficient memory manipulation and provide the ability to dynamically manage
memory.

Pointer to a Function
A pointer to a function stores the address of a function and can be used to call the function
indirectly. This is especially useful when working with callbacks or dynamic function
dispatch.

Syntax:

return_type (*pointer_name)(parameter_list);

Example of a Pointer to a Function:

#include <stdio.h>

void greet() {
printf("Hello, World!\n");
}

int main() {
void (*func_ptr)(); // Declaring a pointer to a function
func_ptr = greet; // Assigning the address of the function
func_ptr(); // Calling the function using the pointer
return 0;
}

Output:

Hello, World!

Array of Pointers to Functions

An array of pointers to functions is a collection of function pointers, allowing dynamic


selection of functions based on certain conditions.

Use Case: This is useful in scenarios such as menu-driven programs or implementing


polymorphism-like behavior in C.

Example: Array of Pointers to Functions


#include <stdio.h>

// Function prototypes
void add(int a, int b);
void subtract(int a, int b);
void multiply(int a, int b);

int main() {
// Declare an array of pointers to functions
void (*operations[])(int, int) = {add, subtract, multiply};

int choice, x = 10, y = 5;

printf("Select an operation:\n");
printf("0: Add\n1: Subtract\n2: Multiply\n");
printf("Enter your choice: ");
scanf("%d", &choice);

if (choice >= 0 && choice < 3) {


// Call the selected function
operations[choice](x, y);
} else {
printf("Invalid choice.\n");
}

return 0;
}

// Function definitions
void add(int a, int b) {
printf("Addition: %d + %d = %d\n", a, b, a + b);
}

void subtract(int a, int b) {


printf("Subtraction: %d - %d = %d\n", a, b, a - b);
}

void multiply(int a, int b) {


printf("Multiplication: %d * %d = %d\n", a, b, a * b);
}

Input:

Output:

Subtraction: 10 - 5 = 5

Explanation:

1. Function Pointers:
The operations array holds pointers to the three functions: add, subtract, and
multiply.
2. Dynamic Selection:
o The user selects an operation by providing an index (choice).
o The corresponding function is accessed using operations[choice] and
invoked with the required parameters.
3. Usage:
o This approach simplifies code for tasks like menu-driven programs.
o Eliminates the need for multiple if-else or switch statements.

Key Points to Remember:

1. Declaration Syntax:
o For a single function pointer:
return_type (*pointer_name)(parameter_list);
o For an array of function pointers:
return_type (*array_name[])(parameter_list);
2. Calling a Function:
Use the pointer like a regular function:
pointer_name(arguments);
3. Initialization:
Assign the address of a function to the pointer:
pointer_name = function_name;

By using arrays of pointers to functions, you can achieve modularity, flexibility, and cleaner
code in your programs.

Ques

Formatted vs. Unformatted Input and Output Functions in C

The input and output (I/O) functions in C can be broadly classified into formatted and
unformatted categories. They differ in terms of how they handle data, provide control over
formatting, and interact with the user or system.

1. Formatted Input and Output Functions

 Purpose: Provide precise control over how data is input and output, allowing for formatting
such as alignment, precision, and data type conversion.
 Functions:
o Input: scanf(), fscanf(), sscanf()
o Output: printf(), fprintf(), sprintf()

Key Features:

1. Control Over Data Format:


o Format specifiers (e.g., %d, %f, %s) define the type and layout of data.
2. Type-Specific Input/Output:
o Ensures correct handling of different data types.
3. Complexity:
o Requires understanding of format specifiers but provides flexibility.

Example:
#include <stdio.h>

int main() {
int num;
float price;

// Formatted input
printf("Enter an integer and a floating-point number: ");
scanf("%d %f", &num, &price);

// Formatted output
printf("Integer: %d, Price: %.2f\n", num, price);
return 0;
}

Input:

42 99.99

Output:

Integer: 42, Price: 99.99

2. Unformatted Input and Output Functions

 Purpose: Perform basic I/O without any formatting. These functions work directly with raw
data (characters, strings, or bytes).
 Functions:
o Input: getchar(), gets(), fgets(), fgetc()
o Output: putchar(), puts(), fputs(), fputc()

Key Features:

1. No Format Specifiers:
o Input/output is handled as-is without type conversion or formatting.
2. Simpler to Use:
o Suitable for character or string I/O operations.
3. Limited Control:
o Cannot format data (e.g., alignment or precision).

Example:
#include <stdio.h>

int main() {
char ch;
char str[50];

// Unformatted input
printf("Enter a character: ");
ch = getchar(); // Reads a single character

getchar(); // Consume newline left by getchar()


printf("Enter a string: ");
fgets(str, sizeof(str), stdin); // Reads a string

// Unformatted output
printf("You entered: ");
putchar(ch); // Prints a single character
puts(str); // Prints a string with a newline

return 0;
}

Input:
A
Hello, World!

Output:

You entered: A
Hello, World!

Key Differences

Feature Formatted I/O Unformatted I/O

Provides precise control over input/output Simple input/output without


Functionality
formatting. formatting.

Functions Used scanf(), printf(), etc. getchar(), puts(), etc.

Requires understanding of format


Complexity Easier to use; no specifiers required.
specifiers.

Suitable for structured data (e.g., numbers, Suitable for raw data (e.g.,
Use Cases
floats). characters, strings).

Handling Data Handles multiple types with format Works primarily with characters and
Types specifiers. strings.

Limited validation; raw data is


Error Handling Can validate input based on specifiers.
accepted.

Directly reads or writes characters or


Examples %d for integers, %f for floats.
strings.

When to Use Which?

 Formatted I/O:
o Use when precision or control over input/output is needed.
o Ideal for structured data, like reading numbers or formatted strings.
 Unformatted I/O:
o Use for basic input/output, such as reading a single character or entire strings.
o Preferred for simpler tasks, like reading user input without format enforcement.

By understanding these differences, you can choose the appropriate method for your specific
programming needs.

Ques

Definition of Structure and Union in C


Structure and Union are user-defined data types in C that allow grouping multiple variables
of different data types under one name. While they are similar in many ways, they differ in
how they store and manage memory.

1. Structure

A structure is a collection of variables (known as members) of different data types grouped


together under a single name.

Key Features of Structure:

1. Members of a structure occupy separate memory locations.


2. Each member can be accessed and modified independently.
3. Useful for creating complex data types like employee records, points, etc.

Syntax:
struct StructureName {
data_type member1;
data_type member2;
...
};

Example:
#include <stdio.h>

// Defining a structure
struct Student {
int id;
char name[50];
float marks;
};

int main() {
struct Student s1;

// Assigning values
s1.id = 101;
strcpy(s1.name, "John Doe");
s1.marks = 85.5;

// Accessing and printing members


printf("ID: %d\n", s1.id);
printf("Name: %s\n", s1.name);
printf("Marks: %.2f\n", s1.marks);

return 0;
}

Output:

ID: 101
Name: John Doe
Marks: 85.50
2. Union

A union is similar to a structure but with one key difference: all members share the same
memory location. This means that only one member can hold a value at any given time.

Key Features of Union:

1. Members of a union share the same memory location, so the size of a union is determined
by its largest member.
2. Changing one member's value will overwrite the value of another member.
3. Useful for memory-efficient programs or cases where only one member is used at a time.

Syntax:
union UnionName {
data_type member1;
data_type member2;
...
};

Example:
#include <stdio.h>

// Defining a union
union Data {
int i;
float f;
char str[20];
};

int main() {
union Data d;

// Assigning and accessing members


d.i = 10;
printf("Integer: %d\n", d.i);

d.f = 12.5;
printf("Float: %.2f\n", d.f);

strcpy(d.str, "Hello");
printf("String: %s\n", d.str);

// Note: Overwriting occurs, as all members share the same memory.


printf("After assigning string, Integer: %d\n", d.i);

return 0;
}

Output:

Integer: 10
Float: 12.50
String: Hello
After assigning string, Integer: Garbage Value (memory overwritten)
Key Differences Between Structure and Union

Feature Structure Union

Memory Each member has its own memory All members share the same memory
Allocation space. space.

Size Size = Sum of sizes of all members. Size = Size of the largest member.

All members can be accessed Only one member can be accessed at a


Access
simultaneously. time.

Used for storing and manipulating Used for memory-efficient programs where
Usage
multiple members simultaneously. only one member is used at a time.

Example Use Representing a variable in different forms


Employee details (ID, name, salary).
Case (e.g., int, float).

By choosing between structures and unions, you can balance between ease of access and
memory efficiency, depending on the requirements of your program.

Ques

What is the atoi() Function?

The atoi() function in C is used to convert a string into an integer. It is part of the
<stdlib.h> library. The name stands for "ASCII to Integer."

Syntax:
int atoi(const char *str);

 Parameter:
str: A null-terminated string representing a numeric value.
 Return Value:
o Returns the integer value of the string.
o If the string does not contain a valid number, the behavior is undefined (usually
returns 0).

Key Features:

1. Converts strings containing numeric characters into integers.


2. Ignores leading white spaces and stops conversion at non-numeric characters.
3. Does not handle errors like invalid strings, which might lead to undefined behavior.

Example: Using atoi()


#include <stdio.h>
#include <stdlib.h> // For atoi()

int main() {
char str1[] = "123";
char str2[] = " 456"; // Leading spaces
char str3[] = "78abc"; // Stops at non-numeric character
char str4[] = "abc123"; // Invalid string

// Convert strings to integers


int num1 = atoi(str1);
int num2 = atoi(str2);
int num3 = atoi(str3);
int num4 = atoi(str4); // Undefined behavior

// Display the results


printf("String: '%s', Integer: %d\n", str1, num1);
printf("String: '%s', Integer: %d\n", str2, num2);
printf("String: '%s', Integer: %d\n", str3, num3);
printf("String: '%s', Integer: %d\n", str4, num4);

return 0;
}

Output:
String: '123', Integer: 123
String: ' 456', Integer: 456
String: '78abc', Integer: 78
String: 'abc123', Integer: 0 (undefined behavior)

Explanation:

1. "123": The string is valid, so it's converted to 123.


2. " 456": Leading spaces are ignored, and the string is converted to 456.
3. "78abc": Conversion stops at the first non-numeric character ('a'), so the result is 78.
4. "abc123": The string starts with non-numeric characters, leading to undefined behavior.
Often, it returns 0.

Limitations of atoi()

1. Undefined Behavior:
If the input string is invalid or contains no numeric data, the function does not handle errors
gracefully.
2. No Overflow Detection:
If the converted value exceeds the range of int, the behavior is undefined.

Alternative: strtol()

To handle errors and overflows, use strtol() instead of atoi(). It provides better error
handling and flexibility.

Example: Using strtol()


#include <stdio.h>
#include <stdlib.h>

int main() {
char str[] = "123abc";
char *end;

// Convert string to integer using strtol


long int num = strtol(str, &end, 10);

// Display results
printf("Converted Number: %ld\n", num);
printf("Unprocessed Part: '%s'\n", end);

return 0;
}

Output:

Converted Number: 123


Unprocessed Part: 'abc'

Summary:

 atoi() is simple but lacks error handling and overflow detection.


 Use it for straightforward conversions where input is guaranteed to be valid.
 For robust applications, prefer strtol() for error and overflow handling.

Ques

Comparison Between Arrays and Structures in C

Arrays and structures are two important data types in C used to store and manage collections
of data. However, they differ significantly in their design, use cases, and functionality.

Key Differences
Aspect Array Structure

A collection of elements of the same A collection of elements of different data


Definition
data type. types.

Memory Memory is allocated contiguously for Memory is allocated separately for each
Allocation all elements. member.

Accessing Accessed using an index (e.g., Accessed using the dot operator (e.g.,
Elements arr[i]). struct.member).

All elements must be of the same


Homogeneity Members can be of different types.
type.

Used when managing a list of similar Used for grouping related but diverse data
Use Case
items (e.g., numbers, strings). (e.g., a record of an employee).

Fixed size (number of elements × size


Size Sum of the sizes of all members.
of one element).

Less flexible, limited to storing More flexible, can represent complex data
Flexibility
homogeneous data. structures.

Slightly more complex due to mixed data


Complexity Simpler to implement and use.
types.

Iteration is straightforward using Iteration requires handling each member


Iteration
loops. separately.

Example of an Array
#include <stdio.h>

int main() {
// Array of integers
int scores[5] = {90, 85, 88, 92, 78};

printf("Scores:\n");
for (int i = 0; i < 5; i++) {
printf("%d ", scores[i]);
}
return 0;
}

Output:

Scores:
90 85 88 92 78
Example of a Structure
#include <stdio.h>

// Define a structure to store student information


struct Student {
int id;
char name[50];
float marks;
};

int main() {
struct Student s1 = {101, "Alice", 88.5};

// Accessing structure members


printf("Student Details:\n");
printf("ID: %d\n", s1.id);
printf("Name: %s\n", s1.name);
printf("Marks: %.2f\n", s1.marks);

return 0;
}

Output:

Student Details:
ID: 101
Name: Alice
Marks: 88.50

Combined Example: Justifying the Comparison

Scenario:

Suppose you want to store details of multiple students, including their ID, name, and marks.
Using an array alone won't work effectively because it can only store homogeneous data. A
structure, however, can handle this complexity.

Using an Array (Homogeneous Data)


#include <stdio.h>

int main() {
int ids[3] = {101, 102, 103}; // Array for IDs
float marks[3] = {88.5, 76.0, 90.2}; // Array for Marks

printf("Student Data:\n");
for (int i = 0; i < 3; i++) {
printf("ID: %d, Marks: %.2f\n", ids[i], marks[i]);
}

return 0;
}

Limitations:
 Cannot store names easily.
 The relationship between ids and marks must be maintained manually.

Using a Structure (Heterogeneous Data)


#include <stdio.h>

// Define a structure for students


struct Student {
int id;
char name[50];
float marks;
};

int main() {
// Array of structures
struct Student students[3] = {
{101, "Alice", 88.5},
{102, "Bob", 76.0},
{103, "Charlie", 90.2}
};

printf("Student Data:\n");
for (int i = 0; i < 3; i++) {
printf("ID: %d, Name: %s, Marks: %.2f\n", students[i].id,
students[i].name, students[i].marks);
}

return 0;
}

Output:

Student Data:
ID: 101, Name: Alice, Marks: 88.50
ID: 102, Name: Bob, Marks: 76.00
ID: 103, Name: Charlie, Marks: 90.20

Key Takeaways

 Use Arrays for simple, homogeneous data like a list of integers or floating-point numbers.
 Use Structures for grouping diverse but related data to represent real-world entities like a
student's record or an employee's details.

Ques

Inbuilt String Functions in C

In C, strings are arrays of characters terminated by a null character ('\0'). The standard C
library <string.h> provides a collection of functions to perform various operations on
strings like copying, concatenating, comparing, and searching. Here’s a summary of the
common string functions, their syntax, and examples of how they are used.
Commonly Used String Functions

1. strlen()
o Purpose: Returns the length of the string (not including the null character).
o Syntax:
o size_t strlen(const char *str);
o Example:
o #include <stdio.h>
o #include <string.h>
o
o int main() {
o char str[] = "Hello, World!";
o printf("Length of string: %zu\n", strlen(str)); // Output:
13
o return 0;
o }
2. strcpy()
o Purpose: Copies the content of one string to another.
o Syntax:
o char *strcpy(char *dest, const char *src);
o Example:
o #include <stdio.h>
o #include <string.h>
o
o int main() {
o char src[] = "Hello";
o char dest[20];
o
o strcpy(dest, src); // Copy content of src to dest
o printf("Copied string: %s\n", dest); // Output: Hello
o
o return 0;
o }
3. strcat()
o Purpose: Concatenates (appends) one string to the end of another.
o Syntax:
o char *strcat(char *dest, const char *src);
o Example:
o #include <stdio.h>
o #include <string.h>
o
o int main() {
o char str1[30] = "Hello, ";
o char str2[] = "World!";
o
o strcat(str1, str2); // Append str2 to str1
o printf("Concatenated string: %s\n", str1); // Output:
Hello, World!
o
o return 0;
o }
4. strcmp()
o Purpose: Compares two strings lexicographically.
o Syntax:
o int strcmp(const char *str1, const char *str2);
 Returns:
 0if the strings are equal.
 A negative value if str1 is less than str2.
 A positive value if str1 is greater than str2.
o Example:
o #include <stdio.h>
o #include <string.h>
o
o int main() {
o char str1[] = "Hello";
o char str2[] = "World";
o
o int result = strcmp(str1, str2);
o if (result == 0) {
o printf("Strings are equal.\n");
o } else if (result < 0) {
o printf("'%s' is lexicographically smaller than '%s'.\
n", str1, str2);
o } else {
o printf("'%s' is lexicographically greater than '%s'.\
n", str1, str2);
o }
o
o return 0;
o }

Output:

'Hello' is lexicographically smaller than 'World'.

5. strchr()
o Purpose: Finds the first occurrence of a character in a string.
o Syntax:
o char *strchr(const char *str, int c);
 Returns a pointer to the first occurrence of c in str, or NULL if the
character is not found.
o Example:
o #include <stdio.h>
o #include <string.h>
o
o int main() {
o char str[] = "Hello, World!";
o char *ptr = strchr(str, 'o');
o
o if (ptr != NULL) {
o printf("Character found: %c at position %ld\n", *ptr,
ptr - str);
o } else {
o printf("Character not found\n");
o }
o
o return 0;
o }

Output:

Character found: o at position 4


6. strstr()
o Purpose: Finds the first occurrence of a substring within another string.
o Syntax:
o char *strstr(const char *haystack, const char *needle);
o Example:
o #include <stdio.h>
o #include <string.h>
o
o int main() {
o char str[] = "Hello, World!";
o char *substr = strstr(str, "World");
o
o if (substr != NULL) {
o printf("Substring found at position: %ld\n", substr -
str);
o } else {
o printf("Substring not found\n");
o }
o
o return 0;
o }

Output:

Substring found at position: 7

7. strtok()
o Purpose: Splits a string into tokens based on delimiters.
o Syntax:
o char *strtok(char *str, const char *delim);
o Example:
o #include <stdio.h>
o #include <string.h>
o
o int main() {
o char str[] = "Hello,World,Welcome";
o char *token = strtok(str, ",");
o
o while (token != NULL) {
o printf("Token: %s\n", token);
o token = strtok(NULL, ",");
o }
o
o return 0;
o }

Output:

Token: Hello
Token: World
Token: Welcome

Summary of String Functions


Function Purpose Example
strlen() Returns the length of a string. strlen("Hello") returns 5.
strcpy() Copies a string into another. strcpy(dest, "Hello") copies to dest.
strcat("Hello", " World") results in
strcat() Concatenates one string to another.
"Hello World".
Compares two strings
strcmp() strcmp("abc", "abd") returns negative.
lexicographically.
Finds the first occurrence of a
strchr() strchr("Hello", 'o') returns pointer to 'o'.
character.
Finds the first occurrence of a strstr("Hello World", "World") returns
strstr()
substring. pointer to "World".
Splits a string into tokens based on
strtok() strtok("a,b,c", ",") splits the string.
delimiters.

These functions provide essential capabilities to manipulate strings in C, making them a vital
part of the standard library.

Ques

What is Type Casting?

Type casting is the process of converting a variable from one data type to another in
programming. It is also known as type conversion.

 Implicit Type Casting: Automatically performed by the compiler when there is no loss of
data.
 Explicit Type Casting: Performed manually by the programmer to force the conversion of a
variable to a specific data type.

Why is Type Casting Required?

1. To perform operations involving multiple data types (e.g., integer and float arithmetic).
2. To avoid data loss or ensure precision in calculations.
3. To make a variable compatible with a specific function or requirement.
4. To manipulate data efficiently in low-level programming.

Example of Type Casting

1. Implicit Type Casting

When a smaller data type is automatically converted to a larger data type.

#include <stdio.h>
int main() {
int a = 10;
float b = a; // Implicit casting from int to float
printf("Value of b: %.2f\n", b);
return 0;
}

Output:

Value of b: 10.00

Here, the int variable a is implicitly converted to float without any manual intervention.

2. Explicit Type Casting

When a programmer explicitly converts one data type to another.

#include <stdio.h>
int main() {
float x = 10.5;
int y = (int)x; // Explicit casting from float to int
printf("Value of y: %d\n", y);
return 0;
}

Output:

Value of y: 10

Here, the float value 10.5 is explicitly cast to int, resulting in the truncation of the decimal
part.

Conclusion

Type casting is required when dealing with multiple data types in operations, avoiding errors,
and controlling precision. It can be done implicitly (automatic) or explicitly (manual)
depending on the situation.

Ques

Here is the detailed explanation and C program based on the question:

1. Explanation of if..else statement

The if..else statement is a conditional control structure used to execute a block of code
based on a condition.
Variations:

1. Simple if statement
o Syntax:
o if (condition) {
o // Code to execute if the condition is true
o }

2. if..else statement
o Syntax:
o if (condition) {
o // Code to execute if condition is true
o } else {
o // Code to execute if condition is false
o }

3. if..else if ladder
o Syntax:
o if (condition1) {
o // Code if condition1 is true
o } else if (condition2) {
o // Code if condition2 is true
o } else {
o // Code if none of the conditions are true
o }

4. Nested if
o Syntax:
o if (condition1) {
o if (condition2) {
o // Code if both conditions are true
o }
o }

2. Explanation of switch..case

The switch..case statement is used to test a variable against a list of values.

Syntax:
switch (variable) {
case value1:
// Code to execute if variable == value1
break;
case value2:
// Code to execute if variable == value2
break;
default:
// Code to execute if none of the cases match
}

Key Points:

1. The switch statement is more efficient when checking a single variable against multiple
constant values.
2. The break statement is used to exit the switch block.
3. default is optional and executes when no case matches.

3. Differences Between if..else and switch..case


if..else switch..case

Used for complex conditions involving relational or Used for testing equality against constant
logical operators. values.

Slower for multiple conditions as it checks them


Faster for multiple cases due to direct jump.
sequentially.

Supports range and conditions. Cannot handle ranges, only constants.

Cleaner when there are many constant


Flexible and readable for complex conditions.
comparisons.

4. C Program Demonstrating the Difference

Here is a program comparing the usage of if..else and switch..case for the same logic:

#include <stdio.h>

int main() {
int choice;

printf("Enter a number (1-3): ");


scanf("%d", &choice);

// Using if..else
printf("\nUsing if..else:\n");
if (choice == 1) {
printf("You chose One\n");
} else if (choice == 2) {
printf("You chose Two\n");
} else if (choice == 3) {
printf("You chose Three\n");
} else {
printf("Invalid choice\n");
}

// Using switch..case
printf("\nUsing switch..case:\n");
switch (choice) {
case 1:
printf("You chose One\n");
break;
case 2:
printf("You chose Two\n");
break;
case 3:
printf("You chose Three\n");
break;
default:
printf("Invalid choice\n");
}

return 0;
}

Output:
Enter a number (1-3): 2

Using if..else:
You chose Two

Using switch..case:
You chose Two

Conclusion:

 Use if..else for complex conditions.


 Use switch..case for fixed, constant-based comparisons. Both achieve the same results
but are suited for different scenarios.

Ques

Recursion

Recursion is a programming technique where a function calls itself directly or indirectly to


solve a problem. It is particularly useful for problems that can be broken down into smaller,
similar sub-problems.

Key Features of Recursion

1. Base Case: The condition where the recursion stops. Without a base case, the
function will keep calling itself indefinitely.
2. Recursive Case: The part where the function calls itself to solve a smaller instance of
the problem.

Example of Recursion

Factorial of a Number

#include <stdio.h>
int factorial(int n) {
if (n == 0) // Base case
return 1;
else // Recursive case
return n * factorial(n - 1);
}

int main() {
int num = 5;
printf("Factorial of %d is %d\n", num, factorial(num));
return 0;
}

Output:

Factorial of 5 is 120

Advantages of Recursion

1. Simplifies code for problems like factorial, Fibonacci series, and tree traversals.
2. Reduces the need for complex looping structures.

Disadvantages of Recursion

1. Consumes more memory due to function call stack.


2. Can lead to stack overflow if the base case is not well defined.

Applications of Recursion

 Mathematical problems (factorial, Fibonacci)


 Data structures (trees, graphs)
 Sorting algorithms (Quick Sort, Merge Sort)
 Solving puzzles (Tower of Hanoi)

Recursion is a powerful tool, but it must be used carefully to avoid performance issues.

Factorial of a no. 5=1*2*3*4*5

#inc……

Void factorial()

Int num, count, fact;

Printf(“enter the number”)

Scanf(“%d”,&num);
For (count=1;count<=num; count++);

Fact=fact*count;

Int main()

Printf(“factorial of %d is %d”,num,factorial(fact));

You might also like