C Q&A Menu

C Programming Q&A

A comprehensive list of 72 common C programming questions and answers. Made by Sayan Maity

1. Difference Between RAM and ROM

RAM (Random Access Memory) and ROM (Read-Only Memory) are both types of computer memory, but they serve different purposes. Here are the major differences between them:

Feature RAM (Random Access Memory) ROM (Read-Only Memory)
Definition Volatile memory used for temporary data storage. Non-volatile memory used for permanent storage.
Volatility & Usage Volatile - Data is lost when power is turned off. Stores data currently in use by the CPU (OS, applications). Non-volatile - Data remains even after power loss. Stores firmware (BIOS, bootloader, embedded systems).
Read/Write Read & Write - Data can be modified frequently. Read-Only - Data is written once (mostly during manufacturing).
Speed Faster - Allows quick access for active processes. Slower - Used for long-term storage, not for active processing.
Types DRAM (Dynamic RAM), SRAM (Static RAM). PROM, EPROM, EEPROM, Flash Memory.
Modification Data can be changed anytime. Data is permanent or requires special methods to modify (e.g., flashing).
Cost More expensive per GB. Cheaper for permanent storage.
Capacity Higher capacity (up to several GBs in modern systems). Smaller capacity (MBs to a few GBs).

Key Takeaways:

  • RAM is temporary, fast, and volatile (used for active tasks).
  • ROM is permanent, slower, and non-volatile (used for firmware).
  • RAM loses data when powered off, while ROM retains it.
  • RAM is used for running applications, whereas ROM stores critical system instructions.

2. Components of a Computer System & Their Roles

A computer system consists of hardware and software components that work together to execute programs. The major components and their roles in program execution are:

  1. Input Unit: Accepts data and instructions from the user or external devices (e.g., Keyboard, Mouse).
  2. Central Processing Unit (CPU): The "brain" that performs arithmetic, logical, and control operations. It includes the Control Unit (CU) and Arithmetic Logic Unit (ALU).
  3. Memory Unit (Primary Storage): Includes RAM (for currently running programs) and ROM (for firmware like BIOS).
  4. Secondary Storage (Auxiliary Memory): Stores data permanently (e.g., HDD, SSD).
  5. Output Unit: Displays or transmits processed data to the user (e.g., Monitor, Printer).
  6. System Bus: Connects CPU, Memory, and I/O devices for communication.

3. C Language: Definition and Characteristics

C is a procedural, high-level programming language developed by Dennis Ritchie in 1972 at Bell Labs. It was designed for system programming, particularly for writing operating systems like UNIX. It is often called the "mother of all programming languages."

Key Characteristics:

  • Procedural Programming: Follows a step-by-step approach using functions.
  • Mid-Level Language: Combines features of low-level and high-level languages.
  • Portability: C programs can run on different machines with little modification.
  • Fast and Efficient: Provides direct memory access via pointers.
  • Rich Library Support: Comes with a standard library (e.g., stdio.h, math.h).
  • Static Typing: Variables must be declared with a data type before use.

4. Identifier in C

An identifier is a name given to variables, functions, arrays, structures, etc., in a C program.

Rules for Declaring Identifier Names:

  • Can include letters (A-Z, a-z), digits (0-9), and underscore (_).
  • Must start with a letter or underscore (not a digit).
  • Case-sensitive (e.g., `sum`, `Sum`, and `SUM` are different).
  • Cannot use reserved keywords (e.g., `int`, `if`).
  • No special symbols allowed (e.g., `!`, `@`, `#`, `$` ).

Valid: total, _count, sum1

Invalid: 5sum (starts with digit), float (keyword), first-name (hyphen not allowed)

5. Number System Conversions

  • (101110)2 to Decimal: (1×25) + (0×24) + (1×23) + (1×22) + (1×21) + (0×20) = 32 + 0 + 8 + 4 + 2 + 0 = 4610
  • (47)8 to Binary: 4 = 100, 7 = 111. Combine: 1001112
  • (2F)16 to Decimal: (2×161) + (15×160) = 32 + 15 = 4710
  • (1001)2 to Octal: Group into 3 bits: 001 001. Convert each group: 1 1. Combine: 118
  • (59)10 to Binary: Repeatedly divide by 2 and record remainders: 1110112

6. Type Casting in C

Type casting is the process of converting a variable from one data type to another. It allows programmers to temporarily change the type of a variable for a specific operation.

Types of Type Casting

  1. Implicit Type Casting (Automatic): Done by the compiler from a lower to a higher data type (e.g., `int` to `float`).
  2. Explicit Type Casting (Manual): Done by the programmer using the cast operator `(datatype)` (e.g., `(int)5.7`).

Example: Explicit Casting for Division

int x = 5, y = 2;
float result = (float)x / y; // Cast x to float for float division
printf("%f", result); // Output: 2.500000

7. Difference Between Algorithm and Flowchart

Feature Algorithm Flowchart
Definition Step-by-step procedure to solve a problem. Graphical representation of an algorithm using symbols.
Form Textual (written in simple language or pseudocode). Visual (uses shapes like rectangles, diamonds, arrows).
Ease of Understanding Requires basic programming knowledge. Easier to understand (even for non-programmers).
Modification Easier to modify (text-based). Harder to modify (requires redrawing).

8. Types of Operators in C

  • Arithmetic: `+`, `-`, `*`, `/`, `%`
  • Relational: `==`, `!=`, `>`, `<`, `>=`, `<=`
  • Logical: `&&`, `||`, `!`
  • Assignment: `=`, `+=`, `-=`, `*=`, `/=`
  • Increment/Decrement: `++`, `--`
  • Bitwise: `&`, `|`, `^`, `~`, `<<`, `>>`
  • Conditional (Ternary): `condition ? expr1 : expr2`

