0 · Recall Warm-up
Answer from memory first. Answers are in the Answer Vault at the bottom.
- In C, what does a function receive when you pass it a variable? from Lesson 1.3.1
- Which if does an else belong to? from Lesson 1.2.1
- How many handshakes among 8 people, each pair once? from Lesson 0.2.2
1 · The Hook
🎣
A school has a notice board in the main hall that everyone can read, a whiteboard in each classroom that only that class sees and that is wiped every evening, and a teacher’s diary that stays in her drawer from year to year. Variables in C come in the same three kinds: who can see them, and how long they last.
2 · Predict First
🤔
What does this program print?
void counter(void)
{
static int c = 0;
int d = 0;
c++;
d++;
printf("c=%d d=%d\n", c, d);
}
int main(void)
{
counter();
counter();
counter();
return 0;
}
Make a guess in your head. The answer opens Section 3.
3 · Core Concept
💡
Predict First — the answer
Output
c=1 d=1
c=2 d=1
c=3 d=1
d is created fresh (as 0) on every call. c is static: it is created once, before the program starts, and keeps its value between calls, so it counts 1, 2, 3.
Scope vs lifetime
Scope is the part of the program text where a name can be used. Lifetime is the period during the run when the variable’s memory exists. They are different questions: a static local has a small scope (one function) but a whole-program lifetime.
Local (automatic) variables
A variable declared inside a function or block is local: visible only from its declaration to the end of that block, created each time the block is entered, destroyed when it is left. Without a first value it holds garbage. Parameters are locals too.
Global variables
A variable declared outside every function is global: visible from its declaration to the end of the file, alive for the whole run, and automatically set to 0 if not initialized.
int total; /* global: starts at 0 */
void add(int v)
{
total = total + v;
}
int main(void)
{
add(5);
add(7);
printf("%d\n", total);
return 0;
}
Output
12
Shadowing
A declaration in an inner block may reuse a name; inside that block it hides (shadows) the outer one. When the block ends, the outer variable is visible again, unchanged.
int x = 1; /* global */
int main(void)
{
printf("%d ", x);
int x = 2; /* local x shadows the global x */
printf("%d ", x);
{
int x = 3; /* block x shadows the local x */
printf("%d ", x);
}
printf("%d\n", x);
return 0;
}
Output
1 2 3 2
static local variables
static int c = 0; inside a function: scope is the function, lifetime is the whole run. It is initialized once (to 0 if no value is given) and keeps its value between calls. The initializer must be a constant.
static and extern at file level
staticon a global variable or function makes it visible only inside its own source file.extern int limit;is a declaration without a definition: “a variable named limit exists, defined somewhere else” (later in this file or in another file). Exactly one definition must exist.
extern int limit; /* declaration only: defined further down */
int main(void)
{
printf("%d\n", limit * 2);
return 0;
}
int limit = 21; /* the definition */
Output
42
register
register int i; is an old hint to keep a local variable in a processor register for speed. Compilers today decide that themselves; the one lasting rule is that you may not ask for a register variable’s memory address.
Summary of storage classes
| Declared | Scope | Lifetime | First value if none given |
|---|---|---|---|
| local (auto) | its block | each entry to the block | garbage |
| static local | its block | whole run, initialized once | 0 |
| global | rest of the file (other files via extern) | whole run | 0 |
| static global | rest of this file only | whole run | 0 |
| register | its block | each entry to the block | garbage |
4 · Visual
Lifetime along a run that calls counter() three times:
time ------------------------------------------------------------->
main [=================================================================]
c [=================================================================] static: one box, kept
call1 [====] d=1
call2 [====] d=1 auto: new box per call
call3 [====] d=1
c after each call: 1 2 3
A static local lives as long as the program; an automatic local is born and dies with each call.
Where variables live: globals and statics in a fixed area; locals in a region that grows and shrinks as functions are called (Lesson 1.3.3).
5 · Worked Examples
Example 1 Easy
What does this print?
int x = 1; /* global */
int main(void)
{
printf("%d ", x);
int x = 2; /* local x shadows the global x */
printf("%d ", x);
{
int x = 3; /* block x shadows the local x */
printf("%d ", x);
}
printf("%d\n", x);
return 0;
}
Solution
The first printf sees the global (1). After int x = 2; the local hides it (2). Inside the inner block, x is 3. After the block, the local x (2) is visible again.
Output
1 2 3 2
Example 2 Medium
What does this print?
int f(void)
{
static int s = 5;
s = s * 2;
return s;
}
int main(void)
{
int a = f();
int b = f();
int c = f();
printf("%d %d %d\n", a, b, c);
return 0;
}
Solution
s starts at 5 once. Call 1: 10. Call 2: 20. Call 3: 40 — s remembers.
Output
10 20 40
Example 3 GATE
What does this print?
int x = 10;
int f(void)
{
static int y = 1;
int z = 1;
x = x + y;
y = y + 2;
z = z + 1;
return x + y + z;
}
int main(void)
{
int a = f();
int b = f();
printf("%d %d %d\n", a, b, x);
return 0;
}
Solution
| call | x | y (static) | z (local) | returns |
|---|---|---|---|---|
| f() #1 | 10 + 1 = 11 | 1 → 3 | 1 → 2 | 11 + 3 + 2 = 16 |
| f() #2 | 11 + 3 = 14 | 3 → 5 | 1 → 2 | 14 + 5 + 2 = 21 |
x is global and y is static, so both carry over from call 1 to call 2; z is a fresh local (1, then 2) in every call. Each call adds the current y to x before y grows by 2. After both calls x is 14.
Output
16 21 14
6 · GATE Traps
⚠️
- A static local is initialized only once, not on every call.
- Globals and statics start at 0; locals start with garbage.
- Shadowing hides the outer variable only inside the inner block; the outer value is unchanged.
extern int x;declares but does not define; without a definition somewhere the program cannot be built.- Scope (where visible) and lifetime (how long it exists) are different properties.
8 · Memory Hook
🧠
Whiteboard, notice board, diary. Locals are classroom whiteboards wiped after every lesson; globals are the hall notice board; a static local is the teacher’s private diary: only she reads it, but it survives every class.
9 · Connect the Dots
Lesson 1.3.1 created fresh parameters on every call; this lesson named that “automatic lifetime” and contrasted it with static storage. Next lesson answers: where are the automatic variables of all the active calls kept, and how does the program know where to return after each call?
10 · Self-Test
GATE format. Try every question before opening the vault.
Q1MCQ1 markStatic
What does this print?
int f(void)
{
static int s = 5;
s = s * 2;
return s;
}
int main(void)
{
int a = f();
int b = f();
int c = f();
printf("%d %d %d\n", a, b, c);
return 0;
}
- (A)
10 20 30 - (B)
10 10 10 - (C)
5 10 20 - (D)
10 20 40
Q2MCQ2 marksScope
What does this print?
int a = 5;
void show(void)
{
printf("%d ", a);
}
int main(void)
{
int a = 9;
show();
{
int a = 1;
printf("%d ", a);
}
printf("%d\n", a);
return 0;
}
- (A)
5 1 1 - (B)
9 1 9 - (C)
5 1 9 - (D)
9 1 5
Q3MSQ1 markStorage classes
Which statements are true?
- (A) A local variable with no initializer starts at 0.
- (B) extern declares a variable without defining it.
- (C) A static local variable is created again on each call.
- (D) A global int with no initializer starts at 0.
Q4MCQ1 markLifetime
A variable declared static inside a function has:
- (A) file scope and whole-program lifetime
- (B) file scope and function lifetime
- (C) function scope and function lifetime
- (D) function scope and whole-program lifetime
Q5NAT2 marksStatic accumulator
What does this print?
int g(int n)
{
static int acc;
acc = acc + n;
return acc;
}
int main(void)
{
g(1);
g(2);
printf("%d\n", g(3) + g(4));
return 0;
}
Numerical answer: ________
11 · Rule Card
- Scope = where a name is visible; lifetime = when its memory exists.
- Local/auto: block scope, born and destroyed with the block, garbage start.
- Global: file scope (extern elsewhere), whole run, starts at 0.
- static local: block scope, whole run, initialized once (0 default), keeps value.
- static global/function: this file only. extern: declaration, not definition.
- Inner declarations shadow outer ones inside their block only.
- register: hint; its address may not be taken.
12 · Concept Ledger
Unlocked in this lesson. From here on, these terms may be used.
scopelifetimelocal (automatic) variableglobal variableblockshadowingstatic local variablestatic globalexternregisterstorage class
13 · Answer Vault
Answer Vault
Try the questions first. Open when you are ready to check.
Recall Warm-up
- A copy of the variable’s value (call by value).
- The nearest unmatched if above it.
- 28 (8C2).
Self-Test
Q1 Answer: (D)1 mark
s keeps its value between calls and doubles each time.
Output
10 20 40
- (A) is wrong: It doubles; it does not add 10.
- (B) is wrong: A static is not reset on each call.
- (C) is wrong: s is doubled before being returned.
Re-read: Lesson 1.3.2 — Scope vs lifetime; local, global, static, extern, register; shadowing in blocks; static local variables
Q2 Answer: (C)2 marks
show() sees only the global a (5): main’s local a is not visible inside another function. Then the block a (1), then main’s a (9).
Output
5 1 9
- (A) is wrong: The block’s a disappears after the block.
- (B) is wrong: show() cannot see main’s local a.
- (D) is wrong: The last printf is in main, where a is 9.
Re-read: Lesson 1.3.2 — Scope vs lifetime; local, global, static, extern, register; shadowing in blocks; static local variables
Q3 Answer: (B) (D)1 mark
Statics are created once; locals start with garbage.
- (A) is wrong: Locals hold garbage until assigned.
- (C) is wrong: It is created once for the whole run.
Re-read: Lesson 1.3.2 — Scope vs lifetime; local, global, static, extern, register; shadowing in blocks; static local variables
Q4 Answer: (D)1 mark
Visible only in its function, but alive for the whole run.
- (A) is wrong: It is visible only inside the function.
- (B) is wrong: It is not visible outside the function.
- (C) is wrong: It outlives each call.
Re-read: Lesson 1.3.2 — Scope vs lifetime; local, global, static, extern, register; shadowing in blocks; static local variables
Q5 Answer: 162 marks
acc: 1, 3, then g(3) = 6 and g(4) = 10 (the order of these two calls does not matter for the sum): 6 + 10 = 16.
Output
16
Re-read: Lesson 1.3.2 — Scope vs lifetime; local, global, static, extern, register; shadowing in blocks; static local variables