Unit 2: Functions and Program Structure
Table of Contents
2.1 Functions and Program Structure
A function is a self-contained block of code that performs a specific task. Using functions makes code modular, reusable, and easier to debug.
Defining and Accessing Functions
// Function Definition float calculateAverage(int a, int b) { float avg = (a + b) / 2.0; return avg; } int main() { int x = 10, y = 5; // Function Access (Call) float result = calculateAverage(x, y); printf("Average: %.2f\n", result); return 0; }Passing Arguments to a Function
In C, arguments are passed by Pass-by-Value by default. This means the function receives a copy of the argument's value, and the original variable in the calling function is not changed. (We will see how to change this with pointers in Unit 3).
2.2 Function Prototypes and Return Types
Function Prototypes
A function prototype is a declaration of a function that tells the compiler about its name, return type, and parameters. It is crucial if you define the function after main().
#include <stdio.h> // Function Prototype float calculateAverage(int a, int b); int main() { float result = calculateAverage(10, 5); // Compiler already knows what this is printf("Result: %.2f\n", result); return 0; } // Function Definition float calculateAverage(int a, int b) { return (a + b) / 2.0; }Functions Returning Non-Integers
Functions can return any data type, such as float, double, char, or even pointers (Unit 3) and structures (Unit 4). The calculateAverage function above is an example of a function returning a float.
2.3 Storage Classes and Scope Rules
Storage classes determine a variable's scope, lifetime, and storage location.
| Storage Class | Keyword | Storage | Default Value | Scope | Lifetime |
|---|---|---|---|---|---|
| Automatic | auto (rarely used) | Stack | Garbage | Block (local) | Within the block |
| External | extern | Data Segment | Zero | File (global) | Entire program |
| Static | static | Data Segment | Zero | Block or File | Entire program |
| Register | register | CPU Register (hint) | Garbage | Block (local) | Within the block |
Scope Rules
- Block Structure (Local Scope): A variable declared inside a block
{ ... }is only accessible within that block. - File Scope (Global Scope): A variable declared outside all functions is global and accessible to all functions in that file.
Header Files
Files (e.g., stdio.h, math.h) containing function prototypes and definitions that can be included in our program using #include.
2.4 Recursion in C
Recursion is a process where a function calls itself. A recursive function must have two parts:
- Base Case: A condition that stops the recursion.
- Recursive Step: The part of the function that calls itself, moving closer to the base case.
Problem Solving: Factorial
long factorial(int n) { // 1. Base Case if (n == 0 || n == 1) { return 1; } // 2. Recursive Step else { return n * factorial(n - 1); } }2.5 The C Preprocessor
The preprocessor is a program that processes your source code before it is passed to the compiler. Its directives start with #.
#include: Pastes the content of a header file into your code.#define: Creates a macro, which is a fragment of code that is given a name.- As a constant:
#define PI 3.14159 - As a function-like macro:
#define SQUARE(x) (x * x)
- As a constant:
#define SQUARE(x) ((x) * (x)).