9. Number System Conversions (Detailed)

This section provides a more detailed look at binary conversions.

  • Binary to Decimal: Multiply each bit by 2n (where n is its position from the right, starting at 0) and sum the results. Example: (1011)2 = 8 + 0 + 2 + 1 = 1110.
  • Binary to Octal: Group binary digits into sets of 3 from the right. Convert each group to its octal equivalent. Example: (110101)2 -> 110 101 -> 6 5 -> 658.
  • Binary to Hexadecimal: Group binary digits into sets of 4 from the right. Convert each group to its hex equivalent. Example: (11101011)2 -> 1110 1011 -> E B -> EB16.

10. Operator Precedence and Associativity

Precedence determines the order in which operators are evaluated in an expression (e.g., `*` has higher precedence than `+`).

Associativity determines the order for operators of the same precedence (e.g., `+` and `-` are left-to-right, while `=` is right-to-left).

Parentheses `()` can be used to override the default precedence.

11. Algorithm and Flowchart to Check for a Prime Number

Algorithm

  1. Start
  2. Read number n.
  3. If n <= 1, print "Not Prime" and exit.
  4. Set a flag `isPrime = true`.
  5. Loop from i = 2 to sqrt(n).
  6. If n % i == 0, set `isPrime = false` and break the loop.
  7. If `isPrime` is true, print "Prime". Otherwise, print "Not Prime".
  8. Stop.

Flowchart

Start ↓ Read number n ↓ Is n <= 1? --(Yes)--> Print "Not Prime" --> End ↓ (No) Set i = 2 ↓ Is i <= sqrt(n)? --(No)--> Print "Prime" --> End ↓ (Yes) Is n % i == 0? --(Yes)--> Print "Not Prime" --> End ↓ (No) i = i + 1 ↓ (Back to "Is i <= sqrt(n)?")

12. C Program to Find Max of Two Numbers (Ternary Operator)

#include <stdio.h>

int main() {
    int num1, num2, max;

    printf("Enter two numbers: ");
    scanf("%d %d", &num1, &num2);

    // Find maximum using ternary operator
    max = (num1 > num2) ? num1 : num2;

    printf("Maximum between %d and %d is: %d\n", num1, num2, max);

    return 0;
}

13. Differentiate between `for`, `while`, and `do-while` loops

Loop Condition Check Minimum Runs Typical Use Case
for Before iteration (Entry-controlled) 0 When the number of iterations is known (e.g., iterating over an array).
while Before iteration (Entry-controlled) 0 When the number of iterations is unknown and depends on a condition.
do-while After iteration (Exit-controlled) 1 When the loop body must be executed at least once (e.g., menu-driven programs).

14. C Program to Check Prime Number using `for` loop

#include <stdio.h>
#include <math.h> // For sqrt() function

int main() {
    int n, i, isPrime = 1; // isPrime=1 means true

    printf("Enter a positive integer: ");
    scanf("%d", &n);

    if (n <= 1) {
        isPrime = 0; // 0 and 1 are not prime
    } else {
        for (i = 2; i <= sqrt(n); i++) {
            if (n % i == 0) {
                isPrime = 0; // Found a divisor, not prime
                break;
            }
        }
    }

    if (isPrime)
        printf("%d is a prime number.\n", n);
    else
        printf("%d is not a prime number.\n", n);

    return 0;
}

15. Concept of Nested Loops

A nested loop is a loop inside another loop. The inner loop completes all its iterations for each single iteration of the outer loop. This is useful for multi-dimensional patterns and matrix operations.

Example: Print a 3x3 Star Pattern

#include <stdio.h>

int main() {
    int i, j;
    for (i = 0; i < 3; i++) { // Outer loop for rows
        for (j = 0; j < 3; j++) { // Inner loop for columns
            printf("* ");
        }
        printf("\n"); // New line after each row
    }
    return 0;
}

16. Use of `break` and `continue` statements

`break` Statement: Used to terminate the loop immediately. Program control flows to the statement following the loop.

`continue` Statement: Used to skip the rest of the code inside the current iteration and move to the next iteration of the loop.

Example:

#include <stdio.h>

int main() {
    printf("Using continue to print odd numbers:\n");
    for (int i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            continue; // Skip even numbers
        }
        printf("%d ", i);
    }

    printf("\n\nUsing break to stop at 5:\n");
    for (int i = 1; i <= 10; i++) {
        if (i == 6) {
            break; // Stop the loop
        }
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}

17. C Program to Calculate Factorial of a Number

#include <stdio.h>

int main() {
    int num;
    long long factorial = 1;

    printf("Enter a non-negative integer: ");
    scanf("%d", &num);

    if (num < 0) {
        printf("Error: Factorial is not defined for negative numbers.\n");
    } else {
        for (int i = 1; i <= num; i++) {
            factorial *= i;
        }
        printf("The factorial of %d is: %lld\n", num, factorial);
    }
    
    return 0;
}

18. C Program to Check if a Number is Positive, Negative, or Zero

#include <stdio.h>

int main() {
    int number;
    printf("Enter an integer: ");
    scanf("%d", &number);

    if (number > 0) {
        printf("%d is a positive number.\n", number);
    } else if (number < 0) {
        printf("%d is a negative number.\n", number);
    } else {
        printf("%d is zero.\n", number);
    }

    return 0;
}

19. Working of the `switch` statement

The `switch` statement is a control flow statement that allows you to execute different blocks of code based on the value of a single variable or expression (which must be an integer type). It's an alternative to a long `if-else if-else` chain.

