C Functions & Recursion - Tricky MCQ
Tricky Questions on Functions, Recursion & Parameter Passing
What is the difference between function declaration and function definition?
A function declaration (prototype) specifies the function's return type, name, and parameter types without providing the body. It tells the compiler about the function's interface. A function definition includes the actual implementation. Declaration is optional if definition appears before use, but mandatory if function is called before its definition appears in source code.
Does C support function overloading?
C does not support traditional function overloading (multiple functions with same name but different parameters). However, C11 introduced the _Generic keyword which provides a form of type-generic programming that can mimic function overloading. In practice, C programmers often use different function names or void pointers for polymorphism.
What is tail recursion optimization?
Tail recursion occurs when the recursive call is the last operation in the function (no computation after the call). Compilers can optimize tail recursion by reusing the current stack frame instead of creating a new one for each recursive call, effectively converting recursion to iteration. This prevents stack overflow for deep recursion and improves performance.
Can a function return multiple values in C?
While C functions can directly return only one value, there are several ways to return multiple values: 1) Return a structure containing multiple values, 2) Use pointer parameters to modify variables in the caller, 3) Use global variables (not recommended due to side effects). The most common approach is using pointer parameters (call by reference).
What is the difference between actual parameters and formal parameters?
Actual parameters (arguments) are the values or expressions passed to a function when it is called. Formal parameters are the variables declared in the function header that receive the actual parameters. In call by value, formal parameters get copies of actual parameters. In call by reference (using pointers), formal parameters get addresses of actual parameters.
Can main() function be called recursively in C?
In C, main() is not a reserved keyword and can be called recursively like any other function. However, it's generally not recommended because main() is the program entry point and recursive calls to main() can cause unexpected behavior with program initialization, atexit() handlers, and command-line arguments. The C standard doesn't forbid it but warns against it.
What is a variadic function in C?
A variadic function accepts a variable number of arguments. It's declared with an ellipsis (...) as the last parameter. Examples include printf() and scanf(). Variadic functions use stdarg.h macros (va_list, va_start, va_arg, va_end) to access arguments. The function must have at least one named parameter before the ellipsis to determine where arguments start.
What happens if you don't provide function prototype before use?
In C (before C99), if a function is called without a prototype, the compiler assumes it returns int and performs default argument promotions (char/short to int, float to double). This can lead to subtle bugs if the actual function has different return type or parameter types. Since C99, implicit function declarations are invalid, but many compilers still allow them with warnings.
What is the stack frame (activation record) in function calls?
A stack frame (activation record) is a memory block on the call stack that contains a function's local variables, parameters, return address, and saved registers. Each function call creates a new stack frame; each return destroys it. Stack frames enable recursion, local variables, and proper function nesting. Stack overflow occurs when too many frames are created (deep recursion).
Can a static function be called from another file?
The static keyword when applied to a function gives it internal linkage, meaning it's only visible within the translation unit (source file) where it's defined. It cannot be accessed from other files even with extern declarations. This is used for helper functions that should not be part of the public API, preventing naming conflicts and improving encapsulation.
What is mutual recursion?
Mutual recursion occurs when two or more functions call each other in a circular manner. For example, function A calls function B, which calls function A, creating indirect recursion. This requires forward declarations since each function needs to know about the other before it's defined. Mutual recursion is useful for parsing nested structures or implementing state machines.
Can we pass arrays by value in C?
In C, arrays cannot be passed by value directly due to array-to-pointer decay. When an array is passed to a function, it decays to a pointer to its first element, so the function receives the address (effectively call by reference). To pass array by value, wrap it in a structure. Modifications to array elements inside function affect the original array.
What is a function pointer and how is it different from normal pointer?
A function pointer stores the address of a function's machine code. It has special declaration syntax: return_type (*ptr_name)(parameter_types). Unlike data pointers, function pointers point to code segment, not data segment. They're used for callbacks, implementing function tables, strategy pattern, and dynamic dispatch. Arithmetic on function pointers is not standard.
What is the difference between recursion and iteration?
Recursion solves problems by having functions call themselves with modified parameters until reaching a base case. Iteration uses loops (for, while, do-while) to repeat operations. Recursion has overhead from stack frames and can cause stack overflow for deep recursion but is elegant for tree/graph problems. Iteration is generally more efficient and uses constant stack space. Any recursive algorithm can be converted to iterative using an explicit stack.
Can a function return a pointer to a local variable?
Returning a pointer to a local (automatic) variable creates a dangling pointer because the variable's memory is freed when the function returns. Accessing it causes undefined behavior. However, returning a pointer to a static local variable is safe because static variables persist for program lifetime. Better alternatives: return pointer to dynamically allocated memory (caller must free) or to caller-provided buffer.