1What is the primary purpose of a function prototype in C?
Function prototypes
Easy
A.To define the actual logic of the function.
B.To call the function from the main() function.
C.To declare the function's name, return type, and parameters to the compiler before it is defined.
D.To store the return value of a function.
Correct Answer: To declare the function's name, return type, and parameters to the compiler before it is defined.
Explanation:
A function prototype acts as a declaration, informing the compiler about the function's signature so that it can be called even before its full definition appears in the code.
Incorrect! Try again.
2What are the two main parts of a function definition?
Function definition
Easy
A.The function header and the function body
B.The function prototype and the function arguments
C.The function call and the return statement
D.The return type and the function name
Correct Answer: The function header and the function body
Explanation:
A function definition consists of a header (return type, name, parameters) and a body (the block of code containing the function's logic).
Incorrect! Try again.
3When you pass an argument by value, what is actually passed to the function?
Function call including passing arguments by value and passing arguments by reference
Easy
A.The memory address of the argument
B.A copy of the argument's value
C.A pointer to the argument
D.The original argument itself
Correct Answer: A copy of the argument's value
Explanation:
In pass by value, a copy of the variable's value is made and passed to the function. Any changes made to the parameter inside the function do not affect the original variable.
Incorrect! Try again.
4A function that calls itself is known as a ____.
Recursive functions
Easy
A.library function
B.recursive function
C.static function
D.nested function
Correct Answer: recursive function
Explanation:
Recursion is a programming concept where a function solves a problem by calling itself with a smaller version of the same problem.
Incorrect! Try again.
5A variable declared inside a function is known as a ____.
Scope rules (local and global scope)
Easy
A.external variable
B.local variable
C.global variable
D.static variable
Correct Answer: local variable
Explanation:
Local variables have a scope limited to the function or block in which they are declared. They cannot be accessed from outside that function.
Incorrect! Try again.
6Which storage class is the default for local variables declared inside a function?
Storage classes in C namely auto, Extern, Register, Static storage classes
Easy
A.extern
B.auto
C.register
D.static
Correct Answer: auto
Explanation:
If no storage class is specified for a local variable, the C compiler automatically assumes it to be of the auto storage class.
Incorrect! Try again.
7Which header file is required to use the sqrt() function in C?
Math library functions
Easy
A.<math.h>
B.<stdlib.h>
C.<stdio.h>
D.<string.h>
Correct Answer: <math.h>
Explanation:
The C standard math library, which includes functions like sqrt(), pow(), and sin(), is declared in the <math.h> header file.
Incorrect! Try again.
8How is 'pass by reference' typically simulated in the C programming language?
Function call including passing arguments by value and passing arguments by reference
Easy
A.By passing pointers (memory addresses) as arguments
B.C does not support pass by reference
C.By using the & symbol in the function definition
D.By using global variables
Correct Answer: By passing pointers (memory addresses) as arguments
Explanation:
C itself only supports pass by value. However, pass by reference is simulated by passing the memory address (a pointer) of a variable, allowing the function to modify the original variable's value.
Incorrect! Try again.
9What is the main characteristic of a static local variable?
Storage classes in C namely auto, Extern, Register, Static storage classes
Easy
A.It can only be an integer.
B.It is stored in a CPU register.
C.It retains its value between function calls.
D.It is automatically deleted after the function call.
Correct Answer: It retains its value between function calls.
Explanation:
A static local variable is initialized only once and its lifetime extends across the entire run of the program, allowing it to preserve its value between calls to the function where it is defined.
Incorrect! Try again.
10Where can a global variable be accessed from?
Scope rules (local and global scope)
Easy
A.Only from the function where it is declared
B.Only from the main() function
C.From any function in the program
D.Only from functions within the same file
Correct Answer: From any function in the program
Explanation:
A global variable is declared outside of all functions and has a scope that extends to the entire program, making it accessible from any function.
Incorrect! Try again.
11What is the condition that stops a recursive function from calling itself infinitely?
Recursive functions
Easy
A.An exit() function call
B.A break statement
C.Recursive case
D.Base case
Correct Answer: Base case
Explanation:
Every recursive function must have a base case, which is a condition under which the function does not call itself, thereby terminating the recursion and preventing a stack overflow.
Incorrect! Try again.
12What does the extern keyword signify for a variable declaration?
Storage classes in C namely auto, Extern, Register, Static storage classes
Easy
A.The variable's value is fixed.
B.The variable is defined in another source file or later in the same file.
C.The variable should be stored outside of the computer's memory.
D.The variable is external to all functions.
Correct Answer: The variable is defined in another source file or later in the same file.
Explanation:
The extern keyword is a declaration that tells the compiler that a variable's definition (the actual memory allocation) exists elsewhere. It's used to share global variables across multiple source files.
Incorrect! Try again.
13What will be the result of the C expression pow(3.0, 2.0)?
Math library functions
Easy
A.6.0
B.9.0
C.8.0
D.1.5
Correct Answer: 9.0
Explanation:
The pow(base, exponent) function calculates the value of base raised to the power of exponent. So, pow(3.0, 2.0) calculates , which is 9.0.
Incorrect! Try again.
14A function prototype in C must always end with which character?
Function prototypes
Easy
A.; (semicolon)
B.: (colon)
C.} (closing curly brace)
D.. (period)
Correct Answer: ; (semicolon)
Explanation:
A function prototype is a declaration statement in C. Like other declaration and expression statements, it must be terminated with a semicolon.
Incorrect! Try again.
15The part of a function definition that contains the executable statements is called the ____.
Function definition
Easy
A.function prototype
B.function header
C.return statement
D.function body
Correct Answer: function body
Explanation:
The function body is the block of code enclosed in curly braces {} that contains the instructions to be executed when the function is called.
Incorrect! Try again.
16If a function is defined as void func(int x), what kind of parameter passing does it use?
Function call including passing arguments by value and passing arguments by reference
Easy
A.Pass by value
B.Pass by address
C.Pass by reference
D.Pass by pointer
Correct Answer: Pass by value
Explanation:
When the parameter is a non-pointer data type like int, char, or float, the function receives a copy of the argument's value. This is known as pass by value.
Incorrect! Try again.
17The register storage class is a hint to the compiler to store a variable in ____.
Storage classes in C namely auto, Extern, Register, Static storage classes
Easy
A.a CPU register
B.static memory
C.main memory (RAM)
D.a file on the disk
Correct Answer: a CPU register
Explanation:
The register keyword suggests to the compiler that the variable should be stored in a CPU register for faster access. The compiler is free to ignore this suggestion.
Incorrect! Try again.
18What happens if a local variable is declared with the same name as a global variable inside a function?
Scope rules (local and global scope)
Easy
A.The local variable takes precedence inside that function.
B.The global variable takes precedence inside that function.
C.The program will crash at runtime.
D.The program will result in a compilation error.
Correct Answer: The local variable takes precedence inside that function.
Explanation:
The local variable 'shadows' the global variable within its scope. Inside the function, any reference to that name will refer to the local variable, not the global one.
Incorrect! Try again.
19Which function from <math.h> would you use to find the absolute value of a floating-point number?
Math library functions
Easy
A.fabs()
B.sqrt()
C.abs()
D.absval()
Correct Answer: fabs()
Explanation:
The fabs() function is used for finding the absolute value of floating-point numbers (float, double). The abs() function, from <stdlib.h>, is used for integers.
Incorrect! Try again.
20In the function call calculate(&num);, what does the & operator do?
Function call including passing arguments by value and passing arguments by reference
Easy
A.It creates a reference to the variable num.
B.It doubles the value of the variable num.
C.It provides the value of the variable num.
D.It provides the memory address of the variable num.
Correct Answer: It provides the memory address of the variable num.
Explanation:
The ampersand & is the 'address-of' operator in C. It retrieves the memory location where the variable num is stored, which is then passed to the function.
Incorrect! Try again.
21What is the primary consequence of calling a function before its definition appears in the source file, without providing a function prototype?
Function prototypes
Medium
A.A linker error will occur because the function object code cannot be found.
B.A runtime error will occur immediately upon calling the function.
C.The program will not compile, citing a syntax error.
D.The program will compile with a warning, and the compiler will assume a default prototype int function_name(), which may lead to runtime errors.
Correct Answer: The program will compile with a warning, and the compiler will assume a default prototype int function_name(), which may lead to runtime errors.
Explanation:
In older C standards (like C89/90), if a function is called without a prior declaration (prototype), the compiler assumes it returns an int and takes an unspecified number of arguments. In modern C (C99 and later), this is an error. However, many compilers still exhibit the older behavior with warnings. This assumption can lead to incorrect data interpretation and runtime errors if the actual function signature is different.
Incorrect! Try again.
22Analyze the following C code. What will be its output?
c
#include <stdio.h>
void swap(int x, int y) {
int temp = x;
*x = y;
y = temp;
}
int main() {
int a = 10, b = 20;
swap(&a, b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
Function call including passing arguments by value and passing arguments by reference
Medium
A.a = 10, b = 20
B.a = 20, b = 20
C.Compiler Error
D.a = 20, b = 10
Correct Answer: a = 20, b = 20
Explanation:
The function swap takes a pointer x (pass-by-reference) and an integer y (pass-by-value). Inside main, &a is passed to x, so *x refers to a. b is passed to y. The line *x = y; changes the value of a to 20. The line y = temp; only changes the local copy of b within the function swap. The original b in main remains unchanged. Therefore, a becomes 20 and b stays 20.
Incorrect! Try again.
23What will be the output of the following C program?
c
#include <stdio.h>
The program has a global variable value initialized to 5 and a local parameter named value in the display function.
The first printf in main prints the global value, which is 5.
display(10) is called. The parameter value inside display gets the value 10. Then it is changed to 20. This local value shadows the global one. The printf inside display prints this local value, which is 20.
After display returns, the third printf in main prints the global value again, which was never modified. It is still 5.
Incorrect! Try again.
24What is the output of the following code when it is executed?
c
#include <stdio.h>
int main() {
count_calls();
count_calls();
count_calls();
return 0;
}
Static storage classes
Medium
A.1 6 11
B.1 1 1
C.1 5 10
D.Compiler Error
Correct Answer: 1 6 11
Explanation:
A static local variable is initialized only once, the first time the function is called. Its value persists across subsequent calls to the function.
First call: counter is initialized to 1. It prints 1. counter becomes 6.
Second call: The initialization is skipped. counter is 6. It prints 6. counter becomes 11.
Third call: The initialization is skipped. counter is 11. It prints 11. counter becomes 16.
Incorrect! Try again.
25Consider the following recursive function. What does calculate(4) return?
c
int calculate(int n) {
if (n <= 1) {
return 1;
}
return n + calculate(n - 2);
}
calculate(4) becomes 4 + 3 = 7
So, the final return value is 7.
Incorrect! Try again.
26Suppose you have two C files, main.c and support.c. What is the most likely result of compiling and linking them?
support.c
c
int global_var = 100;
main.c
c
#include <stdio.h>
int global_var;
int main() {
printf("%d\n", global_var);
return 0;
}
Extern storage classes
Medium
A.The program compiles and prints 100.
B.The program compiles and prints 0.
C.A linker error due to multiple definitions of global_var.
D.A compiler error in main.c.
Correct Answer: A linker error due to multiple definitions of global_var.
Explanation:
In support.c, int global_var = 100; is a definition. In main.c, int global_var; is also a tentative definition (which acts as a definition at link time). When the linker tries to combine the object files from both .c files, it finds two definitions for the same global variable global_var. This violates the one-definition rule and results in a "multiple definition" linker error. To fix this, main.c should have used extern int global_var; to declare it instead of defining it.
Incorrect! Try again.
27What is the output of the following C code snippet? (Assume math.h is included).
c
#include <stdio.h>
#include <math.h>
int main() {
double result = pow(2, 3) + ceil(4.01) - floor(5.99);
printf("%.1f\n", result);
return 0;
}
Math library functions
Medium
A.9.0
B.8.2
C.7.0
D.8.0
Correct Answer: 8.0
Explanation:
Let's break down the calculation:
pow(2, 3) calculates , which is 8.0.
ceil(4.01) rounds up to the smallest integer greater than or equal to 4.01, which is 5.0.
floor(5.99) rounds down to the largest integer less than or equal to 5.99, which is 5.0.
The expression becomes 8.0 + 5.0 - 5.0, which equals 8.0. The format specifier %.1f prints the result with one decimal place.
Incorrect! Try again.
28What will be printed by the following C code? Note how arrays are passed to functions.
c
#include <stdio.h>
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int n = 5;
modify_array(numbers, n);
printf("numbers[0] = %d, n = %d\n", numbers[0], n);
return 0;
}
Function call including passing arguments by value and passing arguments by reference
Medium
A.numbers[0] = 1, n = 10
B.numbers[0] = 100, n = 10
C.numbers[0] = 1, n = 5
D.numbers[0] = 100, n = 5
Correct Answer: numbers[0] = 100, n = 5
Explanation:
In C, when an array is passed to a function, what is actually passed is the address of its first element (pass-by-reference behavior). Therefore, any modifications to the array elements inside the function modify_array will affect the original numbers array in main. So, numbers[0] becomes 100. However, the size parameter is a regular integer passed by value. The change size = 10; only affects the local copy within the function and does not change the value of n in main.
Incorrect! Try again.
29Which of the following operations is invalid for a variable declared with the register storage class?
Register storage classes
Medium
A.Getting its memory address using the & operator.
B.Using it as a loop counter.
C.Passing it by value to another function.
D.Initializing it at the time of declaration.
Correct Answer: Getting its memory address using the & operator.
Explanation:
The register keyword is a hint to the compiler to store the variable in a CPU register instead of RAM for faster access. Since registers do not have memory addresses, the unary & (address-of) operator cannot be applied to a register variable. Attempting to do so will result in a compiler error.
Incorrect! Try again.
30What is the output of the following code for the call fun(25)?
c
#include <stdio.h>
void fun(int n) {
if (n == 0)
return;
fun(n / 2);
printf("%d", n % 2);
}
Recursive functions
Medium
A.25
B.10011
C.The function runs indefinitely.
D.11001
Correct Answer: 11001
Explanation:
This recursive function effectively converts a decimal number to its binary representation and prints it. The printf statement is executed after the recursive call, which means the remainders (n % 2) are printed in reverse order of calculation, which is the correct order for the binary string.
fun(25) calls fun(12)
fun(12) calls fun(6)
fun(6) calls fun(3)
fun(3) calls fun(1)
fun(1) calls fun(0)
fun(0) returns.
fun(1) prints 1 % 2 -> 1
fun(3) prints 3 % 2 -> 1
fun(6) prints 6 % 2 -> 0
fun(12) prints 12 % 2 -> 0
fun(25) prints 25 % 2 -> 1
The final output is 11001.
Incorrect! Try again.
31Predict the output of the given C code.
c
#include <stdio.h>
int x = 10;
int main() {
int x = 20;
{
extern int x;
printf("%d ", x);
}
printf("%d\n", x);
return 0;
}
Scope rules (local and global scope)
Medium
A.10 10
B.20 20
C.10 20
D.Compiler Error
Correct Answer: 10 20
Explanation:
Inside main, a local variable x is defined and initialized to 20, shadowing the global x. However, inside the inner block { ... }, the declaration extern int x; explicitly tells the compiler to refer to the file-scope (global) instance of x. Therefore, the first printf prints the value of the global x, which is 10. Once the block is exited, the extern declaration is no longer in scope, and the name x again refers to the local variable in main. The second printf thus prints the local x's value, which is 20.
Incorrect! Try again.
32Consider the following C code. What is the most likely outcome?
c
#include <stdio.h>
A.The code fails to compile due to a type mismatch in the function call.
B.The code compiles and prints "n = 6".
C.The code compiles and prints "n = 5".
D.The code compiles but results in a runtime error.
Correct Answer: The code compiles and prints "n = 5".
Explanation:
The function prototype void display(int); tells the compiler that the function display expects an integer argument. When display(5.5) is called in main, the double literal 5.5 is implicitly converted (truncated) to an int to match the parameter type specified in the prototype. The value passed to the function will be 5. Therefore, the output will be "n = 5".
Incorrect! Try again.
33What is the primary difference between a static global variable and a non-static (regular) global variable in C?
Static storage classes
Medium
A.A static global variable cannot be modified after initialization.
B.A static global variable has internal linkage, limiting its visibility to the translation unit (the file) in which it is defined.
C.A static global variable retains its value across program executions, while a regular global does not.
D.A static global variable is stored on the stack, while a regular global is stored in the data segment.
Correct Answer: A static global variable has internal linkage, limiting its visibility to the translation unit (the file) in which it is defined.
Explanation:
The static keyword, when applied to a global variable, changes its linkage from external (the default for globals) to internal. This means the variable's name is not visible to the linker and cannot be accessed from other source files using the extern keyword. Its scope is restricted to the single file where it is defined. Both types of variables have static storage duration (exist for the program's lifetime) and are stored in the data/BSS segment.
Incorrect! Try again.
34Examine the following C code. What will be the output?
c
#include <stdio.h>
void update(int *p) {
int y = 20; p = &y;
}
int main() {
int x = 10;
int ptr = &x;
update(&ptr);
printf("%d\n", ptr);
return 0;
}
Function call including passing arguments by value and passing arguments by reference
Medium
A.20
B.10
C.Compiler Error
D.Undefined behavior (printing a value from a dangling pointer).
Correct Answer: Undefined behavior (printing a value from a dangling pointer).
Explanation:
The function update takes a pointer-to-a-pointer. Inside update, *p is made to point to the local variable y. When update returns, its stack frame is destroyed, and the variable y ceases to exist. Back in main, the pointer ptr now holds the address of where yused to be. This is a dangling pointer. Dereferencing this pointer with *ptr in the printf statement results in undefined behavior. The program might crash, print a garbage value, or coincidentally print 20, but the behavior is not guaranteed by the C standard.
Incorrect! Try again.
35Which of the following C statements correctly and safely calculates for a double variable x and stores it in a double variable y? (Assume math.h is included).
Math library functions
Medium
A.y = |pow(x, 3.0)|;
B.y = abs(pow(x, 3.0));
C.y = pow(abs(x), 3.0);
D.y = fabs(pow(x, 3.0));
Correct Answer: y = fabs(pow(x, 3.0));
Explanation:
The function pow(x, 3.0) correctly calculates for a double. The result of pow is also a double. To find the absolute value of a floating-point number (double or float), the correct function is fabs() from math.h. The abs() function is intended for integers, and using it with a double may lead to incorrect results or implicit conversions. The | character is the bitwise OR operator in C, not the absolute value operator.
Incorrect! Try again.
36What are the default storage class and initial value of a variable declared inside a function without any storage class specifier, like int count;?
Auto storage classes
Medium
A.auto storage class, and its initial value is indeterminate (garbage).
B.auto storage class, and its initial value is 0.
C.static storage class, and its initial value is 0.
D.register storage class, and its initial value is indeterminate (garbage).
Correct Answer: auto storage class, and its initial value is indeterminate (garbage).
Explanation:
By default, any variable declared inside a block or a function is an automatic variable. The auto keyword is optional and rarely used because it is the default. Automatic variables are allocated on the stack when the function is entered and deallocated when it exits. They are not initialized by the system and hold an indeterminate (garbage) value unless explicitly initialized by the programmer.
Incorrect! Try again.
37If a function is defined as float calculate(float a, int b);, which of the following is NOT a valid prototype for it?
Function prototypes
Medium
A.float calculate();
B.extern float calculate(float a, int b);
C.float calculate(float, int);
D.float calculate(float value, int count);
Correct Answer: float calculate();
Explanation:
A function prototype must match the function definition's return type and the number and types of its parameters. float calculate(float, int); and float calculate(float value, int count); are both valid prototypes (parameter names are optional in prototypes). extern float calculate(float a, int b); is also a valid prototype; extern is the default for function declarations and is optional. However, float calculate(); is an old-style declaration that indicates the function takes an unspecified number of arguments, which does not match the definition and would likely cause compiler warnings or errors.
Incorrect! Try again.
38What is a potential major drawback of the following recursive implementation for calculating Fibonacci numbers compared to an iterative approach?
c
int fib(int n) {
if (n <= 1) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
Recursive functions
Medium
A.It has exponential time complexity due to recalculating the same values multiple times.
B.It will always result in a stack overflow for n > 2.
C.The base case is incorrect, leading to an infinite recursion.
D.It cannot calculate Fibonacci numbers for even values of n.
Correct Answer: It has exponential time complexity due to recalculating the same values multiple times.
Explanation:
This is a classic example of inefficient recursion. To calculate fib(5), it calls fib(4) and fib(3). fib(4) in turn calls fib(3) and fib(2). The value of fib(3) is computed twice. This redundancy grows exponentially, leading to a time complexity of approximately , which is highly inefficient for even moderately large n. An iterative approach would have a linear time complexity of .
Incorrect! Try again.
39What is the output of the following C code?
c
#include <stdio.h>
int generator() {
static int i = 0;
i += 2;
return i;
}
int main() {
int a = generator();
int b = generator();
printf("%d %d\n", a, b);
return 0;
}
Static storage classes
Medium
A.2 4
B.4 4
C.2 2
D.0 2
Correct Answer: 2 4
Explanation:
The variable i inside generator is static, so it is initialized to 0 only once and retains its value between function calls.
main calls generator() for the first time. i becomes 0 + 2 = 2. The function returns 2. Variable a is assigned the value 2.
main calls generator() for the second time. The value of i is currently 2. It is updated to 2 + 2 = 4. The function returns 4. Variable b is assigned the value 4.
The printf statement then prints the values of a and b, which are 2 and 4.
Incorrect! Try again.
40Which of the following statements is true regarding the initialization of a variable declared with extern?
Extern storage classes
Medium
A.A variable declared with extern cannot be initialized because it is only a declaration, not a definition.
B.An extern variable is always initialized to 0 by the compiler.
C.An extern variable inherits the value of the last variable declared in the previous scope.
D.An extern variable must be initialized at the point of its declaration.
Correct Answer: A variable declared with extern cannot be initialized because it is only a declaration, not a definition.
Explanation:
The extern keyword signifies a declaration, not a definition. It tells the compiler, "This variable exists and is defined somewhere else." Since it's not a definition, it doesn't allocate storage for the variable. Initialization is the process of assigning an initial value when storage is allocated (i.e., at the definition). Therefore, extern int x = 10; is an error because it attempts to initialize a variable at its declaration. The initialization must happen with the actual definition of the variable in another file or location.
Incorrect! Try again.
41Analyze the following C code that uses a static local variable within a recursive function. What will be printed to standard output?
c
#include <stdio.h>
int recursive_static(int n) {
static int s = 5;
if (n <= 1) {
return s;
}
s += n;
recursive_static(n - 1);
return s;
}
int main() {
printf("%d", recursive_static(4));
return 0;
}
Static storage classes
Hard
A.14
B.12
C.5
D.16
Correct Answer: 14
Explanation:
The static int s is initialized only once to 5. Its lifetime is the entire program execution.
recursive_static(4) is called. s is 5. s becomes 5 + 4 = 9. recursive_static(3) is called.
recursive_static(3) is called. s is 9. s becomes 9 + 3 = 12. recursive_static(2) is called.
recursive_static(2) is called. s is 12. s becomes 12 + 2 = 14. recursive_static(1) is called.
recursive_static(1) is called. The base case n <= 1 is met. It returns the current value of s, which is 14.
The return value of recursive_static(1) is ignored by its caller recursive_static(2). recursive_static(2) proceeds and returns the current value of s, which is 14.
Similarly, the return values from the inner calls are ignored. The final call recursive_static(4) returns the final value of s, which is 14.
Incorrect! Try again.
42What is the output of the following C program that manipulates pointers to pointers?
pb = temp (&a)
Final state: a=100, b=200, pa=&b, pb=&a.
Printf: a=100, b=200, *pa=200, *pb=100.
This is the correct result. I will create options around this.
A) a=10, b=20, *pa=20, *pb=10
B) a=100, b=200, *pa=200, *pb=100
C) a=100, b=20, *pa=20, *pb=100
D) a=200, b=10, *pa=10, *pb=200
Correct option is B.
Incorrect! Try again.
43Predict the output of the following C program, which demonstrates complex variable shadowing.
c
#include <stdio.h>
int x = 10;
void display(int x) {
x += 5;
{
int x = ::x + 5; // Note: ::x is not valid C syntax. Assuming it meant the global x.
// C does not have a scope resolution operator. This code is invalid.
// Let's modify the question to be valid C and still hard.
}
}
Let's re-design the question.
c
#include <stdio.h>
int val = 1;
int main() {
int val = 10;
{
extern int val;
printf("%d, ", val);
}
printf("%d", val);
return 0;
}
What is the behavior of this program?
Scope rules (local and global scope)
Hard
A.Linker Error
B.1, 1
C.10, 10
D.1, 10
Correct Answer: Linker Error
Explanation:
This code demonstrates a conflict between an extern declaration and a file-scope definition.
int val = 1; at the top level defines a global variable val with external linkage.
In main, int val = 10; defines a local variable val that shadows the global one.
Inside the inner block, extern int val; is a declaration, not a definition. It refers to a global variable named val with external linkage. At this point, the compiler knows it should look for a global val for the printf.
However, the definition for this global val is right in the same file (int val = 1;). The C standard states that an extern declaration within a block cannot refer to a file-scope variable defined in the same translation unit if that variable is shadowed by an intermediate-scope variable. More practically, many compilers will compile this, and the linker will find the global val = 1. But, let's consider a stricter case. What if int val = 1; was static int val = 1;? Then the extern could not link to it, causing a linker error.
Let's stick to the original code. extern int val; tells the linker to find val defined elsewhere. The linker finds int val = 1; in the same object file. It should link. Let's trace.
The printf in the block refers to the global val. It will print 1.
The printf outside the block refers to main's local val. It will print 10.
Output should be 1, 10. So option A. Is this truly 'Hard'?
Let's make it harder. What causes a linker error for sure?
c
// file1.c
include <stdio.h>
int main() {
extern int val;
printf("%d", val);
return 0;
}
// file2.c
static int val = 100;
Here, extern int val needs a symbol with external linkage. static int val has internal linkage. The linker will not find val. This is a guaranteed Linker Error. This is a better question. I will use this multi-file version. It's more suitable for extern. The previous one was more about scope, this one is about linkage which is tied to extern. Okay, I'll go with the multi-file version.
Incorrect! Try again.
44Analyze the following mutually recursive functions. What is the final output when A(6) is called?
B(1): The condition n > 1 is false. The function returns.
A(2) finishes.
B(5) finishes.
A(6) finishes.
Let's retrace A(2).
A(2): prints 2. Calls B(2-1), which is B(1).
B(1): n > 1 is false. Returns.
A(2) returns to B(5). B(5) returns to A(6). A(6) returns. The output is 6 5 2. My trace seems to give this. What did I miss?
Ah, I misread the question I wrote myself. Let's make B call A(n/2) which makes it more interesting.
Okay, A(6) -> prints 6, calls B(5). B(5) -> prints 5, calls A(2). A(2) -> prints 2, calls B(1). B(1) does nothing. This is still 6 5 2. This is not hard enough. Let's change A slightly.
New A: A(n-2)? No.
Let's make B print something after the call.
No, let's just make the trace longer. A(7) -> prints 7, B(6). B(6) -> prints 6, A(3). A(3) -> prints 3, B(2). B(2) -> prints 2, A(1). A(1) -> prints 1, B(0). B(0) stops. Output: 7 6 3 2 1. This is better. I will use A(7).
A(6) prints 6, calls B(5)
B(5) prints 5, calls A(2)
A(2) prints 2, calls B(1)
B(1) returns.
Where did 1 come from in the option 6 5 2 1? Let's change A.
New A: void A(int n) { if (n > 0) { printf("%d ", n); B(n-1); } }
New B: void B(int n) { if (n > 1) { printf("%d ", n); A(n-2); } } A(6) -> print 6, B(5). B(5) -> print 5, A(3). A(3) -> print 3, B(2). B(2) -> print 2, A(0). A(0) -> returns. Final output 6 5 3 2. This is a decent trace. Let me stick to the first version and assume my chosen correct answer 6 5 2 1 implies a bug in my trace. Let's re-read the code from the question. A(n/2) in B. B(n-1) in A. A(6) -> print 6, call B(5) B(5) -> print 5, call A(2) (5/2=2) A(2) -> print 2, call B(1) B(1) -> base case, returns.
So far: 6 5 2. Okay, I must have had a different question in mind. Let's change B to A(n-3). A(6) -> print 6, B(5). B(5) -> print 5, A(2). A(2) -> print 2, B(1). Returns. Still 6 5 2.
How to get 6 5 2 1?
If A(2) calls something that results in 1. A(2) calls B(1). B(1) would have to call A(1) and print. The if (n > 1) prevents this. Let's change it to if (n >= 1). No, that causes infinite recursion A(1) -> B(0) -> A(0/2)=A(0). Let's change A(n/2) to A(n-1).
New B: B(n) { if (n>1) { printf(n); A(n-1); } }. A(6) -> p6, B(5). B(5)->p5,A(4). A(4)->p4,B(3). B(3)->p3,A(2).A(2)->p2,B(1). Returns. Still doesn't print 1.
Okay, final attempt to fix the question.
c
void A(int n) { if (n > 0) { A(n - 1); printf("%d ", n); } }
void B(int n) { if (n > 1) { B(n - 2); printf("%d ", n); } }
// A(3) -> A(2) -> A(1) -> A(0). Prints 1 2 3.
This is getting too far from the original. I'll stick with the original question and fix the options and explanation. Output is 6 5 2.
Options: 6 5 4 2, 6 5 2, 6 5, 6. Correct: 6 5 2.
This feels less 'hard' now.
What if A was defined as: void A(int n) { if (n > 0) { printf("%d ", n); B(n); } } -- No, infinite recursion.
What if the base case for A was different?
My original trace 6 5 2 1 came from A(6) -> p6, B(5). B(5) -> p5, A(2). A(2) -> p2, B(1). B(1) -> p1, A(0). This would require B's condition to be if (n > 0). Let's use that. void B(int n) { if (n > 0) { printf("%d ", n); A(n / 2); } } A(6) -> p6, B(5). B(5) -> p5, A(2). A(2) -> p2, B(1). B(1) -> p1, A(0). A(0) -> returns. Final output: 6 5 2 1. Yes, this works and is a good trace. I will use this version of B.
Incorrect! Try again.
45Consider two C files, f1.c and f2.c. What is the behavior when they are compiled and linked together?
f1.c:
c
#include <stdio.h>
int main() {
extern int global_var;
printf("%d", global_var);
return 0;
}
f2.c:
c
static int global_var = 100;
Extern storage class
Hard
A.A linker error occurs.
B.A compilation error occurs in f1.c.
C.The program compiles and prints 100.
D.The program compiles and prints 0.
Correct Answer: A linker error occurs.
Explanation:
The extern int global_var; declaration in f1.c tells the compiler that global_var is defined elsewhere with external linkage. The linker is then responsible for finding this definition in other object files. In f2.c, static int global_var = 100; defines a variable named global_var, but the static keyword gives it internal linkage. This means global_var from f2.c is only visible within f2.c and is not exposed to the linker for use by other modules. Consequently, the linker will fail to resolve the reference to global_var from f1.c, resulting in a linker error (typically an 'undefined symbol' or 'unresolved external' error).
Incorrect! Try again.
46According to the C90 standard, what is the most likely result of compiling and running the following code where a function is called without a prior prototype?
c
#include <stdio.h>
int main() {
printf("%ld", sizeof(get_val()));
return 0;
}
long double get_val() {
return 100.0L;
}
Function prototypes
Hard
A.It prints sizeof(int), which is typically 4.
B.It prints sizeof(long double), which is typically 10, 12, or 16.
C.It results in a runtime crash.
D.It results in a compilation error.
Correct Answer: It prints sizeof(int), which is typically 4.
Explanation:
In the C90 (or K&R C) standard, if a function is called without a visible prototype, the compiler assumes an implicit declaration of int function_name(). Therefore, in main, the compiler sees get_val() and assumes it is a function that returns an int. The expression sizeof(get_val()) becomes sizeof(int). The actual definition of get_val returning a long double is seen later, but it doesn't change how the call site was compiled. The code exhibits undefined behavior if you tried to use the value returned, but the sizeof operator works on the type of the expression, which the compiler determined to be int. In C99 and later standards, this would be a compilation error.
Incorrect! Try again.
47What is the output of the following C program that deals with edge cases of mathematical functions?
This question tests specific edge cases defined in the IEEE 754 standard, which C's math library follows.
pow(0.0, 0.0): By standard, is defined as 1.0.
pow(-1.0, INFINITY): This is also defined to be 1.0. The reasoning is that as the exponent approaches infinity, it takes on both even and odd large values, and the limit is considered to be 1.
remainder(10.0, 3.0): The remainder function computes the remainder , where is the integer value closest to . Here, . The closest integer is 3. So the result is . This differs from fmod(10.0, 3.0), which would also be 1.0. A trickier case would be remainder(5.0, 3.0): , closest int is 2. Remainder is . Let's change the question to use that. remainder(5.0, 3.0) is -1.0. remainder(10, 3.0) gives 1.0. Let's use remainder(5.0, 3.0). Okay new question with remainder(5.0, 3.0).
New trace: p1=1.0, p2=1.0, r = remainder(5.0, 3.0). 5.0/3.0 is 1.66.... Closest integer is 2. Result is 5.0 - 2*3.0 = -1.0. So output is 1.0 1.0 -1.0. This is a better question. I will use this version.
Incorrect! Try again.
48What is the primary reason the following C code fails to compile?
c
#include <stdio.h>
int main() {
register int reg_var = 10;
int ptr = ®_var;
ptr = 20;
printf("%d", reg_var);
return 0;
}
Register storage class
Hard
A.A pointer cannot point to a register variable.
B.A register variable cannot be initialized.
C.The address-of operator (&) cannot be applied to a register variable.
D.A register variable is read-only after initialization.
Correct Answer: The address-of operator (&) cannot be applied to a register variable.
Explanation:
The register storage class is a hint to the compiler to store the variable in a CPU register for faster access. CPU registers do not have memory addresses. The address-of operator (&) is used to get the memory address of a variable. Since a register variable might not be stored in memory, the C standard explicitly forbids taking its address. Therefore, the line int *ptr = ®_var; is a constraint violation and will cause a compilation error.
Incorrect! Try again.
49The Ackermann function is a classic example of a recursive function that is not primitive recursive. What is the value of ack(2, 3)?
c
int ack(int m, int n) {
if (m == 0) {
return n + 1;
} else if (n == 0) {
return ack(m - 1, 1);
} else {
return ack(m - 1, ack(m, n - 1));
}
}
Recursive functions
Hard
A.Stack Overflow
B.11
C.7
D.9
Correct Answer: 9
Explanation:
Tracing the Ackermann function requires careful substitution:
Substitute back: ack(2, 2) = ack(1, 5) = ... Using the pattern ack(1, n) = n + 2, we get ack(1, 5) = 7.
Substitute back: ack(2, 2) = 7.
Finally, ack(2, 3) = ack(1, 7). Using the pattern ack(1, n) = n+2, the result is 7 + 2 = 9.
Alternatively, the pattern for ack(2, n) is 2n + 3. For n=3, this is 2*3 + 3 = 9.
Incorrect! Try again.
50What is printed by the following program, which passes an array to a function and uses the sizeof operator? (Assume a 64-bit system where sizeof(int) is 4 and sizeof(int*) is 8).
int main() {
int data[20];
printf("%zu,", sizeof(data));
process_array(data);
return 0;
}
Function call including passing arguments by value and passing arguments by reference
Hard
A.8,80
B.80,8
C.80,80
D.8,8
Correct Answer: 80,8
Explanation:
This question highlights the concept of array decay.
In main, data is an array of 20 integers. sizeof(data) calculates the total memory occupied by the array, which is 20 * sizeof(int) = 20 * 4 = 80 bytes.
When an array is passed to a function, it decays into a pointer to its first element. The function parameter int arr[20] is treated by the compiler exactly as int *arr.
Inside process_array, sizeof(arr) is therefore not the size of the original array, but the size of the pointer variable arr. On the assumed 64-bit system, the size of any pointer is 8 bytes.
Therefore, the output is 80,8.
Incorrect! Try again.
51Analyze this code. A function returns a pointer to a static local variable. What is the output?
c
#include <stdio.h>
int get_counter() {
static int counter = 10;
counter += 5;
return &counter;
}
int main() {
int p1 = get_counter();
int p2 = get_counter(); p1 += 5;
printf("%d", *p2);
return 0;
}
Static storage classes
Hard
A.20
B.Undefined Behavior
C.15
D.25
Correct Answer: 25
Explanation:
The key is that static int counter refers to the same variable across all calls to get_counter().
First call to get_counter(): counter is initialized to 10. It is incremented to 15. The address of counter is returned. p1 now points to counter.
Second call to get_counter(): The initialization is skipped. counter (which is 15) is incremented to 20. The same address is returned. p2 now also points to counter.
*p1 += 5;: This dereferences p1, which points to counter. The value of counter (which is 20) is incremented by 5, becoming 25.
printf("%d", *p2);: This dereferences p2. Since p2 also points to counter, it prints the current value of counter, which is 25.
Incorrect! Try again.
52In C, a declaration extern int var = 10; is placed at file scope in a single file program.c. Which statement accurately describes this line?
Extern storage class
Hard
A.It is a tentative definition that will be initialized to 0 by default.
B.It is a full definition, not just a declaration. It allocates storage for var and provides an initial value.
C.It is a syntax error because extern declarations cannot have initializers.
D.It is a declaration, and the program requires another file to provide the definition of var.
Correct Answer: It is a full definition, not just a declaration. It allocates storage for var and provides an initial value.
Explanation:
This is a subtle rule in C. While extern int var; is a pure declaration that states var is defined elsewhere, the C standard specifies that if an initializer is present with an extern declaration, that declaration is treated as the definition of the variable. Therefore, extern int var = 10; allocates storage for var, gives it external linkage, and initializes it to 10. If another file also contained a definition like int var = 20;, it would result in a "multiple definition" linker error.
Incorrect! Try again.
53What is the status of the following C code when compiled by a standard-compliant C compiler?
c
#include <stdio.h>
void my_func(void); // Prototype specifies zero arguments
int main() {
my_func(42); // Called with one argument
return 0;
}
void my_func(void) {
printf("Hello!\n");
}
Function prototypes
Hard
A.Compiles with a warning, but runs correctly.
B.Results in undefined behavior at runtime.
C.Results in a compilation error.
D.Compiles and runs, ignoring the extra argument.
Correct Answer: Results in a compilation error.
Explanation:
The function prototype void my_func(void); is an explicit declaration that the function my_func takes exactly zero arguments. The call my_func(42); in main attempts to pass one argument. This is a direct violation of the function's prototype. A standard-compliant C compiler is required to diagnose this mismatch as an error, so the code will fail to compile.
Incorrect! Try again.
54What is the output of this C program demonstrating variable shadowing and lifetime?
This program tests the difference between global, static local, and auto local variables.
int x = 5; is a global variable.
In get_x, static int x = 10; is a static local variable. It shadows the global x inside get_x. Its lifetime is the whole program. The function returns a pointer to this static variable.
In set_x, int x = 20; is an auto local variable. It shadows the global x inside set_x.
The line *get_x() = x; calls get_x(), which returns the address of the static local x. It then assigns the value of set_x's local x (which is 20) to the static local x. The global x is never touched.
The printf statements in main are outside the scope of both local x variables, so they always refer to the global x, whose value remains 5 throughout.
Incorrect! Try again.
55What is the behavior of the following C code, which attempts to modify a const qualified variable via a pointer?
c
#include <stdio.h>
void attempt_modify(int p) { p = 100;
}
int main() {
const int value = 50;
attempt_modify((int*)&value);
printf("%d", value);
return 0;
}
Function call including passing arguments by value and passing arguments by reference
Hard
A.The behavior is undefined.
B.The program prints 50 as the modification fails silently.
C.Compilation error due to the cast (int*).
D.The program prints 100 as the const is overridden.
Correct Answer: The behavior is undefined.
Explanation:
The variable value is declared const, meaning it should not be modified. Taking its address (&value) yields a pointer of type const int *. The code then explicitly casts this to int *, removing the const qualifier. This cast itself is allowed, but it's a dangerous operation. When attempt_modify tries to write to the memory location of value through the non-const pointer, it is attempting to modify a const-qualified object. According to the C standard, this results in undefined behavior. The program might print 50, print 100, crash, or do something else entirely, as the compiler is allowed to make optimizations based on the assumption that const objects are never modified.
Incorrect! Try again.
56A function is defined using the old K&R style as shown. What does sizeof(arg) evaluate to inside the function when called with a char?
c
#include <stdio.h>
void K_and_R_func(arg)
char arg; // Parameter type declared here
{
printf("%zu", sizeof(arg));
}
int main()
{
K_and_R_func('A');
return 0;
}
Function definition
Hard
A.This is not valid C and will not compile.
B.sizeof(char)
C.sizeof(double)
D.sizeof(int)
Correct Answer: sizeof(char)
Explanation:
This question tests knowledge of K&R C function definitions and default argument promotions. When K_and_R_func is called without a visible ANSI-style prototype, the character 'A' undergoes default argument promotion to int. So, an int value is actually passed on the stack. However, the function definition void K_and_R_func(arg) char arg; explicitly declares that the parameter arg has the type char. The received int value is converted back to char and stored in the parameter arg. Inside the function body, the sizeof operator is applied to the parameter arg, whose type is char. Therefore, sizeof(arg) will evaluate to sizeof(char), which is 1.
Incorrect! Try again.
57What will be printed by the following C program?
c
#include <stdio.h>
#include <math.h>
int main() {
double val1 = log(0.0);
double val2 = log10(-1.0);
double val3 = sqrt(-1.0);
int result = 0;
if (isinf(val1)) result += 1;
if (isnan(val2)) result += 2;
if (isnan(val3)) result += 4;
printf("%d", result);
return 0;
}
Math library functions
Hard
A.7
B.6
C.0
D.3
Correct Answer: 7
Explanation:
This question tests the error handling of common math functions:
log(0.0): The logarithm of zero is negative infinity. A pole error occurs. val1 will hold -Infinity. isinf(val1) will be true. result becomes 1.
log10(-1.0): The logarithm of a negative number is not a real number. A domain error occurs. val2 will be set to NaN (Not a Number). isnan(val2) will be true. result becomes 1 + 2 = 3.
sqrt(-1.0): The square root of a negative number is not a real number. A domain error occurs. val3 will be set to NaN. isnan(val3) will be true. result becomes 3 + 4 = 7.
The final value of result is 7.
Incorrect! Try again.
58What is the output of the following program that uses recursion to print a pattern?
This is a complex trace of the function call stack.
pattern(5):
printf(5) -> Output: 5
pattern(3):
printf(3) -> Output: 5 3
pattern(1):
printf(1) -> Output: 5 3 1
pattern(-1) -> returns
pattern(-2) -> returns
printf(1) -> Output: 5 3 1 1
pattern(0) -> returns
printf(3) -> Output: 5 3 1 1 3
pattern(2):
printf(2) -> Output: 5 3 1 1 3 2
pattern(0) -> returns
pattern(-1) -> returns
printf(2) -> Output: 5 3 1 1 3 2 2
printf(5) -> Output: 5 3 1 1 3 2 2 5
Incorrect! Try again.
59Consider the following code snippet. Which statement is true?
c
void my_func() {
auto int a = 1; // Line 1
static int b = 1; // Line 2
a++;
b++;
printf("a=%d, b=%d\n", a, b);
}
int main() {
my_func();
my_func();
return 0;
}
Storage classes in C namely auto, Extern, Register, Static storage classes
Hard
A.The output is a=2, b=2 followed by a=2, b=2.
B.The output is a=2, b=2 followed by a=3, b=3.
C.The output is a=2, b=2 followed by a=2, b=3.
D.The code has a syntax error because auto is not used this way.
Correct Answer: The output is a=2, b=2 followed by a=2, b=3.
Explanation:
This question contrasts the lifetime of auto and static local variables.
auto int a = 1;: a is an automatic local variable. It is created and initialized to 1 each time my_func is entered. Its lifetime is limited to the function call.
static int b = 1;: b is a static local variable. It is initialized to 1 only once, before the program starts execution. Its lifetime is the entire duration of the program, and it retains its value between function calls.
First call to my_func():
a is created and set to 1. b already exists with value 1.
a becomes 2. b becomes 2.
Output: a=2, b=2.
a is destroyed.
Second call to my_func():
a is created again and set to 1. b still exists with its last value, 2.
a becomes 2. b becomes 3.
Output: a=2, b=3.
a is destroyed.
Incorrect! Try again.
60Predict the output of the following C program involving pointer reassignment within a function.
c
#include <stdio.h>
struct Point { int x, y; };
void reassign(struct Point *p) {
struct Point new_p = {100, 200};
p->x = 50;
p = &new_p;
p->x = 300;
}
int main() {
struct Point my_p = {10, 20};
reassign(&my_p);
printf("%d %d", my_p.x, my_p.y);
return 0;
}
Function call including passing arguments by value and passing arguments by reference
Hard
A.50 200
B.10 20
C.300 200
D.50 20
Correct Answer: 50 20
Explanation:
This question illustrates that pointers themselves are passed by value in C.
In main, reassign is called with the address of my_p. The parameter p inside reassign becomes a local copy of this address.
p->x = 50;: This uses the copied address to access the original my_p structure in main and changes my_p.x to 50. my_p is now {50, 20}.
struct Point new_p = {100, 200};: A new local structure is created on reassign's stack.
p = &new_p;: This changes the local pointer p to point to the new local structure new_p. It does not affect anything in main.
p->x = 300;: This modifies the local new_p.x to 300.
reassign returns. new_p is destroyed. The only persistent change was the modification to my_p.x.
The printf in main prints the final state of my_p, which is {50, 20}.