MAKAUT Solved Paper · UPID : 002008

Programming for Problem Solving

B.Tech Even Semester Examination 2024–2025 · Paper Code: ESCS201 · Full Marks: 70

Group-A: Very Short Answer Type Questions Answer Any 10 · [ 1 x 10 = 10 Marks ]

1. (I) Point out the difference between strcmp() and strncmp(). [ 1 Mark ]

Answer: Both functions are defined in <string.h> and compare two null-terminated strings lexicographically (character by character using ASCII values):

  • strcmp(s1, s2): Compares the entire string s1 against s2 until a mismatch is found or the null terminator ('\0') is reached in both strings.
  • strncmp(s1, s2, n): Compares at most the first n characters of s1 and s2. It stops comparing after n characters even if null terminators haven't been reached.
strcmp("apple", "approx"); // Returns negative (< 0) because 'l' < 'r' strncmp("apple", "approx", 2); // Returns 0 because first 2 characters ("ap") match exactly!

1. (II) What do you mean by pointer arithmetic in C? [ 1 Mark ]

Answer: Pointer arithmetic refers to performing arithmetic operations (specifically addition +, subtraction -, increment ++, and decrement --) on memory addresses stored in pointer variables.

Unlike regular integer arithmetic, when a pointer ptr of type T* is incremented by 1 (ptr++), the memory address increases by sizeof(T) bytes (the byte size of the data type it points to), pointing directly to the very next memory element of that type.

int *p = (int*)0x1000; // Suppose p holds address 4096 (0x1000) p++; // Address becomes 4100 (4096 + 1 * sizeof(int) = 4096 + 4)

1. (III) Write the main differences between Structure and Union? [ 1 Mark ]

Feature Structure (struct) Union (union)
Memory Allocation Each member gets its own separate memory space. Total size is the sum of all members (plus padding). All members share the same single memory location. Total size is equal to the size of the largest member.
Member Access All members can be accessed and manipulated simultaneously without affecting others. Only one member can hold a meaningful value at a time; modifying one member overwrites the value of others.

1. (IV) Find the correct output:
#include<stdio.h>
main() {
  for(int i=0; i<=5;i++);
  { printf("%d",i); }
}
[ 1 Mark ]

Answer: Compilation Error: 'i' undeclared (in ISO C99 / C11 standards).

Detailed Explanation:
1. Notice the semicolon ; immediately after the for statement: for(int i=0; i<=5; i++);. This makes the loop body an empty null statement.
2. In modern C (C99 and later), a variable declared inside the initial clause of a for loop (int i=0) has scope strictly limited to that loop statement.
3. When the code attempts to print i in the block after the loop, i is out of scope and no longer exists in memory, resulting in a compile-time error: error: 'i' undeclared (first use in this function).
Note: If int i; had been declared outside/before the loop, the output would be 6 because the empty loop terminates when i increments to 6.

1. (V) What is the main difference between call by value and call by address in C? [ 1 Mark ]

Answer:

  • Call by Value: A duplicate copy of the actual arguments is passed to the function parameters. Any modifications made inside the called function occur only on local copies and do not affect the original variables in the caller function.
  • Call by Address (Reference via Pointers): The memory addresses of the actual variables are passed using pointers. Therefore, dereferencing and modifying the parameters inside the called function directly alters the original variables in the caller's memory scope.

1. (VI) Why is scope of variable necessary in function? [ 1 Mark ]

Answer: Variable scope is necessary for the following critical reasons:

  • Memory Efficiency: Local variables are automatically created on the call stack when a function is invoked and destroyed immediately upon function exit, preventing memory wastage.
  • Encapsulation & Data Hiding: It prevents unintended side effects and data corruption from other functions or parts of the program that might accidentally modify variables with the same name.
  • Name Reusability: Programmers can safely use common, readable variable names like i, count, or temp across different functions without naming collisions.

1. (VII) What will be the output of the above code?
#include<stdio.h>
main() {
  int i=3;
  i=i++;
  printf("%d",i);
}
[ 1 Mark ]

