Computer ScienceUnit 414 min read
Functions & Recursion in C: Definitions, Calls, Scope & Recursion
Unit 4 of Computer Science teaches how to write modular C programs using functions (definition, calling, scope, parameters) and recursion (base case, recursive case, stack usage), with solved examples and NEB-style questions.
TAKEAWAYS:
- A function is a reusable block of code with a name, parameters, return type, and body that performs a specific task.
- Function calls transfer control to the function, pass arguments, and return a value (if any) to the caller.
- Scope rules determine where variables are accessible: local (inside function), global (entire program), and formal parameters (inside function only).
- Recursion is a function calling itself to solve smaller subproblems, requiring a base case (stopping condition) and a recursive case (progress toward base).
- Pass-by-value copies the argument, while pass-by-reference (using pointers) modifies the original variable.
- NEB exams test function prototypes, scope conflicts, recursive logic, and debugging—practice tracing and writing both iterative and recursive solutions.
1. What is a Function?
A function is a named block of code that performs a specific task. It helps in:
- Code reusability: Write once, use many times.
- Modularity: Break large programs into smaller, manageable parts.
- Readability: Give meaningful names to functions (e.g.,
calculateSum()instead ofmain()doing everything).
Parts of a Function
return_type function_name(parameter_list) {
// Function body
return value; // Optional, if return_type is not void
}
- Return type: Data type of the value returned (e.g.,
int,float,void). - Function name: Identifier (e.g.,
addNumbers). - Parameter list: Inputs to the function (e.g.,
(int a, int b)). - Function body: Statements inside
{}. - Return statement: Sends a value back to the caller (only for non-
voidfunctions).
(A labeled diagram showing the structure of a function with arrows pointing to return_type, function_name, parameters, and body.)
2. Defining and Calling Functions
Example: Adding Two Numbers
// Function definition
int add(int x, int y) {
return x + y;
}
int main() {
int a = 5, b = 7, sum;
sum = add(a, b); // Function call
printf("Sum = %d", sum); // Output: Sum = 12
return 0;
}
Key Points:
- The function
add()is defined beforemain()(or declared with a prototype). add(a, b)is a function call whereaandbare arguments passed toxandy.- The returned value (
x + y) is stored insum.
TRACE EXAMPLE: Step-by-Step Execution
flowchart TD
A["main() starts"] --> B["a=5, b=7"]
B --> C["sum = add(a, b)"]
C --> D["add() called\nx=5, y=7"]
D --> E["return 5+7=12"]
E --> F["sum = 12 in main()"]
F --> G["Print 'Sum = 12'"](Shows how control moves from main() to add() and back.)
3. Types of Functions
| Type | Description | Example |
|---|---|---|
| Library Function | Predefined in C (e.g., printf(), scanf()). |
printf("Hello"); |
| User-defined | Written by the programmer. | int square(int n) |
| Recursive | Calls itself to solve a problem. | factorial(n) |
| Void Function | Does not return a value (return_type = void). |
void displayMessage() |
| Value-returning | Returns a value (e.g., int, float). |
int max(int a, int b) |
4. Function Prototypes
If a function is defined after main(), declare it first with a prototype:
int add(int, int); // Prototype (no body)
int main() {
int sum = add(3, 4); // Call before definition
return 0;
}
int add(int x, int y) { // Definition
return x + y;
}
Why?
- Tells the compiler about the function’s name, parameters, and return type before it’s used.
- Helps catch errors early (e.g., wrong number of arguments).
5. Scope of Variables
Variables can be:
- Local: Inside a function (accessible only there).
- Global: Outside all functions (accessible everywhere).
- Formal parameters: Inside a function (like local variables).
Example: Scope Conflict
int x = 10; // Global variable
void display() {
int x = 20; // Local variable (hides global x)
printf("Local x = %d\n", x); // Output: 20
}
int main() {
printf("Global x = %d\n", x); // Output: 10
display();
return 0;
}
Output:
Global x = 10
Local x = 20
Key Rule:
- If a local variable and global variable have the same name, the local one is used inside the function.
(A diagram showing global variables in the outer box, local variables inside function boxes, and arrows showing accessibility.)
6. Passing Arguments: Call by Value vs. Call by Reference
| Method | Description | Example | Modifies Original? |
|---|---|---|---|
| Call by Value | Copies the argument’s value (original unchanged). | void swap(int a, int b) |
❌ No |
| Call by Reference | Passes the address (modifies original). Uses & and *. |
void swap(int *a, int *b) |
✅ Yes |
sequenceDiagram
participant main as main()
participant swap as swap(int*, int*)
main->>swap: swap(&x, &y) (x=5, y=10)
swap->>main: *a=10, *b=5 (modifies original)
main-->>main: x=10, y=5
note right of main: Call by Reference
sequenceDiagram
participant main as main()
participant add as add(int, int)
main->>add: add(5, 10) (copies values)
add-->>main: returns 15 (originals unchanged)
note right of main: Call by ValueSequence diagrams comparing call-by-value (no change) vs. call-by-reference (modifies original)Example: Call by Reference (Swapping)
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
swap(&x, &y); // Pass addresses
printf("x = %d, y = %d", x, y); // Output: x = 10, y = 5
return 0;
}
Why * and &?
&x→ Address ofx.*a→ Value at addressa.
(A diagram showing two boxes: one with a copy of the value (call by value) and one with an arrow pointing to the original variable (call by reference).)
7. Recursion in C
Recursion is when a function calls itself to solve smaller instances of the same problem.
Parts of a Recursive Function
- Base Case: Stops the recursion (prevents infinite calls).
- Recursive Case: Calls the function again with a modified input.
Example: Factorial Using Recursion
int factorial(int n) {
if (n == 0 || n == 1) // Base case
return 1;
else
return n * factorial(n - 1); // Recursive case
}
int main() {
int num = 5, result = factorial(num);
printf("Factorial of %d = %d", num, result); // Output: 120
return 0;
}
Trace for factorial(3):
Output: 3 * 2 * 1 = 6
Key Rules for Recursion
- Must have a base case (otherwise, infinite recursion → stack overflow).
- Each call should move closer to the base case (e.g.,
n-1in factorial). - Avoid excessive recursion (slows down the program).
(A stack diagram showing calls to factorial(3), factorial(2), factorial(1), and the return values.)
8. Advantages and Disadvantages of Functions
| Advantages | Disadvantages |
|---|---|
| ✅ Reusable code | ❌ Overhead of function calls |
| ✅ Easier debugging (smaller chunks) | ❌ Recursion can cause stack overflow |
| ✅ Modularity (easy to update/maintain) | ❌ May reduce performance (vs. loops) |
| ✅ Improves readability | ❌ Complexity in passing arguments |
| Recursion Pros | Recursion Cons |
|---|---|
| ✅ Elegant solution for divide-and-conquer problems | ❌ High memory usage (stack frames) |
| ✅ Simpler code for problems like trees/graphs | ❌ Slower than iteration for some cases |
| ✅ Natural fit for mathematical definitions | ❌ Risk of stack overflow for large n |
9. Common Errors and Debugging
| Error | Cause | Fix |
|---|---|---|
| Undefined function | Function called but not defined/prototyped | Add prototype or define before main() |
| Wrong return type | Function returns int but declared void |
Match return type and actual return |
| Infinite recursion | Missing/base case or no progress toward it | Add proper base case |
| Segmentation fault | Dereferencing invalid pointer | Check pointer validity |
| Garbage output | Using global variable when local is intended | Rename variables to avoid conflicts |
EXAM TIP:
- NEB often tests:
- Function prototypes (order of definition vs. call).
- Scope conflicts (global vs. local variables).
- Recursive logic (trace
factorial(4)orfibonacci(5)). - Call by value/reference (when to use
*and&).
- Practice:
- Write a function to check if a number is prime (recursive/iterative).
- Debug a program with scope errors.
- Convert an iterative loop to recursion (e.g., sum of first
nnumbers).
10. NEB-Style Questions and Solutions
Question 1: Function Definition and Call
Write a function int power(int base, int exp) to calculate base^exp using recursion. Call it in main() to print 2^3.
Solution:
#include <stdio.h>
int power(int base, int exp) {
if (exp == 0) // Base case
return 1;
else
return base * power(base, exp - 1); // Recursive case
}
int main() {
int result = power(2, 3);
printf("2^3 = %d", result); // Output: 8
return 0;
}
Question 2: Scope and Global Variables
What will the following program print?
int x = 5;
void display() {
int x = 10;
printf("%d ", x);
}
int main() {
display();
printf("%d", x);
return 0;
}
Answer:
10 5
Explanation:
- Inside
display(),xis local (10). - In
main(),xis global (5).
Question 3: Call by Value vs. Reference
Modify the following program to swap two numbers using call by reference:
void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 5, y = 10;
swap(x, y);
printf("x = %d, y = %d", x, y); // Output: x = 5, y = 10 (no swap)
return 0;
}
Solution:
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
swap(&x, &y); // Pass addresses
printf("x = %d, y = %d", x, y); // Output: x = 10, y = 5
return 0;
}
Question 4: Recursive Function
Write a recursive function to print numbers from n to 1.
Solution:
void printNumbers(int n) {
if (n == 0) // Base case
return;
printf("%d ", n);
printNumbers(n - 1); // Recursive call
}
int main() {
printNumbers(5); // Output: 5 4 3 2 1
return 0;
}
11. Summary Table: Key Concepts
| Concept | Syntax/Example | Key Point |
|---|---|---|
| Function Definition | int add(int a, int b) |
Must match prototype |
| Function Call | result = add(3, 4); |
Pass arguments in order |
| Scope | int x = 10; (global) |
Local hides global if names clash |
| Call by Value | void func(int x) |
Original unchanged |
| Call by Reference | void func(int *x) |
Uses & and * to modify original |
| Recursion | factorial(n) = n * factorial(n-1) |
Needs base case + progress toward it |
12. Final Tips for NEB Exam
- Always declare functions before
main()(or use prototypes) to avoid errors. - Trace recursive functions step-by-step (NEB loves this!).
- Watch out for scope conflicts—rename variables if needed.
- Use
*and&correctly for call by reference. - Practice writing both iterative and recursive solutions (e.g., factorial, Fibonacci).
(A checklist with icons for: prototypes, scope, recursion trace, call by reference, debugging.)
Based on the NEB +2 Management syllabus for Computer Science (Comp), unit 4.
Discussion
Loading…