B.Tech Even Semester Examination 2024–2025 · Paper Code: ESCS201 · Full Marks: 70
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.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.
| 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. |
#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.
Answer:
Answer: Variable scope is necessary for the following critical reasons:
i, count, or temp across different functions without naming collisions.#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.
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.
#include<stdio.h>
int main() {
char x;
x = 'a';
printf("%d\n", x);
}
[ 1 Mark ]
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.
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.
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!
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!
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:
switch statement:
nested-if statement:
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.
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).
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!
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 \]
(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:
(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}\).
(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.
(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.
(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!
(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.
(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'.
(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.
(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.
(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} \]
(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.