Answer: Undefined Behavior (UB) in ANSI/ISO C. (Depending on compiler version, GCC/Clang typically output 3 or 4).

Why is it Undefined Behavior?
According to the ISO C Standard, modifying the same scalar variable (here, i) more than once between two consecutive sequence points (or modifying it while accessing its prior value for an assignment) violates sequence point rules. In i = i++, i is both modified by the post-increment operator ++ and modified by the assignment operator = without an intervening sequence point. Thus, the compiler is free to execute the assignment before or after the increment, making the output compiler-dependent.

1. (VIII) Why do we use header files? [ 1 Mark ]

Answer: Header files (e.g., <stdio.h>, <stdlib.h>, <math.h>) serve as interfaces that declare function prototypes, macro definitions (#define), user-defined data types (struct, enum), and global variables.

We use them to enable modular programming and code reusability—allowing multiple source files to share standard library capabilities and custom function declarations without rewriting their declarations or implementations from scratch in every file.

1. (IX) Write the output of the following Code:
#include<stdio.h>
int main() {
  char x;
  x = 'a';
  printf("%d\n", x);
}
[ 1 Mark ]

Console Output 97

Explanation: In C, characters are stored internally in memory as integers representing their ASCII code values. The format specifier %d instructs printf to display the integer representation of the character variable x. The ASCII decimal integer value of the lowercase letter 'a' is exactly 97.

1. (X) Define recursion. [ 1 Mark ]

Answer: Recursion is a programming technique where a function calls itself directly or indirectly to solve a larger problem by breaking it down into smaller, self-similar sub-problems.

A valid recursive function must always contain two essential components:
1. Base Case (Terminating Condition): A simple condition where the problem is solved directly without further recursive calls, preventing infinite recursion and stack overflow.
2. Recursive Step: The function calling itself with modified parameters that progressively converge toward the base case.

1. (XI) Arrangement of playing cards is an example of which sorting technique? [ 1 Mark ]

Answer: Insertion Sort.

Explanation: When a player arranges playing cards in their hand, they pick one card at a time from the unsorted table/pile and insert it into its correct sequential position among the cards already sorted in their left hand. This physical action mirrors the exact algorithm of Insertion Sort!

1. (XII) Explain Ackerman function. [ 1 Mark ]

Answer: The Ackermann function \(A(m, n)\) is a classic example in computability theory of a recursive mathematical function that is totally computable but not primitive recursive because its value grows at an extraordinarily rapid rate—much faster than exponential or factorial functions.

For non-negative integers \(m\) and \(n\), it is formally defined by three recursive rules: \[ A(m, n) = \begin{cases} n + 1 & \text{if } m = 0 \\ A(m - 1, 1) & \text{if } m > 0 \text{ and } n = 0 \\ A(m - 1, A(m, n - 1)) & \text{if } m > 0 \text{ and } n > 0 \end{cases} \] Even for small inputs like \(A(4, 2)\), the numerical result is an integer with nearly 20,000 digits, causing deep call stacks in computers!

Group-B: Short Answer Type Questions Answer Any 3 · [ 5 x 3 = 15 Marks ]

2. Differentiate between the switch and nested-if statement in C with proper example. [ 5 Marks ]

Comparison Basis switch Statement nested-if (or if-else if ladder)
Expression Type Can only evaluate an expression that yields an integral or enumeration value (int, char). Cannot check floats or strings. Can evaluate any boolean expression, including relational comparisons, logical operators, floating-point tests, and string checks.
Condition Check Tests equality (==) only against constant case labels. Cannot test ranges (e.g., x > 10). Can test complex ranges, inequalities, and multiple compound conditions simultaneously using && and ||.
Execution & Jump Uses a jump table (in optimized compilers) to leap directly to the matching case label, offering \(O(1)\) execution time. Requires break to prevent fall-through. Evaluates conditions sequentially from top to bottom until a true condition is met, running in \(O(n)\) worst-case time. No fall-through occurs.

Code Comparison Example:

Using switch statement:
char grade = 'B'; switch(grade) { case 'A': printf("Excellent"); break; case 'B': printf("Good"); break; case 'C': printf("Average"); break; default: printf("Invalid"); }
Using nested-if statement:
int score = 85; if (score >= 90) { printf("Grade A"); } else if (score >= 80) { printf("Grade B"); // Range check! } else { printf("Grade C"); }

3. Write a C program to count the number of even and odd numbers from an 1-D array. [ 5 Marks ]

Algorithm / Logic: Traverse through each element of the 1-D array. For each element arr[i], check if the remainder when divided by 2 is zero (arr[i] % 2 == 0). If true, increment the even_count variable; otherwise, increment the odd_count variable.

#include <stdio.h> int main() { int n, i; int even_count = 0, odd_count = 0; // Input array size printf("Enter the number of elements in array: "); if (scanf("%d", &n) != 1 || n <= 0) { printf("Invalid array size!\n"); return 1; } int arr[n]; // C99 Variable Length Array (VLA) // Input array elements printf("Enter %d integers:\n", n); for (i = 0; i < n; i++) { scanf("%d", &arr[i]); // Check even or odd immediately during traversal if (arr[i] % 2 == 0) { even_count++; } else { odd_count++; } } // Output summary printf("\n--- Array Analysis Result ---\n"); printf("Total Elements : %d\n", n); printf("Even Numbers : %d\n", even_count); printf("Odd Numbers : %d\n", odd_count); return 0; }
Sample Input & Output Enter the number of elements in array: 6 Enter 6 integers: 12 17 24 39 40 55 --- Array Analysis Result --- Total Elements : 6 Even Numbers : 3 Odd Numbers : 3

4. Write a program in C to find the area and circumference of a circle using function. [ 5 Marks ]

Logic: We define two separate functions: calculateArea(double radius) returning \(\pi r^2\), and calculateCircumference(double radius) returning \(2\pi r\). We use the mathematical constant M_PI from <math.h> (or define it as 3.141592653589793).

#include <stdio.h> #define PI 3.14159265358979323846 // Function declarations (prototypes) double calculateArea(double radius); double calculateCircumference(double radius); int main() { double radius, area, circumference; printf("Enter the radius of the circle (in units): "); if (scanf("%lf", &radius) != 1 || radius < 0) { printf("Error: Please enter a valid non-negative radius value.\n"); return 1; } // Function calls area = calculateArea(radius); circumference = calculateCircumference(radius); // Display formatted results printf("\n=== Circle Measurements ===\n"); printf("Radius : %.4f units\n", radius); printf("Area : %.4f sq. units\n", area); printf("Circumference : %.4f units\n", circumference); return 0; } // Function to calculate area: A = π * r * r double calculateArea(double radius) { return PI * radius * radius; } // Function to calculate circumference: C = 2 * π * r double calculateCircumference(double radius) { return 2.0 * PI * radius; }
Sample Execution Enter the radius of the circle (in units): 5.0 === Circle Measurements === Radius : 5.0000 units Area : 78.5398 sq. units Circumference : 31.4159 units

5. Write a C program to find the length of an array using pointer arithmetic. [ 5 Marks ]

Pointer Arithmetic Principle: When an array is passed to a function or when we take the address of the array boundary, we can find the number of elements without using the standard counter loop or sizeof division by subtracting the starting memory pointer (&arr[0]) from the pointer pointing immediately after the last valid element (&arr[n] or using pointer traversal until a special sentinel token).

In standard C, the most idiomatic pointer arithmetic formula to compute array length when the array is within scope is: ptrdiff_t length = (&arr)[1] - arr; where (&arr)[1] is the memory address immediately after the whole array block!

#include <stdio.h> #include <stddef.h> // For ptrdiff_t int main() { int arr[] = {10, 25, 40, 55, 70, 85, 100, 115, 130}; // Method 1: Using Pointer Subtraction of Array Boundary Pointers // &arr points to the entire array block. (&arr + 1) points immediately after it. // Subtracting the start pointer (arr) from (&arr + 1) cast to (int*) yields exact length! int *start_ptr = arr; int *end_ptr = (int*)(&arr + 1); ptrdiff_t length = end_ptr - start_ptr; printf("--- Array Length via Pointer Arithmetic ---\n"); printf("Start Memory Address : %p\n", (void*)start_ptr); printf("End Memory Address : %p\n", (void*)end_ptr); printf("Byte Difference : %ld bytes\n", (long)((char*)end_ptr - (char*)start_ptr)); printf("Element Size : %zu bytes\n", sizeof(int)); printf("Calculated Length : %td elements\n", length); // Method 2: Demonstrating traversal using a pointer pointer until sentinel (if null-terminated) return 0; }
Sample Output --- Array Length via Pointer Arithmetic --- Start Memory Address : 0x7ffee2b8a710 End Memory Address : 0x7ffee2b8a734 Byte Difference : 36 bytes Element Size : 4 bytes Calculated Length : 9 elements

6. Write a C program to perform bit wise left shift operation on a number taken from the user. Write the output with an example. [ 5 Marks ]

Theory of Bitwise Left Shift (<<): The left shift operator num << k shifts all bits of the integer num to the left by k positions. The vacated bits on the right are filled with zeros. Mathematically, left shifting an integer by \(k\) positions is equivalent to multiplying the number by \(2^k\): \[ \text{Result} = \text{num} \times 2^k \]

#include <stdio.h> // Function to print 8-bit binary representation for clarity void printBinary8(unsigned char n) { for (int i = 7; i >= 0; i--) { printf("%d", (n >> i) & 1); if (i == 4) printf(" "); // Nibble separator } } int main() { unsigned int num, shift_bits, result; printf("Enter a positive integer value: "); scanf("%u", &num); printf("Enter number of positions to left shift (0-31): "); scanf("%u", &shift_bits); // Perform Bitwise Left Shift result = num << shift_bits; printf("\n=== Bitwise Left Shift Analysis ===\n"); printf("Original Number : %u (in decimal)\n", num); printf("Shift Positions : %u bits to the left (<< %u)\n", shift_bits, shift_bits); printf("Result Value : %u (in decimal)\n", result); printf("Math Check : %u * (2^%u) = %u\n", num, shift_bits, num * (1 << shift_bits)); printf("\nBinary Illustration (lower 8 bits):\n"); printf("Before Shift : "); printBinary8((unsigned char)num); printf(" (%u)\n", num); printf("After Shift : "); printBinary8((unsigned char)result); printf(" (%u)\n", result); return 0; }
Sample Output & Example Enter a positive integer value: 13 Enter number of positions to left shift (0-31): 2 === Bitwise Left Shift Analysis === Original Number : 13 (in decimal) Shift Positions : 2 bits to the left (<< 2) Result Value : 52 (in decimal) Math Check : 13 * (2^2) = 52 Binary Illustration (lower 8 bits): Before Shift : 0000 1101 (13) After Shift : 0011 0100 (52)
Group-C: Long Answer Type Questions Answer Any 3 · [ 15 x 3 = 45 Marks ]

7. (a) Draw a flowchart to evaluate factorial of a number.
(b) Write a C program to generate Fibonacci Series upto n-terms using loop.
(c) Explain preprocessor directive with suitable example.
[ 5 + 5 + 5 = 15 Marks ]

(a) Flowchart to Evaluate Factorial of a Number [5 Marks]:

The factorial of a non-negative integer \(n\), denoted by \(n!\), is the product of all positive integers less than or equal to \(n\). Below is the structured algorithm represented as a textual flowchart step diagram:

[ START ]
|
v
[ Input integer N ]
|
v
/ Is N < 0 ? \ ----( YES )----> [ Print "Factorial undefined for negative numbers" ] --> [ STOP ]
\ /
| ( NO )
v
[ Set FACT = 1, I = 1 ]
|
+-------------+
| |
v |
/ Is I <= N ? \ | (NO: Loop Ends)
\ / --+----------------------------------+
| ( YES ) |
v v
[ FACT = FACT * I ] [ Print FACT ]
| |
v v
[ I = I + 1 ] [ STOP ]
|
+-----( Jump back to condition I <= N )

(b) C Program to Generate Fibonacci Series upto n-terms using loop [5 Marks]:

The Fibonacci sequence begins with terms 0 and 1. Every subsequent term is the algebraic sum of the two preceding terms: \(F_n = F_{n-1} + F_{n-2}\).

#include <stdio.h> int main() { int n, i; unsigned long long t1 = 0, t2 = 1, nextTerm; printf("Enter the number of terms (n) for Fibonacci Series: "); if (scanf("%d", &n) != 1 || n <= 0) { printf("Please enter a positive integer greater than 0.\n"); return 1; } printf("\nFibonacci Series up to %d terms:\n", n); for (i = 1; i <= n; ++i) { if (i == 1) { printf("%llu", t1); continue; } if (i == 2) { printf(", %llu", t2); continue; } // Calculate next term nextTerm = t1 + t2; printf(", %llu", nextTerm); // Update variables for the next iteration t1 = t2; t2 = nextTerm; } printf("\n"); return 0; }
Sample Output Enter the number of terms (n) for Fibonacci Series: 10 Fibonacci Series up to 10 terms: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

(c) Preprocessor Directives Explained with Example [5 Marks]:

Definition: The C Preprocessor is a macro processor that transforms the source code automatically before the actual compiler translation phase begins. All preprocessor directives begin with the hash/pound symbol # and do not end with a semicolon.

Key Types of Directives:
1. File Inclusion (#include): Inserts the complete contents of another header file into the current source file (e.g., #include <stdio.h> or #include "myheader.h").
2. Macro Substitution (#define): Defines symbolic constants or parameterized macro functions.
3. Conditional Compilation (#ifdef, #ifndef, #if, #endif): Compiles or skips sections of code based on conditions, widely used for header guards.

// Example demonstrating preprocessor directives #include <stdio.h> // File inclusion directive #define PI 3.14159265 // Constant macro definition #define SQUARE(x) ((x) * (x)) // Function-like macro definition #define DEBUG 1 // Conditional flag int main() { double radius = 5.0; double area = PI * SQUARE(radius); // Preprocessor expands to: 3.14159265 * ((radius) * (radius)) printf("Area of circle: %.2f\n", area); #if DEBUG // This code block is only compiled if DEBUG is non-zero printf("[DEBUG MODE]: Macro SQUARE(5.0) expanded and evaluated successfully.\n"); #endif return 0; }

8. (a) Define a recursive function to calculate factorial of a number and call this function to calculate \(S = 1! + 2! + \dots + n!\), where n is user input.
(b) Write a C program to swap the content of two variables using Call by Value.
[ 8 + 7 = 15 Marks ]

(a) Recursive Factorial Sum Series \(S = 1! + 2! + \dots + n!\) [8 Marks]:

We implement a recursive function unsigned long long factorial(int k) where base case is k <= 1 returning 1, and recursive step returns k * factorial(k - 1). In main, we loop from 1 to \(n\) and accumulate the sum.

#include <stdio.h> // Recursive function prototype to calculate factorial unsigned long long factorial(int k); int main() { int n, i; unsigned long long sum = 0, currentFact; printf("Enter a positive integer value for n: "); if (scanf("%d", &n) != 1 || n < 1) { printf("Please enter a valid positive integer greater than 0.\n"); return 1; } printf("\nCalculating Series: S = "); for (i = 1; i <= n; i++) { currentFact = factorial(i); sum += currentFact; if (i == n) { printf("%d! ", i); } else { printf("%d! + ", i); } } printf("\n\n=== Final Result ===\n"); printf("Total Sum (S) of factorials from 1! to %d! = %llu\n", n, sum); return 0; } // Recursive function implementation unsigned long long factorial(int k) { // Base Case: 0! = 1 and 1! = 1 if (k <= 1) { return 1; } // Recursive Step: k! = k * (k - 1)! return k * factorial(k - 1); }
Sample Output Enter a positive integer value for n: 5 Calculating Series: S = 1! + 2! + 3! + 4! + 5! === Final Result === Total Sum (S) of factorials from 1! to 5! = 153 (Math verification: 1 + 2 + 6 + 24 + 120 = 153)

(b) Swapping Two Variables Using Call by Value [7 Marks]:

Important Conceptual Note for Examiners: In C, standard parameter passing is strictly call by value. When variables are passed by value to a function, the function receives independent copies. Therefore, swapping the parameters inside the function only swaps the local copies on the stack frame of the called function; it does not modify the original variables in the caller (e.g., main). To permanently swap variables in the caller, one must use pointers (Call by Address). Below, we write the program demonstrating Call by Value and print the values inside the function to prove how the local swap occurs!

#include <stdio.h> // Function prototype using Call by Value void swapByValue(int a, int b); int main() { int x = 100, y = 200; printf("=== Demonstration of Swap via Call by Value ===\n"); printf("[Main Function] Before calling swap : x = %d, y = %d\n", x, y); printf("Memory Addresses in Main : &x = %p, &y = %p\n\n", (void*)&x, (void*)&y); // Calling the function by value (copies of x and y are passed) swapByValue(x, y); // Notice that x and y in main remain unchanged! printf("\n[Main Function] After calling swap : x = %d, y = %d\n", x, y); printf("Conclusion: In Call by Value, changes inside the function do NOT affect caller variables!\n"); return 0; } // Function definition receiving arguments by value void swapByValue(int a, int b) { printf(" --> [Inside swapByValue] Before swap: a = %d, b = %d\n", a, b); printf(" --> Memory Addresses of copies : &a = %p, &b = %p\n", (void*)&a, (void*)&b); // Performing the swap on local copies using a temporary variable int temp = a; a = b; b = temp; printf(" --> [Inside swapByValue] AFTER SWAP : a = %d, b = %d (Successfully swapped locally!)\n", a, b); }
Console Output Demonstrating Call by Value Scope === Demonstration of Swap via Call by Value === [Main Function] Before calling swap : x = 100, y = 200 Memory Addresses in Main : &x = 0x7ffee1a2b804, &y = 0x7ffee1a2b800 --> [Inside swapByValue] Before swap: a = 100, b = 200 --> Memory Addresses of copies : &a = 0x7ffee1a2b7ec, &b = 0x7ffee1a2b7e8 --> [Inside swapByValue] AFTER SWAP : a = 200, b = 100 (Successfully swapped locally!) [Main Function] After calling swap : x = 100, y = 200 Conclusion: In Call by Value, changes inside the function do NOT affect caller variables!

9. (a) Write a C program to list all the prime numbers for a given range of numbers.
(b) Write a C program to check the entered character is a consonant or vowel. If it is not an alphabet return 'wrong input'.
[ 8 + 7 = 15 Marks ]

(a) Prime Numbers in a Given Range [8 Marks]:

A prime number is an integer greater than 1 that has no positive divisors other than 1 and itself. For each number \(N\) in the user-specified range \([L, R]\), we test divisibility from 2 up to \(\sqrt{N}\) (or up to \(N/2\)). If no divisor is found, the number is prime.

#include <stdio.h> #include <math.h> // Function to test if a number is prime (returns 1 if prime, 0 otherwise) int isPrime(int num) { if (num <= 1) return 0; // 0, 1, and negative numbers are not prime if (num == 2) return 1; // 2 is the only even prime number if (num % 2 == 0) return 0; // Exclude all other even numbers // Check odd divisors up to square root of num int limit = (int)sqrt(num); for (int i = 3; i <= limit; i += 2) { if (num % i == 0) { return 0; // Found a divisor, not prime } } return 1; } int main() { int start, end, count = 0; printf("Enter the starting number of range: "); scanf("%d", &start); printf("Enter the ending number of range: "); scanf("%d", &end); if (start > end) { int temp = start; start = end; end = temp; // Swap if entered out of order } printf("\nPrime numbers between %d and %d are:\n", start, end); for (int i = start; i <= end; i++) { if (isPrime(i)) { printf("%d ", i); count++; if (count % 10 == 0) printf("\n"); // Format 10 numbers per line } } printf("\n\nTotal prime numbers found in range: %d\n", count); return 0; }
Sample Output Enter the starting number of range: 10 Enter the ending number of range: 50 Prime numbers between 10 and 50 are: 11 13 17 19 23 29 31 37 41 43 47 Total prime numbers found in range: 11

(b) Consonant or Vowel Validation with 'wrong input' Check [7 Marks]:

We first check if the entered character is an alphabet using the standard library function isalpha(ch) from <ctype.h> (or manual ASCII range check: (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')). If it is not an alphabet, we output wrong input. If it is an alphabet, we convert it to lowercase using tolower(ch) and check against 'a', 'e', 'i', 'o', 'u'.

#include <stdio.h> #include <ctype.h> int main() { char ch, lower_ch; printf("Enter a single character to check: "); scanf(" %c", &ch); // Leading space in %c ignores any leftover newline/whitespace // Step 1: Check if the character is an English alphabet if (!isalpha(ch)) { printf("wrong input\n"); return 0; } // Step 2: Convert to lowercase for uniform vowel checking lower_ch = tolower(ch); // Step 3: Check if it matches any vowel if (lower_ch == 'a' || lower_ch == 'e' || lower_ch == 'i' || lower_ch == 'o' || lower_ch == 'u') { printf("The character '%c' is a VOWEL.\n", ch); } else { printf("The character '%c' is a CONSONANT.\n", ch); } return 0; }
Sample Execution Cases Case 1: Enter a single character to check: E The character 'E' is a VOWEL. Case 2: Enter a single character to check: z The character 'z' is a CONSONANT. Case 3: Enter a single character to check: 9 wrong input Case 4: Enter a single character to check: @ wrong input

10. (a) Describe string with example.
(b) How strings are represented in memory?
(c) Write a C program to check the entered string is a palindrome or not.
[ 5 + 4 + 6 = 15 Marks ]

(a) Description of String with Example [5 Marks]:

In C programming, a string is defined as a one-dimensional array of characters that is terminated by a special null character ('\0', whose ASCII value is 0). Unlike languages like Java or Python, C does not have a built-in primitive string data type; strings are manipulated as character arrays or character pointers.

// Two common ways to initialize a string in C: char str1[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // Explicit character array initialization char str2[] = "Hello"; // String literal (compiler appends '\0' automatically) printf("Message: %s\n", str2);

(b) How Strings are Represented in Memory [4 Marks]:

When a string is created, its characters are allocated in contiguous (sequential) memory addresses. Every individual character occupies exactly 1 byte of memory. The string must always conclude with the null terminator '\0' so that string-handling functions (like strlen, printf, strcpy) know exactly where the character sequence terminates.

For example, for the string literal "MAKAUT", if the starting memory address is 2000, the memory layout in RAM is:

Index str[0] str[1] str[2] str[3] str[4] str[5] str[6]
Character 'M' 'A' 'K' 'A' 'U' 'T' '\0'
ASCII Value 77 65 75 65 85 84 0
Memory Address 2000 2001 2002 2003 2004 2005 2006

(c) C Program to Check if String is Palindrome or Not [6 Marks]:

A string is a palindrome if it reads exactly the same backward as forward (e.g., "madam", "racecar", "level"). We use two indices: left = 0 and right = length - 1, comparing characters moving inward until they meet in the middle.

#include <stdio.h> #include <string.h> #include <ctype.h> int main() { char str[100]; int left = 0, right; int isPalindrome = 1; // Flag: assume true initially printf("Enter a string (up to 99 characters): "); scanf("%99s", str); // Reads a single word without spaces right = strlen(str) - 1; // Two-pointer comparison loop while (left < right) { // Case-insensitive comparison using tolower() if (tolower(str[left]) != tolower(str[right])) { isPalindrome = 0; // Mismatch found! break; } left++; right--; } printf("\n--- Palindrome Verification ---\n"); printf("Input String : \"%s\"\n", str); if (isPalindrome) { printf("Result : The entered string IS A PALINDROME.\n"); } else { printf("Result : The entered string is NOT a palindrome.\n"); } return 0; }
Sample Output Cases Case 1: Enter a string (up to 99 characters): Radar --- Palindrome Verification --- Input String : "Radar" Result : The entered string IS A PALINDROME. Case 2: Enter a string (up to 99 characters): Algorithm --- Palindrome Verification --- Input String : "Algorithm" Result : The entered string is NOT a palindrome.

11. (a) Create a recursive C function to find the GCD of two numbers.
(b) Write a C program to sort names of students in a class.
[ 5 + 10 = 15 Marks ]

(a) Recursive C Function for GCD of Two Numbers [5 Marks]:

The Greatest Common Divisor (GCD) or HCF of two positive integers can be computed efficiently using the Euclidean Algorithm: \[ \text{gcd}(a, b) = \begin{cases} a & \text{if } b = 0 \\ \text{gcd}(b, a \bmod b) & \text{if } b > 0 \end{cases} \]

#include <stdio.h> // Recursive function to calculate GCD using Euclidean algorithm int gcd(int a, int b) { // Base case: if remainder becomes 0, divisor 'a' is the GCD if (b == 0) { return a; } // Recursive step: gcd(b, a % b) return gcd(b, a % b); } int main() { int num1, num2; printf("Enter two positive integers separated by space: "); if (scanf("%d %d", &num1, &num2) != 2 || num1 <= 0 || num2 <= 0) { printf("Invalid input! Please enter positive integers.\n"); return 1; } int result = gcd(num1, num2); printf("GCD of %d and %d is = %d\n", num1, num2, result); return 0; }
Sample Output Enter two positive integers separated by space: 48 18 GCD of 48 and 18 is = 6

(b) C Program to Sort Names of Students in a Class [10 Marks]:

To store multiple student names, we use a 2-dimensional character array char names[N][MAX_LEN] (or an array of string pointers). To sort the names in alphabetical (lexicographical) order, we apply a sorting algorithm like Bubble Sort or Selection Sort, comparing adjacent names using strcmp() and swapping them using strcpy() when they are out of order.

#include <stdio.h> #include <string.h> #define MAX_STUDENTS 50 #define MAX_NAME_LEN 60 int main() { int n, i, j; char names[MAX_STUDENTS][MAX_NAME_LEN]; char temp[MAX_NAME_LEN]; printf("Enter the total number of students in class (max %d): ", MAX_STUDENTS); if (scanf("%d", &n) != 1 || n < 1 || n > MAX_STUDENTS) { printf("Invalid number of students!\n"); return 1; } // Clear input buffer before reading strings while (getchar() != '\n'); printf("\nEnter full names of %d students:\n", n); for (i = 0; i < n; i++) { printf("Student %d: ", i + 1); // Read string including spaces using fgets if (fgets(names[i], MAX_NAME_LEN, stdin) != NULL) { // Remove trailing newline character '\n' appended by fgets size_t len = strlen(names[i]); if (len > 0 && names[i][len - 1] == '\n') { names[i][len - 1] = '\0'; } } } // Alphabetical Sorting using Bubble Sort logic for (i = 0; i < n - 1; i++) { for (j = 0; j < n - i - 1; j++) { // If names[j] is lexicographically greater than names[j+1], swap them! if (strcmp(names[j], names[j + 1]) > 0) { strcpy(temp, names[j]); strcpy(names[j], names[j + 1]); strcpy(names[j + 1], temp); } } } // Output sorted names printf("\n=========================================\n"); printf(" Student Names in Alphabetical Order \n"); printf("=========================================\n"); for (i = 0; i < n; i++) { printf("%2d. %s\n", i + 1, names[i]); } printf("=========================================\n"); return 0; }
Sample Execution Enter the total number of students in class (max 50): 5 Enter full names of 5 students: Student 1: Soumya Chakraborty Student 2: Aniket Sharma Student 3: Debojyoti Roy Student 4: Bikramjit Das Student 5: Chandan Mitra ========================================= Student Names in Alphabetical Order ========================================= 1. Aniket Sharma 2. Bikramjit Das 3. Chandan Mitra 4. Debojyoti Roy 5. Soumya Chakraborty =========================================