STEP 5 Review: Functions, Scope, Array Arguments, and Recursion

Review the key points with a cheat sheet, six code-reading questions, and a checklist of common mistakes.

① Key-point cheat sheet

Review the essentials of STEP 5 in these tables .

🔧 Function structure

// Return type, function name(parameter type and name, ...) 
int square(int x) {
    return x * x;
}

int main(void) {
    printf("%d\n", square(5)); // 25
}
  • Return type / name / parameters / body : four parts
  • A function with no return value uses void
  • return returns a value (and can exit early)

🎚️ Arguments are passed by value (copied)

void add10(int x) {
    x += 10; // x is a copy 
}
int main(void) {
    int a = 5;
    add10(a);
    printf("%d\n", a); // Still 5! 
}
  • A parameter holds a copy of the value , so changing it inside the function does not change the caller's variable
  • To change the caller's value, use a pointer or return value .

🔭 Scope: where variables are visible

int g = 100;       // Global 

void f(void) {
    int x = 1;     // Local to f 
}
int main(void) {
    int x = 2;     // main's x (a separate variable) 
    f();
    printf("%d %d\n", x, g); // 2 100
}
  • A variable declared inside a function is visible only within its scope in that function (local)
  • A variable declared outside functions is visible from its declaration onward at file scope (global)
  • The same name in different scopes can denote different variables

📐 Passing an array argument

void fill(int a[], int n) {
    for (int i = 0; i < n; i++) a[i] = 7;
}
int main(void) {
    int a[3] = {0};
    fill(a, 3);
    // a becomes {7, 7, 7} 
}
  • An array argument passes the address of its first element (the elements are not copied)
  • Changes to those elements inside the function affect the caller's array
  • For an array parameter, sizeof cannot determine its length; pass the length separately

🔄 Recursion: a function calls itself

int factorial(int n) {
    if (n <= 1) return 1; // Base case! 
    return n * factorial(n - 1);
}
// factorial(4) = 4*3*2*1 = 24
  • Always provide a base case to stop recursion and avoid exhausting the stack
  • Break the task into a smaller problem and call the function again

📋 Function prototypes

// Declare first; define the body later 
int add(int, int);

int main(void) {
    printf("%d\n", add(2, 3));
}

int add(int a, int b) { return a + b; }
  • Before use, tell the compiler the function's interface .
  • For a function defined below main, declare its prototype before main

② Six code-reading questions

Execute the code mentally before choosing an answer. Read the explanation even if you get it wrong.

Q1. Using a return value

int square(int x) { return x * x; }

int main(void) {
    printf("%d\n", square(3) + square(4));
}

What is the output?

12
25
7
49
Explanation: square(3)=9 and square(4)=16, so their sum is 25. These are also the squared sides of a 3–4–5 right triangle.

Q2. Pass by value

void add10(int x) { x += 10; }

int main(void) {
    int a = 5;
    add10(a);
    printf("%d\n", a);
}

What is the output?

5
10
15
Indeterminate
Explanation: The parameter x receives a copy of a. Adding 10 to x does not modify a, so the output is 5. To update a, pass its address or assign a returned result, for example a = add10(a).

Q3. Passing an array

void setZero(int a[], int n) {
    for (int i = 0; i < n; i++) a[i] = 0;
}

int main(void) {
    int a[3] = {7, 8, 9};
    setZero(a, 3);
    printf("%d %d %d\n", a[0], a[1], a[2]);
}

What is the output?

7 8 9 (unchanged)
0 0 0
Indeterminate (treated as uninitialized)
Compilation error
Explanation: Passing an array supplies a pointer to its first element; the elements are not copied. Setting a[i]=0 through that pointer changes the original array, so the output is 0 0 0. The pointer itself is still passed by value.

Q4. Local and global variables

int g = 100;

void f(void) {
    int g = 1; // Local with the same name 
    printf("f: %d\n", g);
}

int main(void) {
    f();
    printf("main: %d\n", g);
}

What is the output?

f: 100
main: 100
f: 1
main: 100
f: 1
main: 1
Compilation error (duplicate name)
Explanation: Inside f, local g=1 shadows global g=100. f therefore prints f: 1; main prints main: 100. The two variables are separate.

Q5. A recursive base case

int fact(int n) {
    if (n <= 1) return 1;
    return n * fact(n - 1);
}
printf("%d\n", fact(4));

What is the output?

10
24
4
Infinite recursion causes a crash
Explanation: fact(4) = 4 × fact(3) = 4 × 3 × fact(2) = 4 × 3 × 2 × fact(1) = 24. The base case n<=1 returns 1 and stops recursion.

Q6. Array size inside a function

void show(int a[]) {
    printf("%zu\n", sizeof a);
}

int main(void) {
    int a[5] = {0};
    show(a);
}

Inside show, what does sizeof a return?

20 (= 5 × 4 bytes)
5
The pointer size (often 8 bytes)
Compilation error
Explanation: In a function parameter, int a[] is adjusted to int *a. Thus sizeof a is the pointer size (often 8 bytes), not the array size. Pass the element count separately, for example void show(int a[], int n).

③ Common mistakes and tricky points

If an item feels familiar, return to its original lesson and review it.
  1. 1
    Expected a changed parameter to update the caller's variable
    Arguments are bound Pass by value (a copy). To change the caller's value, use return value or passing a pointer .
  2. 2
    The declared return type and the type of returndid not match
    int causes a returned double to be converted to int. void combined with return x; is invalid.
  3. 3
    Tried to obtain an array's length inside a function with sizeof.
    An array parameter is treated as a pointer , so array length information is not retained. Pass the length separately .
  4. 4
    Forgot a recursive base case
    Infinite recursion can cause Stack overflow and crash. Write the terminating case first.
  5. 5
    Used a function defined below main without a prototype
    The compiler processes declarations in order, so a function used in main needs a prior declaration .
  6. 6
    Confused local and global variables with the same name
    When the same name is declared locally, the local variable takes precedence (shadowing). Avoid accidental duplicate names.
  7. 7
    Overused global variables
    It becomes difficult to track where values change. Pass data through arguments and return values as the default approach.

④ Lessons to revisit when you get stuck

Use these links to return to the relevant explanation.
Lesson 26: Function basics Review function structure, parameters, and return values Lesson 27: Functions (Advanced) Review pass by value and scope Lesson 30: Prototype & Macro Review forward declarations Lesson 31: Global variables Review scope and visibility Lesson 32: Array arguments Review pointer adjustment and the sizeof trap Quiz (Functions) Check understanding with related questions Recursion Review base cases and smaller subproblems Cheat sheet Review formats and functions on one page