Example: Simple Day of the Week Printer

#include <stdio.h>

int main() {
    int day = 4;
    switch (day) {
        case 1: printf("Monday\n"); break;
        case 2: printf("Tuesday\n"); break;
        case 3: printf("Wednesday\n"); break;
        case 4: printf("Thursday\n"); break;
        case 5: printf("Friday\n"); break;
        case 6: printf("Saturday\n"); break;
        case 7: printf("Sunday\n"); break;
        default: printf("Invalid day\n");
    }
    return 0;
}

20. What is a selection statement and explain its types briefly?

A selection statement (or conditional statement) allows a program to make decisions and execute different blocks of code based on whether a specified condition is true or false.

Types of Selection Statements:

  • `if` statement: Executes a block of code only if a condition is true.
  • `if-else` statement: Executes one block of code if a condition is true, and another block if it is false.
  • `if-else if-else` ladder: Tests a series of conditions sequentially and executes the block corresponding to the first true condition.
  • `switch` statement: Chooses among many code blocks based on the value of a single integer or character variable.

21. What is a Table of Strings? How to Declare and Initialize it?

A "table of strings" is a collection of strings. It can be represented in C in two main ways:

  1. 2D Character Array: A fixed-size grid of characters, e.g., char names[5][20];. Wastes memory if strings have varying lengths.
  2. Array of Character Pointers: An array where each element is a pointer to a string, e.g., char *names[5];. More memory-efficient for strings of varying lengths.

Example Program:

#include <stdio.h>

int main() {
    // Method 1: 2D Character Array
    char languages[4][10] = {"C", "Python", "Java", "Go"};
    printf("--- 2D Array ---\n");
    for (int i = 0; i < 4; i++) {
        printf("%s\n", languages[i]);
    }

    // Method 2: Array of Pointers
    char *planets[] = {"Mercury", "Venus", "Earth", "Mars"};
    printf("\n--- Array of Pointers ---\n");
    int num_planets = sizeof(planets) / sizeof(planets[0]);
    for (int i = 0; i < num_planets; i++) {
        printf("%s\n", planets[i]);
    }

    return 0;
}

22. C Program to find the sum of all even and odd numbers separately from 1 to N

#include <stdio.h>

int main() {
    int N, sum_even = 0, sum_odd = 0;

    printf("Enter a positive integer (N): ");
    scanf("%d", &N);

    if (N <= 0) {
        printf("Error: Please enter a positive integer.\n");
        return 1;
    }

    for (int i = 1; i <= N; i++) {
        if (i % 2 == 0) {
            sum_even += i;
        } else {
            sum_odd += i;
        }
    }

    printf("Sum of even numbers from 1 to %d: %d\n", N, sum_even);
    printf("Sum of odd numbers from 1 to %d: %d\n", N, sum_odd);

    return 0;
}

23. C Program for Student Exam Eligibility (75% Attendance)

#include <stdio.h>

int main() {
    int total_classes, attended_classes;
    double percentage;

    printf("Enter total number of classes held: ");
    scanf("%d", &total_classes);
    printf("Enter number of classes attended: ");
    scanf("%d", &attended_classes);

    if (total_classes <= 0) {
        printf("Invalid total classes.\n");
        return 1;
    }

    percentage = ((double)attended_classes / total_classes) * 100.0;
    printf("Attendance Percentage: %.2f%%\n", percentage);

    if (percentage >= 75.0) {
        printf("Result: Eligible for exams.\n");
    } else {
        printf("Result: NOT eligible for exams.\n");
    }

    return 0;
}

24. Compare and contrast `if-else` and `switch`

Both are selection statements, but they are suited for different scenarios.

Feature if-else Statement switch Statement
Condition Type Evaluates boolean expressions (true/false). Can handle complex logic, ranges, and floating-point comparisons. Evaluates an integer-type expression (int, char). Checks against multiple discrete, constant values.
Flexibility More flexible; can handle any type of condition. Less flexible; restricted to integer-type expressions and constant cases.
Readability Can become a long, hard-to-read "ladder" with many `else if` conditions. Often more readable for a large number of discrete value checks.
Execution Flow Executes the first block whose condition is true and skips the rest. Jumps to the matching `case`. Requires `break` to prevent "fall-through" to subsequent cases.

25. What are different types of pointers?

  • Null Pointer: A pointer that points to nothing (NULL). Used for initialization and to indicate an invalid address.
  • Void Pointer (void *): A generic pointer that can hold the address of any data type. Must be cast before dereferencing.
  • Wild Pointer: A pointer that has been declared but not initialized. Points to a random memory address and is dangerous to use.
  • Dangling Pointer: A pointer that points to a memory location that has been deallocated (freed). Accessing it leads to undefined behavior.
  • Function Pointer: A pointer that stores the memory address of a function, allowing functions to be called indirectly.

26. Differentiate between a 1-D and a 2-D array

Feature One-Dimensional (1-D) Array Two-Dimensional (2-D) Array
Structure Linear list of elements (a single row/column). Table/grid of elements organized in rows and columns.
Indexing Requires a single index: array[i]. Requires two indices (row, column): array[i][j].
Declaration data_type name[size]; data_type name[rows][cols];
Use Cases Storing lists of items, sequences. Storing tabular data, matrices, images.

27. C program to find the largest element in a 1-D array

#include <stdio.h>

int main() {
    int arr[100], n, i, largest;

    printf("Enter the number of elements (1-100): ");
    scanf("%d", &n);

    printf("Enter %d elements:\n", n);
    for (i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }

    largest = arr[0]; // Assume first element is largest

    for (i = 1; i < n; i++) {
        if (arr[i] > largest) {
            largest = arr[i];
        }
    }

    printf("The largest element in the array is: %d\n", largest);
    return 0;
}

