Functions and Scope

Chapter 9: Functions and Scope

Functions allow you to modularize your code, making it reusable and easier to maintain. To master C, you must understand not just how to call functions, but how variables are scoped and how they persist in memory.

I. Function Anatomy

A C function consists of a Return Type, a Name, Parameters, and a Body.

// Prototype (Declaration) - Tells the compiler the function exists
int add(int a, int b);

int main() {
    int sum = add(5, 3); // Call
    return 0;
}

// Definition - The actual implementation
int add(int a, int b) {
    return a + b;
}

II. Scope and Lifetime

The scope of a variable determines where it can be accessed. The lifetime determines when it is allocated and deallocated.

  1. Local (Block) Scope: Variables declared inside {}. They are created on the Stack when the block starts and destroyed when it ends.
  2. Global (File) Scope: Variables declared outside any function. They are stored in the Data Segment and persist for the entire program's life.

III. Storage Classes

Storage classes modify the visibility and lifetime of variables.

KeywordLifetimeScopePurpose
autoStackLocalDefault for local variables.
staticProgramLocalRetains value between function calls.
externProgramGlobalReferences a global variable in another file.
registerCPULocalSuggests the compiler store the variable in a CPU register.
void count_calls() {
    static int count = 0; // Initialized only once
    count++;
    printf("Called %d times\n", count);
}

IV. Passing Arguments: Value vs. Reference

  • Pass by Value: C is default "pass by value." A copy of the argument is made. Changes inside the function do not affect the original.
  • Pass by Reference (via Pointers): By passing the address of a variable, the function can modify the original value. (We will cover this in depth in Chapter 11).

V. The Function Call Stack

Every time a function is called, the CPU creates a Stack Frame. This frame stores the function's parameters, return address, and local variables.

Stack Frame: main()Stack Frame: functionA()Stack Frame: functionB()Stack Growth (Downwards)

Stack Overflow

If you have too many nested function calls (e.g., infinite recursion), the stack will run out of memory, causing the program to crash.

VI. Inline Functions (inline)

The inline keyword (C99) suggests the compiler copy the function's code directly into the caller's code instead of performing a function call. This reduces overhead for small, performance-critical functions.