Functions — Call by Value, Call by Reference, Recursion
754 words
4 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Functions — Call by Value, Call by Reference, Recursion ## 🎯 Learning Objectives - Define and call functions with various parameter types - Explain the difference between call by value and call by reference - Write recursive functions and analyze their stack usage - Use function pointers for callbacks * * * ## 1....

Functions — Call by Value, Call by Reference, Recursion
🎯 Learning Objectives
- Define and call functions with various parameter types
- Explain the difference between call by value and call by reference
- Write recursive functions and analyze their stack usage
- Use function pointers for callbacks
1. Function Basics
1.1 Declaration vs Definition
c// Declaration (prototype) — tells compiler the function exists int add(int a, int b); // Definition — provides the implementation int add(int a, int b) { return a + b; } // Call int result = add(5, 3); // 8
1.2 Parameter Passing
Call by value: The function receives a copy of the argument.
cvoid modify(int x) { x = 100; // Only modifies the copy } int main() { int a = 10; modify(a); printf("%d\n", a); // Still 10! }
Call by reference (simulated with pointers): The function receives the address of the argument.
cvoid modify(int *x) { *x = 100; // Modifies the original through pointer } int main() { int a = 10; modify(&a); printf("%d\n", a); // 100 }
1.3 Returning Values
c// Return by value int square(int x) { return x * x; } // Return by pointer (be careful with lifetime!) int* create_int(int value) { int *p = malloc(sizeof(int)); *p = value; return p; // OK — heap memory persists } // WRONG: returning pointer to local variable int* bad_function() { int x = 42; return &x; // Dangling pointer! x destroyed when function returns }
2. Recursion
2.1 Structure
A recursive function calls itself until a base case is reached.
cint factorial(int n) { // Base case if (n <= 1) return 1; // Recursive case return n * factorial(n - 1); }
2.2 Stack Trace
(Diagram)
2.3 Common Recursion Patterns
c// Fibonacci (inefficient — exponential) int fib(int n) { if (n <= 1) return n; return fib(n-1) + fib(n-2); // O(2^n) — many repeated calls! } // Fibonacci (efficient — linear with memoization) int fib_memo(int n, int *memo) { if (n <= 1) return n; if (memo[n] != 0) return memo[n]; memo[n] = fib_memo(n-1, memo) + fib_memo(n-2, memo); return memo[n]; } // Towers of Hanoi void hanoi(int n, char from, char to, char aux) { if (n == 1) { printf("Move disk 1 from %c to %c\n", from, to); return; } hanoi(n-1, from, aux, to); printf("Move disk %d from %c to %c\n", n, from, to); hanoi(n-1, aux, to, from); }
3. Storage Classes
| Storage | Lifetime | Scope | Default Value |
|---|---|---|---|
| auto | Block | Block | Garbage |
| static (local) | Program | Block | 0 |
| static (global) | Program | File | 0 |
| extern | Program | Global | 0 |
| register | Block (hint) | Block | Garbage |
cvoid counter() { static int count = 0; // Initialized once count++; printf("Called %d times\n", count); } int main() { counter(); // Called 1 times counter(); // Called 2 times counter(); // Called 3 times }
4. 📝 Practice Questions
Q1: Explain the output of:void f(int *p) { (*p)++; } int main() { int x = 5; f(&x); printf("%d", x); }Answer: 6. The function receives the address of x and increments the value at that address by 1. Call by reference (via pointer) allows the function to modify the caller's variable. Q2: Convert this iteration to recursion:for (int i=0; i<10; i++) printf("%d ", i);cvoid print_rec(int i, int n) { if (i >= n) return; printf("%d ", i); print_rec(i+1, n); } // Call: print_rec(0, 10);Q3: What is a function pointer? Give an example.Answer: A function pointer stores the address of a function. Used for callbacks and dynamic dispatch. Example:int (*op)(int, int) = add; int result = op(5, 3);Q4: What happens if a recursive function has no base case?Answer: It leads to infinite recursion. Each call consumes stack space until the stack overflows, causing a segmentation fault (stack overflow error). The call stack grows until it hits the OS-imposed limit. Q5: When would you use a static variable inside a function?Answer: When the function needs to remember state between calls without using a global variable. Examples: counters, random seed values, one-time initialization flags.
5. 🔗 Cross-References
- Week 3 - Pointers: Pointer fundamentals for call by reference
- Week 5 - Dynamic Memory: malloc inside functions
- BSCS4022 (OS): Call stack, function calling conventions Join Discord PreviousPointers Deep DiveNextDynamic Memory