28. C program to implement the Linear Search algorithm

#include <stdio.h>

int linearSearch(int arr[], int size, int key) {
    for (int i = 0; i < size; i++) {
        if (arr[i] == key) {
            return i; // Return index if found
        }
    }
    return -1; // Return -1 if not found
}

int main() {
    int arr[] = {10, 2, 8, 5, 17};
    int n = sizeof(arr) / sizeof(arr[0]);
    int key = 8;
    int result = linearSearch(arr, n, key);

    if (result == -1) {
        printf("Element not found in the array.\n");
    } else {
        printf("Element found at index: %d\n", result);
    }
    return 0;
}

29. What is recursion? Compare with iteration.

Recursion is a programming technique where a function calls itself to solve a problem by breaking it down into smaller, identical sub-problems. Every recursive function needs a base case to stop the recursion and a recursive step where it calls itself.

Feature Recursion Iteration (Loops)
Mechanism A function calls itself. A block of code is repeated using `for`, `while`, etc.
Termination Requires a base case. Loop condition becomes false.
Memory Usage Uses more memory (call stack). Can cause stack overflow. More memory-efficient.
Code Complexity Can be more elegant for problems with a recursive structure (e.g., tree traversal). Can be more verbose for recursive problems but simpler for linear tasks.

30. Explain the working of the Bubble Sort algorithm

Bubble Sort is a simple sorting algorithm that repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. In each pass, the largest unsorted element "bubbles up" to its correct position.

Example: Sorting `[5, 1, 4, 2, 8]`

  • Pass 1: [5, 1, 4, 2, 8] → [1, 5, 4, 2, 8] → [1, 4, 5, 2, 8] → [1, 4, 2, 5, 8]. (8 is sorted)
  • Pass 2: [1, 4, 2, 5, 8] → [1, 2, 4, 5, 8]. (5 is sorted)
  • Pass 3: [1, 2, 4, 5, 8]. No swaps. (4 is sorted)
  • Pass 4: [1, 2, 4, 5, 8]. No swaps. (2 is sorted)

The final sorted array is `[1, 2, 4, 5, 8]`.

31. Why is Binary Search more efficient than Linear Search?

Binary search is significantly more efficient for large, sorted datasets because it follows a "divide and conquer" strategy.

  • Linear Search: Checks every element one by one. Time complexity is O(n). For 1,000,000 elements, it could take up to 1,000,000 comparisons.
  • Binary Search: Halves the search space with each comparison. Time complexity is O(log n). For 1,000,000 elements, it takes at most ~20 comparisons.

The key trade-off is that Binary Search requires the data to be sorted beforehand, while Linear Search does not.

32. Compare character arrays and strings. Program to concatenate without `strcat()`

In C, a "string" is a special type of character array: one that is terminated by a null character (`\0`). This null terminator is crucial for standard library functions (`strlen`, `strcpy`, etc.) to know where the string ends.

Program to Concatenate Strings Manually

#include <stdio.h>

int main() {
    char str1[50] = "Hello, ";
    char str2[] = "World!";
    int i, j;

    // Find the end of the first string
    for (i = 0; str1[i] != '\0'; i++);

    // Copy the second string to the end of the first
    for (j = 0; str2[j] != '\0'; j++, i++) {
        str1[i] = str2[j];
    }

    // Add the null terminator
    str1[i] = '\0';

    printf("Concatenated String: %s\n", str1);
    return 0;
}

33. Differentiate between call by value and call by reference

Call by Value: A copy of the argument's value is passed to the function. Changes made to the parameter inside the function do not affect the original variable.

Call by Reference (achieved with pointers in C): The memory address of the argument is passed. Changes made inside the function (by dereferencing the pointer) affect the original variable.

Program to Demonstrate Swapping

#include <stdio.h>

// Call by reference using pointers
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 10, y = 20;
    printf("Before swap: x = %d, y = %d\n", x, y);
    swap(&x, &y); // Pass addresses of x and y
    printf("After swap: x = %d, y = %d\n", x, y);
    return 0;
}

34. Recursive function to find the Fibonacci series

The Fibonacci series is a sequence where each number is the sum of the two preceding ones, starting from 0 and 1. A recursive solution directly models this definition.

#include <stdio.h>

long long fibonacci(int n) {
    // Base cases
    if (n == 0) return 0;
    if (n == 1) return 1;
    // Recursive step
    return fibonacci(n - 1) + fibonacci(n - 2);
}

int main() {
    int terms = 10;
    printf("Fibonacci Series for %d terms:\n", terms);
    for (int i = 0; i < terms; i++) {
        printf("%lld ", fibonacci(i));
    }
    printf("\n");
    return 0;
}

How it works: The function repeatedly calls itself, breaking down the problem (e.g., `fib(4)`) into smaller pieces (`fib(3) + fib(2)`), until it hits the base cases (`fib(1)` or `fib(0)`). The results are then passed back up the call stack to compute the final answer.

35. What are Built-in Library Functions? How are Arrays Passed to Functions?

Built-in (Standard Library) Functions

These are pre-written, optimized functions provided by the C Standard Library to perform common tasks. You include header files like `<stdio.h>`, `<string.h>`, and `<math.h>` to use them.

  • I/O (`<stdio.h>`): `printf()`, `scanf()`
  • String (`<string.h>`): `strlen()`, `strcpy()`
  • Math (`<math.h>`): `sqrt()`, `pow()`

How Arrays are Passed to Functions

In C, arrays are always passed by reference (or more accurately, by address). This means when you pass an array to a function, you are passing a pointer to its first element. The function does not get a copy of the array.

