Answers Pyq
Answers Pyq
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.
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
}
}
}
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.
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];
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}
};
return 0;
}
Partial Initialization
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
};
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;
// Assigning values
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
array[i][j] = i * cols + j + 1;
}
}
// Freeing memory
for (int i = 0; i < rows; i++) {
free(array[i]);
}
free(array);
return 0;
}
Key Notes:
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:
Storage Usually stored in the stack Stored in the data segment of memory
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
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
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:
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:
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.
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;
}
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;
}
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
1. Arithmetic Operators
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;
}
Used to compare two values and return a Boolean result (1 for true, 0 for false).
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
` ` Logical OR
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
` ` Bitwise OR `a
5. Assignment Operators
= Assign value a = b a = b
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
Summary Table
Arithmetic a + b, a * b
Operator Type Example
Relational a < b, a == b
Logical a && b, !a
Assignment a = b, 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:
Syntax:
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
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
#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);
#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);
#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:
Explanation: The entire input "John Doe" is captured, including the space.
Key Differences
#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)
#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)
#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;
}
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.
Output:
Count: 1
Count: 2
Count: 3
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)
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
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:
Syntax:
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
return 0;
}
Output:
1 2 3 4 5
Syntax:
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
return 0;
}
Output:
0 0 0 0 0
3. realloc() (Reallocation)
Syntax:
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
return 0;
}
Output:
1 2 3 4 5 6 7 8 9 10
Syntax:
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;
}
return 0;
}
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);
#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!
// 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};
printf("Select an operation:\n");
printf("0: Add\n1: Subtract\n2: Multiply\n");
printf("Enter your choice: ");
scanf("%d", &choice);
return 0;
}
// Function definitions
void add(int a, int b) {
printf("Addition: %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.
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
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.
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:
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:
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
// 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
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.
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
1. Structure
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;
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.
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;
d.f = 12.5;
printf("Float: %.2f\n", d.f);
strcpy(d.str, "Hello");
printf("String: %s\n", d.str);
return 0;
}
Output:
Integer: 10
Float: 12.50
String: Hello
After assigning string, Integer: Garbage Value (memory overwritten)
Key Differences Between Structure and 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.
Used for storing and manipulating Used for memory-efficient programs where
Usage
multiple members simultaneously. only one member is used at a time.
By choosing between structures and unions, you can balance between ease of access and
memory efficiency, depending on the requirements of your program.
Ques
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:
int main() {
char str1[] = "123";
char str2[] = " 456"; // Leading spaces
char str3[] = "78abc"; // Stops at non-numeric character
char str4[] = "abc123"; // Invalid string
return 0;
}
Output:
String: '123', Integer: 123
String: ' 456', Integer: 456
String: '78abc', Integer: 78
String: 'abc123', Integer: 0 (undefined behavior)
Explanation:
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.
int main() {
char str[] = "123abc";
char *end;
// Display results
printf("Converted Number: %ld\n", num);
printf("Unprocessed Part: '%s'\n", end);
return 0;
}
Output:
Summary:
Ques
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
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).
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).
Less flexible, limited to storing More flexible, can represent complex data
Flexibility
homogeneous data. structures.
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>
int main() {
struct Student s1 = {101, "Alice", 88.5};
return 0;
}
Output:
Student Details:
ID: 101
Name: Alice
Marks: 88.50
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.
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.
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
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:
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:
Output:
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
These functions provide essential capabilities to manipulate strings in C, making them a vital
part of the standard library.
Ques
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.
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.
#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.
#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
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
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.
Used for complex conditions involving relational or Used for testing equality against constant
logical operators. values.
Here is a program comparing the usage of if..else and switch..case for the same logic:
#include <stdio.h>
int main() {
int 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:
Ques
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
Applications of Recursion
Recursion is a powerful tool, but it must be used carefully to avoid performance issues.
#inc……
Void factorial()
Scanf(“%d”,&num);
For (count=1;count<=num; count++);
Fact=fact*count;
Int main()
Printf(“factorial of %d is %d”,num,factorial(fact));