C Notes
Learn how to use pointers with functions in C for pass-by-reference, returning pointers, function pointers, and callback patterns with practical examples.
Functions in C use "pass by value" by default — parameters are copies of the arguments, so changes inside the function don't affect the originals. Pointers solve this limitation by passing the memory address instead, allowing functions to directly modify the caller's variables. This technique is commonly called "pass by reference" (even though technically C only has pass by value — we pass the value of an address).
The Problem: Pass by Value
#include <stdio.h>
void increment(int x) {
x = x + 1; // Modifies the LOCAL copy only
printf("Inside function: x = %d\n", x);
}
int main() {
int num = 10;
increment(num);
printf("After function: num = %d\n", num); // Unchanged!
return 0;
}Inside function: x = 11 After function: num = 10
The Solution: Pass by Reference (Using Pointers)
#include <stdio.h>
void increment(int *x) {
*x = *x + 1; // Modifies the ORIGINAL through address
printf("Inside function: *x = %d\n", *x);
}
int main() {
int num = 10;
increment(&num); // Pass address of num
printf("After function: num = %d\n", num); // Changed!
return 0;
}Inside function: *x = 11 After function: num = 11
| num = 10 | ←──────── | x = &num |
|---|---|---|
| addr: 0x100 |
Classic Example: Swap Function
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
printf("Before: x = %d, y = %d\n", x, y);
swap(&x, &y);
printf("After: x = %d, y = %d\n", x, y);
return 0;
}Before: x = 5, y = 10 After: x = 10, y = 5
Returning Multiple Values from a Function
C functions can only return one value. Pointers let you return multiple results through parameters:
Min = 12, Max = 89 17 / 5 = 3 remainder 2
Returning Pointers from Functions
A function can return a pointer, but you must be careful about what it points to:
❌ WRONG: Returning Pointer to Local Variable
int* badFunction() {
int x = 42;
return &x; // DANGEROUS! x is destroyed after function returns
}
// The returned pointer is DANGLING — points to freed stack memory✅ CORRECT: Return Pointer to Static Variable
#include <stdio.h>
int* getStaticValue() {
static int x = 100; // Persists beyond function call
return &x;
}
int main() {
int *p = getStaticValue();
printf("Value: %d\n", *p); // Safe — static storage
return 0;
}Value: 100
✅ CORRECT: Return Dynamically Allocated Memory
10 20 30 40 50
Function Pointers
A function pointer stores the address of a function and can be used to call it indirectly:
#include <stdio.h>
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int main() {
// Declare function pointer
int (*operation)(int, int);
operation = add;
printf("add(5, 3) = %d\n", operation(5, 3));
operation = subtract;
printf("subtract(5, 3) = %d\n", operation(5, 3));
operation = multiply;
printf("multiply(5, 3) = %d\n", operation(5, 3));
return 0;
}add(5, 3) = 8 subtract(5, 3) = 2 multiply(5, 3) = 15
Callback Functions
Function pointers enable callback patterns — passing a function as an argument:
Original: 1 2 3 4 5 Doubled: 2 4 6 8 10 Squared: 4 16 36 64 100
Using qsort with Function Pointers
The standard library's qsort uses a callback for custom sorting:
Ascending: 12 23 34 45 78 89 Descending: 89 78 45 34 23 12
Summary Table: When to Use Pointer Parameters
| Situation | Use Pointer? | Reason |
|---|---|---|
| Modify caller's variable | ✅ Yes | Only way to change original |
| Return multiple values | ✅ Yes | C functions return only one value |
| Large struct parameter | ✅ Yes | Avoid expensive copy |
| Array parameter | ✅ Always | Arrays always decay to pointers |
| Read-only small value | ❌ No | Pass by value is simpler |
Interview Questions
Q1: What's the difference between pass by value and pass by reference in C?
C technically only has pass by value. "Pass by reference" in C means passing the value of an address (a pointer). The function receives a copy of the address, but since it's the real address, dereferencing it modifies the original variable.
Q2: Why is returning a pointer to a local variable dangerous?
Local variables live on the stack and are deallocated when the function returns. The returned pointer becomes "dangling" — it points to memory that may be reused by other function calls, leading to undefined behavior.
Q3: What is a function pointer and when would you use one?
A function pointer stores the address of a function. Use cases: callback mechanisms (like qsort), plugin architectures, state machines, and implementing polymorphism in C.
Q4: Can a function return a pointer to an array?
Yes, the return type would be int (*func())[N] — a function returning a pointer to an array of N ints. However, it's more common to return int* (pointer to first element) or pass the array as a parameter.
Summary
- Pass addresses (
&variable) to functions when you need them to modify the original - Use pointer parameters (
*param) to accept addresses and dereference to access values - Never return pointers to local (stack) variables — use static, global, or heap memory
- Function pointers enable callbacks, dynamic dispatch, and generic algorithms
- The
qsortpattern demonstrates the power of function pointers for generic code - Always validate pointer parameters against NULL before dereferencing
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Pointers and Functions in C - Pass by Reference.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, pointers, and, functions, pointers and functions in c - pass by reference
Related C Programming Topics