Key Implication: Any modifications made to the array's elements inside the function will affect the original array in the calling scope.

36 & 37. C Program for Student Marks Analysis

This program accepts marks for N students, finds the highest and lowest marks, sorts the marks in ascending order using Bubble Sort, and searches for a specific mark using Binary Search.

#include <stdio.h>
#include <limits.h> // For INT_MIN and INT_MAX

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

void findMinMax(int arr[], int size, int *min_mark, int *max_mark) {
    *min_mark = INT_MAX;
    *max_mark = INT_MIN;
    for (int i = 0; i < size; i++) {
        if (arr[i] < *min_mark) *min_mark = arr[i];
        if (arr[i] > *max_mark) *max_mark = arr[i];
    }
}

void bubbleSort(int arr[], int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int binarySearch(int arr[], int size, int key) {
    int low = 0, high = size - 1;
    while (low <= high) {
        int mid = low + (high - low) / 2;
        if (arr[mid] == key) return mid;
        if (arr[mid] < key) low = mid + 1;
        else high = mid - 1;
    }
    return -1;
}

int main() {
    int N, marks[100], min_mark, max_mark, search_mark, found_index;

    printf("Enter the number of students (N, max 100): ");
    scanf("%d", &N);

    printf("Enter marks for %d students:\n", N);
    for (int i = 0; i < N; i++) {
        scanf("%d", &marks[i]);
    }

    printf("\nOriginal Marks: ");
    printArray(marks, N);

    findMinMax(marks, N, &min_mark, &max_mark);
    printf("Highest Mark: %d\n", max_mark);
    printf("Lowest Mark: %d\n", min_mark);

    printf("\nSorting marks...\n");
    bubbleSort(marks, N);
    printf("Sorted Marks: ");
    printArray(marks, N);

    printf("\nEnter a mark to search for: ");
    scanf("%d", &search_mark);
    found_index = binarySearch(marks, N, search_mark);

    if (found_index != -1) {
        printf("Mark %d found at sorted index %d.\n", search_mark, found_index);
    } else {
        printf("Mark %d not found.\n", search_mark);
    }
    return 0;
}

38. What is a structure in C? How is it different from an array?

A structure (struct) in C is a user-defined data type that groups items of different data types under a single name. An array groups items of the same data type.

Feature Structure (struct) Array ([])
Data Types Can group different (heterogeneous) data types. Can group only the same (homogeneous) data type.
Element Identification Members are identified by names (e.g., student.name). Elements are identified by numerical indices (e.g., scores[0]).
Purpose To represent a single, complex entity with varied attributes. To store a collection of similar items.

39. Differentiate between `struct` and `union` in C

The key difference is memory allocation. A struct allocates memory for all its members. A union allocates memory only for its largest member, and all members share that same memory space.

Feature struct union
Memory Allocation Allocates memory for all members. Size is sum of member sizes (+ padding). Allocates memory for the largest member only. Size is size of largest member.
Member Storage Each member has its own unique memory location. All members share the same memory location.
Simultaneous Access All members can be accessed simultaneously. Only one member can be actively used at any given time.

40. File Opening Modes in C

When opening a file with fopen(), you specify a mode string:

  • "r" (Read): Opens an existing file for reading. File pointer starts at the beginning. Returns NULL if file doesn't exist.
  • "w" (Write): Opens a file for writing. Creates a new file or truncates (deletes content of) an existing file.
  • "a" (Append): Opens a file for writing. Creates a new file if it doesn't exist. File pointer starts at the end of the file to add new content.
  • "r+": Opens an existing file for both reading and writing.
  • "w+": Opens a file for both reading and writing, but truncates it first.
  • "a+": Opens a file for reading and appending.

41. C Program to Use a Student Structure

#include <stdio.h>
#include <string.h>

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

int main() {
    struct Student student1;

    printf("Enter student's Name: ");
    fgets(student1.name, sizeof(student1.name), stdin);
    student1.name[strcspn(student1.name, "\n")] = '\0'; // Remove newline

    printf("Enter student's Roll Number: ");
    scanf("%d", &student1.roll_no);

    printf("Enter student's Marks: ");
    scanf("%f", &student1.marks);

    printf("\n--- Student Details ---\n");
    printf("Name: %s\n", student1.name);
    printf("Roll Number: %d\n", student1.roll_no);
    printf("Marks: %.2f\n", student1.marks);

    return 0;
}

42. C Program to Create and Write to a File

#include <stdio.h>

int main() {
    FILE *fptr;
    char file_name[] = "my_output_file.txt";
    char content[] = "Hello from C programming!";

    // Open the file in write mode ("w")
    fptr = fopen(file_name, "w");

    if (fptr == NULL) {
        printf("Error: Could not create the file '%s'.\n", file_name);
        return 1;
    }

    // Write the string to the file
    fprintf(fptr, "%s\n", content);

    // Close the file to save changes
    fclose(fptr);

    printf("Successfully wrote to '%s'.\n", file_name);
    return 0;
}

43. C Program: Struct vs. Union Memory Allocation

This program demonstrates that a struct's size is the sum of its members (plus padding), while a union's size is that of its largest member.

#include <stdio.h>

struct MyStruct {
    int i;    // 4 bytes
    float f;  // 4 bytes
    char c;   // 1 byte
};

union MyUnion {
    int i;
    float f;
    char c;
};

int main() {
    printf("--- STRUCT ---\n");
    printf("Total size of MyStruct: %zu bytes\n", sizeof(struct MyStruct));
    
    printf("\n--- UNION ---\n");
    printf("Total size of MyUnion: %zu bytes\n", sizeof(union MyUnion));

    return 0;
}

44. Difference Between "w" (Write) and "a" (Append) File Modes

"w" (Write mode): If the file exists, its contents are deleted before writing. If it doesn't exist, it's created. Use this to overwrite a file.

"a" (Append mode): If the file exists, new data is added to the end of the file, preserving existing content. If it doesn't exist, it's created. Use this for logging or adding records.

45. Union in C: Applications, Advantages, and Disadvantages

Applications/Need

  • Memory Optimization: When only one of several data members is needed at any time.
  • Variant Records: Creating a structure that can hold different types of data in the same field, often using a "tag" to identify the current type.
  • Type Punning: Interpreting the same block of memory as different data types for low-level programming.

Advantages

  • Memory efficient.
  • Flexible for handling varied data types.

Disadvantages

  • Not type-safe; programmer must track the active member.
  • Only one member can hold a value at a time.
  • Can lead to complex and hard-to-debug code.

46. C Program: Storing Records of 5 Students in a Struct Array

#include <stdio.h>
#include <string.h>

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

int main() {
    struct Student students[5];
    int i;

    printf("--- Enter Details for 5 Students ---\n");
    for (i = 0; i < 5; i++) {
        printf("\nStudent %d\n", i + 1);
        printf("Name: ");
        // fgets is safer than gets
        fgets(students[i].name, sizeof(students[i].name), stdin);
        students[i].name[strcspn(students[i].name, "\n")] = '\0';
        
        printf("Roll Number: ");
        scanf("%d", &students[i].roll_no);
        
        printf("Marks: ");
        scanf("%f", &students[i].marks);

        // Consume leftover newline for the next fgets
        while (getchar() != '\n'); 
    }

    printf("\n--- Displaying Records ---\n");
    for (i = 0; i < 5; i++) {
        printf("\nStudent %d:\n", i + 1);
        printf("Name: %s\n", students[i].name);
        printf("Roll Number: %d\n", students[i].roll_no);
        printf("Marks: %.2f\n", students[i].marks);
    }
    return 0;
}

47. Nested Structures in C

Nested structures occur when one structure is a member of another. This is useful for organizing complex data, like an employee record that includes a joining date.

#include <stdio.h>

// Inner structure
struct Date {
    int day;
    int month;
    int year;
};

// Outer structure containing the inner one
struct Employee {
    char name[50];
    int employee_id;
    struct Date joining_date; // Nested structure
};

int main() {
    struct Employee emp1;
    
    // Assigning values
    strcpy(emp1.name, "John Doe");
    emp1.employee_id = 101;
    emp1.joining_date.day = 25;   // Accessing nested member
    emp1.joining_date.month = 10;
    emp1.joining_date.year = 2023;

    printf("Employee: %s (ID: %d)\n", emp1.name, emp1.employee_id);
    printf("Joining Date: %02d/%02d/%d\n", emp1.joining_date.day, emp1.joining_date.month, emp1.joining_date.year);

    return 0;
}

48. C Program: Read Student Records from a File and Filter

This program reads student records (Name, Roll, Marks) from a text file and displays only those students who scored more than 75 marks.

#include <stdio.h>

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

int main() {
    FILE *fptr;
    char filename[] = "student_records.txt";
    struct Student s;

    // For demonstration, create a dummy file
    fptr = fopen(filename, "w");
    fprintf(fptr, "Alice 101 88.5\nBob 102 65.0\nCharlie 103 90.0\n");
    fclose(fptr);

    // Open the file for reading
    fptr = fopen(filename, "r");
    if (fptr == NULL) {
        printf("Error opening file.\n");
        return 1;
    }

    printf("--- Students with marks > 75 ---\n");
    // Read records until end of file
    while (fscanf(fptr, "%s %d %f", s.name, &s.roll_no, &s.marks) == 3) {
        if (s.marks > 75.0) {
            printf("Name: %s, Roll: %d, Marks: %.2f\n", s.name, s.roll_no, s.marks);
        }
    }

    fclose(fptr);
    return 0;
}

49. C Program: Append User Input to a File

This program takes user input (Name, Age, City), appends it to a file named `user_data.txt`, and then reads and displays the entire file's contents.

#include <stdio.h>
#include <string.h>

int main() {
    FILE *fptr;
    char filename[] = "user_data.txt";
    char name[50], city[50], buffer[200];
    int age;

    // Part 1: Get input and append to file
    printf("Enter Name: ");
    fgets(name, sizeof(name), stdin);
    name[strcspn(name, "\n")] = '\0'; // Remove newline

    printf("Enter Age: ");
    scanf("%d", &age);
    
    while (getchar() != '\n'); // Clear buffer

    printf("Enter City: ");
    fgets(city, sizeof(city), stdin);
    city[strcspn(city, "\n")] = '\0';

    fptr = fopen(filename, "a"); // "a" for append
    if (fptr == NULL) return 1;
    fprintf(fptr, "Name: %s, Age: %d, City: %s\n", name, age, city);
    fclose(fptr);
    printf("\nDetails added to %s.\n\n", filename);

    // Part 2: Read and display file
    printf("--- Contents of %s ---\n", filename);
    fptr = fopen(filename, "r");
    if (fptr == NULL) return 1;
    while (fgets(buffer, sizeof(buffer), fptr) != NULL) {
        printf("%s", buffer);
    }
    fclose(fptr);

    return 0;
}

52. Flowcharts for Area of Rectangle and Circle

Area of Rectangle

Start ↓ Read length 'l' ↓ Read breadth 'b' ↓ Calculate area = l * b ↓ Print area ↓ End

Area of Circle

Start ↓ Read radius 'r' ↓ Calculate area = 3.14 * r * r ↓ Print area ↓ End

53. Number System Conversions

(a) Binary 10110.1100 to Decimal

For the integer part (10110): (1×16) + (0×8) + (1×4) + (1×2) + (0×1) = 16 + 4 + 2 = 22.

For the fractional part (.1100): (1×0.5) + (1×0.25) + (0×0.125) + (0×0.0625) = 0.5 + 0.25 = 0.75.

Result: 22 + 0.75 = 22.7510

(b) Decimal 47 to Hexadecimal

Divide 47 by 16: 47 / 16 = 2 with a remainder of 15 (which is 'F' in hex).

Divide 2 by 16: 2 / 16 = 0 with a remainder of 2.

Read remainders from bottom to top: 2F16

55. Variables and Storage Classes in C

A variable is a named storage location in memory that holds a value which can change during program execution.

A variable's storage class determines its scope (where it's accessible), lifetime (how long it exists), and default initial value.

  • auto: The default for local variables. They exist only within the block they are declared in. Stored on the stack.
  • register: A hint to the compiler to store the variable in a CPU register for faster access. Cannot have its address taken.
  • static: A static variable's lifetime is the entire program execution. It retains its value between function calls. Initialized only once.
  • extern: Declares a global variable that is defined in another source file, telling the compiler that it exists elsewhere.

