Functions
Master this concept with detailed explanations and interactive coding examples.
Interview Questions & Answers
Technical InterviewFunctions
Functions are the building blocks of C programs, enabling modularity, code reuse, and abstraction. This section covers function fundamentals, parameter passing, recursion, function pointers, and advanced function-related concepts.
1. What is a Function in C?
A function is a block of code that performs a specific task. It runs only when it is called.
Why do we use functions?
- To avoid code repetition
- To make programs modular
- To improve readability
- To simplify debugging and testing
Example: Simple Function
#include <stdio.h>
void greet() {
printf("Hello, Welcome to C Programming!\n");
}
int main() {
greet();
return 0;
}
Explanation: The function greet() prints a message. It is called inside main().
2. What are the Parts of a Function?
A function in C has three main parts:
- Declaration (Prototype)
- Definition
- Function Call
Example:
#include <stdio.h>
// Function Declaration
int add(int, int);
int main() {
int result = add(5, 3); // Function Call
printf("Sum = %d", result);
return 0;
}
// Function Definition
int add(int a, int b) {
return a + b;
}
Explanation:
- Declaration tells the compiler about the function.
- Definition contains the actual logic.
- Call executes the function.
3. Types of Functions in C
Functions are mainly of two types:
1. Library Functions
Built-in functions provided by C standard library.
Example: printf(), scanf(), sqrt()
2. User-defined Functions
Functions created by the programmer.
4. Types of User-Defined Functions (Based on Arguments & Return Type)
Case 1: No Arguments, No Return Value
#include <stdio.h>
void showMessage() {
printf("This function has no arguments and no return value.");
}
int main() {
showMessage();
return 0;
}
Case 2: Arguments but No Return Value
#include <stdio.h>
void printSum(int a, int b) {
printf("Sum = %d", a + b);
}
int main() {
printSum(4, 6);
return 0;
}
Case 3: No Arguments but Return Value
#include <stdio.h>
int getNumber() {
return 10;
}
int main() {
int num = getNumber();
printf("Number = %d", num);
return 0;
}
Case 4: Arguments and Return Value
#include <stdio.h>
int multiply(int x, int y) {
return x * y;
}
int main() {
int result = multiply(5, 4);
printf("Multiplication = %d", result);
return 0;
}
5. What is the Difference Between Call by Value and Call by Reference?
Call by Value
Copy of variable is passed. Original value does not change.
#include <stdio.h>
void change(int x) {
x = 100;
}
int main() {
int a = 10;
change(a);
printf("Value of a = %d", a);
return 0;
}
Output: Value of a = 10
Call by Reference (Using Pointers)
Address is passed. Original value changes.
#include <stdio.h>
void change(int *x) {
*x = 100;
}
int main() {
int a = 10;
change(&a);
printf("Value of a = %d", a);
return 0;
}
Output: Value of a = 100
6. What is Recursion in C?
Recursion is when a function calls itself.
Example: Factorial Using Recursion
#include <stdio.h>
int factorial(int n) {
if(n == 0)
return 1;
else
return n * factorial(n - 1);
}
int main() {
int num = 5;
printf("Factorial = %d", factorial(num));
return 0;
}
Explanation: Function keeps calling itself until base condition (n == 0) is met.
7. What are Inline Functions?
Inline functions suggest the compiler to insert function code directly at the call location to reduce overhead.
#include <stdio.h>
inline int square(int x) {
return x * x;
}
int main() {
printf("Square = %d", square(6));
return 0;
}
8. What is a Static Function?
A static function is visible only within the same source file.
#include <stdio.h>
static void display() {
printf("Static function example");
}
int main() {
display();
return 0;
}
9. What is a Function Pointer?
A function pointer stores the address of a function.
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int (*ptr)(int, int);
ptr = add;
printf("Sum = %d", ptr(3, 4));
return 0;
}
10. Practice Questions (Important for Exams & Interviews)
- Write a function to check whether a number is prime.
- Write a function to reverse a number.
- Write a recursive function to calculate Fibonacci series.
- Write a function to swap two numbers using call by reference.
- Write a function to find the largest among three numbers.
Interactive Code Playground
Live CodingTips:
- Use Ctrl + Enter to run code
- Include <stdio.h> for printf/scanf
- main() function must return int
Sample Snippets:
Detailed Explanation
FunctionsUnderstanding Functions in C
A function in C is a self-contained block of code that performs a specific task. Functions are the building blocks of C programs that promote code reusability, modularity, and easier debugging. Every C program must have at least one function, which is main().
- Function Declaration (Prototype) - Tells the compiler about the function's name, return type, and parameters. Ends with a semicolon.
- Function Definition - Contains the actual body of the function with the code to be executed.
- Function Call - Executes the function by passing control and arguments (if any) to it.
- Return Value - The value a function sends back to the caller using the
returnstatement. - Parameters - Variables that receive values passed to the function (formal parameters) or sent during call (actual parameters).
- Scope - Variables inside functions have local scope and are destroyed when the function exits.
Key Points to Remember:
return_type function_name(parameter_list) { // body } - Every function follows this basic structure.
C uses pass-by-value by default. The function receives copies of arguments; original values remain unchanged.
Using pointers, you can simulate pass-by-reference, allowing functions to modify original variables.
A function that calls itself. Useful for problems like factorial, Fibonacci, tree traversal.
Expert Interview Tips:
When explaining functions, always start with the 'why' - code reusability, modularity, and abstraction. Then move to 'how' - syntax and examples.
Common mistake: Forgetting to declare function prototypes before main() leads to implicit declaration warnings/errors. Always prototype or define before first use.
Pro tip: Use static functions to limit scope to the file - great for encapsulation and information hiding.
Common Follow-up Questions:
Function Declaration (Prototype): Tells the compiler about function name, return type, and parameters. Ends with semicolon. Example: int add(int, int);
Function Definition: Contains the actual body/code of the function. Example: int add(int a, int b) { return a + b; }
Function Call: Executes the function. Example: result = add(5, 3);
#include <stdio.h>
// Declaration
int multiply(int x, int y);
int main() {
// Function call
int result = multiply(4, 5);
printf("Result: %d\n", result);
return 0;
}
// Definition
int multiply(int x, int y) {
return x * y;
}
Pass by value: A copy of the argument's value is passed to the function. Changes inside the function do not affect the original variable.
Pass by reference (simulated): Using pointers, the address of the variable is passed. The function can dereference the pointer to modify the original variable.
C strictly uses pass-by-value, but pointers allow us to achieve pass-by-reference behavior.
#include <stdio.h>
void passByValue(int a) {
a = 100; // Only changes local copy
}
void passByReference(int *a) {
*a = 100; // Changes original variable via pointer
}
int main() {
int x = 10, y = 10;
passByValue(x);
printf("After passByValue: x = %d\n", x); // Still 10
passByReference(&y);
printf("After passByReference: y = %d\n", y); // Now 100
return 0;
}
Recursion is a technique where a function calls itself to solve a smaller instance of the same problem. It consists of a base case (stopping condition) and a recursive case.
Advantages: Elegant, clean code for problems with recursive nature (tree traversal, divide-and-conquer).
Disadvantages: Consumes more stack memory, can lead to stack overflow if too deep, sometimes slower due to function call overhead.
#include <stdio.h>
// Factorial using recursion
int factorial(int n) {
// Base case
if (n <= 1) {
return 1;
}
// Recursive case
return n * factorial(n - 1);
}
// Fibonacci using recursion
int fibonacci(int n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
int main() {
printf("Factorial of 5: %d\n", factorial(5));
printf("Fibonacci(6): %d\n", fibonacci(6));
return 0;
}
Static functions are functions declared with the static keyword at file scope. They have internal linkage, meaning they are only visible within the file where they are defined.
Differences:
- Normal functions: Have external linkage by default, accessible from other files using
externdeclarations. - Static functions: Limited to the same file, cannot be called from other files. Provides encapsulation and information hiding.
/* File: helper.c */
static int privateHelper() {
return 42; // Only accessible within helper.c
}
int publicFunction() {
return privateHelper() * 2; // Can call static function here
}
/* File: main.c */
extern int publicFunction(); // OK
// extern int privateHelper(); // ERROR! Cannot access static function from other file
Inline functions are functions defined with the inline keyword. They suggest to the compiler to replace the function call with the actual function code, avoiding function call overhead for small, frequently used functions.
Benefits:
- Reduces function call overhead (stack push/pop, jump).
- Can lead to faster execution for small functions.
- Better than function-like macros (type checking, no side effects).
Note: inline is a request, not a command. The compiler may ignore it for large functions or when optimizations are disabled.
#include <stdio.h>
// Inline function definition
static inline int square(int x) {
return x * x;
}
int main() {
int result = square(5); // Compiler may replace with 5*5 directly
printf("Square: %d\n", result);
// Equivalent to: int result = 5 * 5;
return 0;
}
Function pointers store the address of a function, allowing functions to be passed as arguments, stored in arrays, or assigned to variables. Syntax: return_type (*pointer_name)(parameter_types);
Use cases:
- Callback functions (e.g., event handlers, sorting comparators).
- Implementing state machines or jump tables.
- Dynamic function dispatch (like polymorphism in C).
#include <stdio.h>
// Two functions with same signature
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
// Function that takes a function pointer as parameter
int operate(int x, int y, int (*operation)(int, int)) {
return operation(x, y);
}
int main() {
// Declare and initialize function pointer
int (*func_ptr)(int, int) = &add;
// Call via function pointer
printf("Add: %d\n", func_ptr(5, 3));
// Change to another function
func_ptr = multiply;
printf("Multiply: %d\n", func_ptr(5, 3));
// Pass as argument
printf("Operate (add): %d\n", operate(10, 5, add));
printf("Operate (multiply): %d\n", operate(10, 5, multiply));
// Array of function pointers
int (*operations[])(int, int) = {add, multiply};
printf("Array[0]: %d\n", operations[0](4, 2));
return 0;
}
When a function is called, a stack frame (or activation record) is created on the call stack. It contains:
- Return address: Where to continue after function returns.
- Function parameters: Values passed to the function.
- Local variables: Memory for variables declared inside the function.
- Saved registers: CPU register values to restore after return.
When the function returns, its stack frame is popped, and control returns to the saved address.
High Address → +------------------+
| Caller's frame |
+------------------+
| Return Address |
+------------------+
| Parameters |
+------------------+
| Local Variables | ← Current function's stack frame
+------------------+
| Saved Registers |
+------------------+
| ... (next call) |
Low Address → +------------------+