Why Do We Need Functions?
Imagine copy-pasting the same 20 lines again and again. Functions let you define once, call many times — the foundation of structured programming in C.
Reusability
Write once, use anywhere. No copy-pasting code blocks.
Modularity
Break a big problem into smaller, manageable sub-problems.
Easy Debugging
Bug in factorial? Fix it in one function — fixed everywhere.
Readability
calculateArea(r) is clearer than 5 raw lines of math.
Anatomy of a C Function
Every function has 4 essential parts. Hover over each highlighted part to learn what it does:
Hover: int | factorial | (int n) | { body } | return
Declaration vs. Definition
These are two different things that beginners often confuse — understand them clearly.
{ }.Function Prototype — Why It Matters
C reads code top to bottom. If you call a function before defining it, the compiler panics — unless you give it a prototype first.
Where to place it?
Before main(), usually at the top of the file or inside a .h header file.
Names are optional
int add(int, int); is a valid prototype — parameter names can be omitted.
Header Files
#include <stdio.h> gives you prototypes for printf, scanf, etc.
Calling a Function — What Happens Inside?
When you call a function, control jumps to it. After it finishes, control returns back to exactly where it left off.
🔍 What’s Happening?
Variable Scope — Who Can See What?
A variable’s scope is where it can be accessed. Each function creates its own private space — variables inside it are invisible to outsiders.
Declared outside all functions. Visible to every function. Lives for the entire program duration. Auto-initialized to 0.
Declared inside main(). Only visible inside main(). Destroyed when main() returns. Contains garbage if not initialized.
A local variable named count shadows (hides) the global count within that function. Dangerous — avoid same names!
Scope Rules at a Glance
Scope rules prevent the most common bugs — accessing a destroyed variable, or accidentally modifying a global.
| Variable Type | Declared Where? | Accessible In | Lifetime | Default Value |
|---|---|---|---|---|
| Local Variable | Inside a function / block { } | Only that block | Created on call, destroyed on return | Garbage (undefined!) |
| Global Variable | Outside all functions | Entire program | Whole program execution | 0 (auto-initialized) |
| Formal Parameter | Function parameter list | Only that function | Created on call, destroyed on return | Caller’s value (copy) |
| Block Variable | Inside if / for / while | Only that block | Block entry → block exit | Garbage |
Avoid Globals When Possible
Any function can modify them — creates hidden side-effects and makes debugging hard.
Local Vars Die on Return
Never return a pointer to a local variable — that memory is released after the function ends!
Nested Function Calls
C functions can call other functions. This creates a chain of calls — each with its own local scope. Control flows back like a stack of trays.
Complete Working Example
One program demonstrating: prototype, definition, calling, local scope, global variable, and nested calls — all together.
🖥️ Expected Output
n=4 sq=16 cube=64
Total calls: 6
✅ Concepts Used
- Global
callCount— shared across all - Prototypes — all 3 declared before main
- Local Scope —
resultin square() only - Nested Call — cube() calls square()
- void Function — printPowers returns nothing
Quick Quiz 🎯
6 questions covering functions, scope, prototypes, and nested calls.