56. Nested `if` Statements

A nested `if` statement is an `if` statement that is the target of another `if` or `else`. They are used to test for multiple conditions where one decision depends on another.

Program: Greatest of Three Numbers

#include <stdio.h>

int main() {
    int n1 = 10, n2 = 25, n3 = 15;
    
    if (n1 >= n2) {
        if (n1 >= n3)
            printf("%d is the largest.\n", n1);
        else
            printf("%d is the largest.\n", n3);
    } else {
        if (n2 >= n3)
            printf("%d is the largest.\n", n2);
        else
            printf("%d is the largest.\n", n3);
    }
    return 0;
}

57. How a C Program is Executed

The execution of a C program is a multi-stage process:

  1. Writing (Editor): You write source code in a text file (e.g., `program.c`).
  2. Preprocessing: The preprocessor handles directives like `#include` and `#define`, creating an expanded source file.
  3. Compilation: The compiler translates the expanded source code into assembly language, then into a machine-code object file (`.o` or `.obj`).
  4. Linking: The linker combines your object file(s) with code from standard libraries (like for `printf`) to create a single, executable file (`.exe` or `a.out`).
  5. Loading & Execution: The operating system's loader loads the executable into memory (RAM), and the CPU begins executing the instructions from the `main()` function.

58. Entry-Controlled vs. Exit-Controlled Loops

Feature Entry-Controlled Loop (`for`, `while`) Exit-Controlled Loop (`do-while`)
Condition Check Condition is checked before the loop body is executed. Condition is checked after the loop body is executed.
Execution Guarantee The loop body may not execute even once. The loop body is guaranteed to execute at least once.

A count-controlled loop (`for`) runs a fixed number of times. A condition-controlled loop (`while`, `do-while`) runs as long as a condition is true.

59. Two-Way Selection Statements (`if`, `if-else`)

A two-way selection statement provides two possible paths of execution based on a condition.

  • `if`: A single-way selection. Executes a block if the condition is true, otherwise does nothing.
  • `if-else`: A true two-way selection. Executes one block if the condition is true, and a different block if false.
  • Cascaded `if-else if-else`: A multi-way selection. Checks a series of conditions and executes the block for the first true condition found.

60. Difference Between `=` (Assignment) and `==` (Equality)

This is a fundamental concept and a common source of bugs.

  • `=` (Assignment Operator): Assigns the value on the right to the variable on the left. E.g., x = 5; puts the value 5 into `x`.
  • `==` (Equality Operator): Compares the values on both sides. It returns `1` (true) if they are equal and `0` (false) if they are not. E.g., if (x == 5) checks if `x` holds the value 5.

61. `switch` Statement with a Menu-Based Program

The `switch` statement selects one of many code blocks to be executed based on an integer or character expression. It is ideal for menu-driven programs.

#include <stdio.h>

void displayMenu() {
    printf("\n1. Add\n2. Subtract\n3. Exit\n");
    printf("Enter choice: ");
}

int main() {
    int choice;
    displayMenu();
    scanf("%d", &choice);

    switch (choice) {
        case 1:
            printf("Addition selected.\n");
            break; // break is crucial
        case 2:
            printf("Subtraction selected.\n");
            break;
        case 3:
            printf("Exiting.\n");
            break;
        default:
            printf("Invalid choice.\n");
    }
    return 0;
}

62. C Program: Check Number Properties

This program checks if a user-entered number is Even/Odd, Positive/Negative/Zero, and Divisible by 5.

#include <stdio.h>

int main() {
    int number;
    printf("Enter an integer: ");
    scanf("%d", &number);

    // Even or Odd
    if (number % 2 == 0) printf("%d is Even.\n", number);
    else printf("%d is Odd.\n", number);

    // Positive, Negative, or Zero
    if (number > 0) printf("%d is Positive.\n", number);
    else if (number < 0) printf("%d is Negative.\n", number);
    else printf("The number is Zero.\n");

    // Divisible by 5
    if (number % 5 == 0) printf("%d is divisible by 5.\n", number);
    else printf("%d is NOT divisible by 5.\n", number);
    
    return 0;
}

63. C Program: Generating Patterns with Nested Loops

Right-Angled Triangle Pattern

#include <stdio.h>

int main() {
    int n = 5;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

Floyd's Triangle Pattern

#include <stdio.h>

int main() {
    int n = 5, num = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            printf("%d ", num++);
        }
        printf("\n");
    }
    return 0;
}

64. C Program: Menu-Driven Calculator with `switch`

#include <stdio.h>

int main() {
    int choice;
    double n1, n2;
    printf("1.Add 2.Sub 3.Mul 4.Div\nEnter choice: ");
    scanf("%d", &choice);
    printf("Enter two numbers: ");
    scanf("%lf %lf", &n1, &n2);

    switch (choice) {
        case 1: printf("%.2lf + %.2lf = %.2lf\n", n1, n2, n1 + n2); break;
        case 2: printf("%.2lf - %.2lf = %.2lf\n", n1, n2, n1 - n2); break;
        case 3: printf("%.2lf * %.2lf = %.2lf\n", n1, n2, n1 * n2); break;
        case 4: 
            if (n2 != 0) printf("%.2lf / %.2lf = %.2lf\n", n1, n2, n1 / n2);
            else printf("Error: Division by zero.\n");
            break;
        default: printf("Invalid choice.\n");
    }
    return 0;
}

66. C Program: String Operations

Demonstrates `strlen`, `strcmp`, `strncpy`, converting to lowercase, and reversing a string.

#include <stdio.h>
#include <string.h>
#include <ctype.h>

void stringReverse(char *str) {
    int len = strlen(str);
    for (int i = 0, j = len - 1; i < j; i++, j--) {
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;
    }
}

int main() {
    char str1[] = "Hello";
    char str2[] = "World";
    char copy[50];

    // Length
    printf("Length of '%s' is %zu\n", str1, strlen(str1));

    // Comparison
    printf("Comparison of '%s' and '%s': %d\n", str1, str2, strcmp(str1, str2));

    // Partial Copy
    strncpy(copy, str1, 3);
    copy[3] = '\0'; // Manual null-termination
    printf("First 3 chars of '%s' are '%s'\n", str1, copy);

    // Reverse
    stringReverse(str1);
    printf("Reversed string: %s\n", str1);

    return 0;
}

67. Nested Loops in Matrix Operations (Transpose)

Nested loops are essential for matrix operations. The outer loop iterates through rows, and the inner loop iterates through columns. For a transpose, you swap the row and column indices.

#include <stdio.h>

int main() {
    int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int transpose[3][2];
    int i, j;

    // Calculate transpose
    for (i = 0; i < 2; i++) {
        for (j = 0; j < 3; j++) {
            transpose[j][i] = matrix[i][j];
        }
    }

    // Display transpose
    printf("Transposed Matrix:\n");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 2; j++) {
            printf("%d ", transpose[i][j]);
        }
        printf("\n");
    }
    return 0;
}

68. Bubble Sort Algorithm

Bubble Sort repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. In each pass, the largest unsorted element "bubbles up" to its correct position.

Computation: Sorting `[90, 50, 70, 10, 60, 30]`

  • Pass 1: [50, 70, 10, 60, 30, 90]
  • Pass 2: [50, 10, 60, 30, 70, 90]
  • Pass 3: [10, 50, 30, 60, 70, 90]
  • Pass 4: [10, 30, 50, 60, 70, 90]
  • Pass 5: [10, 30, 50, 60, 70, 90]

Final Sorted Array: [10, 30, 50, 60, 70, 90]

69. Selection Sort Algorithm

Selection Sort works by repeatedly finding the minimum element from the unsorted part of the list and putting it at the beginning of the unsorted part.

#include <stdio.h>

void selectionSort(int arr[], int n) {
    int i, j, min_idx, temp;
    for (i = 0; i < n - 1; i++) {
        min_idx = i;
        for (j = i + 1; j < n; j++) {
            if (arr[j] < arr[min_idx])
                min_idx = j;
        }
        // Swap the found minimum element with the first element
        temp = arr[min_idx];
        arr[min_idx] = arr[i];
        arr[i] = temp;
    }
}

int main() {
    int arr[] = {90, 50, 70, 10, 60, 30};
    int n = sizeof(arr) / sizeof(arr[0]);
    selectionSort(arr, n);
    printf("Sorted array: ");
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

70. Linear Search vs. Binary Search

Linear search checks every element sequentially (O(n) time), while binary search repeatedly divides a sorted array in half (O(log n) time), making it much faster for large datasets.

#include <stdio.h>

// Linear Search: works on any array
int linearSearch(int arr[], int n, int target) {
    for (int i = 0; i < n; i++) {
        if (arr[i] == target) return i;
    }
    return -1;
}

int main() {
    int arr[] = {90, 50, 70, 10, 60, 30};
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 60;
    int result = linearSearch(arr, n, target);
    if (result != -1) printf("Found %d at index %d\n", target, result);
    else printf("%d not found.\n", target);
    return 0;
}

71. Functions and Recursion

A function is a block of organized, reusable code that performs a single, related action. It provides modularity and reusability.

Recursion is a technique where a function calls itself to solve a problem. It requires a base case to stop the recursion and a recursive step that moves closer to the base case.

Example: Factorial using Recursion

#include <stdio.h>

long long factorial(int n) {
    if (n == 0) // Base case
        return 1;
    else // Recursive step
        return n * factorial(n - 1);
}

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

72. Recursion vs. Iteration

Both are used for repetitive tasks. Recursion uses function calls, while iteration uses loops.

Feature Recursion Iteration
Approach Function calls itself. Uses loops (`for`, `while`).
Memory Higher (uses call stack). Risk of stack overflow. Lower (constant memory usage).
Speed Slower due to function call overhead. Faster.
Code Size Often more concise and elegant. Can be more verbose.