0 · Recall Warm-up
Answer from memory first. Answers are in the Answer Vault at the bottom.
- How many times does
for (i = 1; i <= n; i *= 2)run for n = 20? from Lesson 1.2.2 - What does
(int)-3.99give? from Lesson 1.1.3 - What is ⌈log₂ 1000⌉? from Lesson 0.2.1
1 · The Hook
🎣
A canteen app computes the bill for every customer: price times quantity, plus tax. Writing those lines again for each customer copies mistakes everywhere. Instead we write the calculation once, give it a name, and call it with different inputs, the way you press the same calculator button with different numbers.
2 · Predict First
🤔
What does this program print?
void change(int x)
{
x = 100;
}
int main(void)
{
int a = 5;
change(a);
printf("%d\n", a);
return 0;
}
Make a guess in your head. The answer opens Section 3.
3 · Core Concept
💡
Predict First — the answer
Output
5
change receives a copy of a’s value. Setting the copy to 100 does not touch a. This is call by value, C’s only way of passing arguments.
Defining a function
return_type name(type1 param1, type2 param2)
{
statements;
return value; /* hands a value back to the caller */
}
The parameters are local variables of the function that receive the values passed in. A function that returns nothing has return type void; it may use a bare return; to finish early.
Calling a function
A call name(arg1, arg2) evaluates the arguments, copies their values into the parameters, runs the body, and replaces the call by the returned value.
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
int main(void)
{
printf("%d %d\n", max(3, 8), max(-2, -9));
return 0;
}
Output
8 -2
return ends the function at once; any statements after it are skipped.
Declaration (prototype) and definition
The compiler reads top to bottom, so a function must be declared before it is called. If its definition (the body) comes later, put a prototype first: the header followed by a semicolon. This is the “declaration that is not a definition” promised in Lesson 1.1.1.
int square(int n); /* declaration (prototype) */
int main(void)
{
printf("%d\n", square(7));
return 0;
}
int square(int n) /* definition */
{
return n * n;
}
Output
49
Call by value
Every argument is copied. Changing a parameter changes only the copy; the caller’s variable is untouched. So a function cannot swap two of the caller’s variables by working on their values:
void swap(int a, int b)
{
int t = a;
a = b;
b = t;
printf("inside: %d %d\n", a, b);
}
int main(void)
{
int x = 1, y = 2;
swap(x, y);
printf("outside: %d %d\n", x, y);
return 0;
}
Output
inside: 2 1
outside: 1 2
Calls inside expressions
A call is an expression, so calls can be nested and combined: square(add(2, 3)) first computes add(2, 3) = 5, then square(5). The order in which the arguments of one call are evaluated is not fixed by C, so f(i++, i++) is undefined behavior.
4 · Visual
int a = 5; change(a); (call by value)
main's box change's box
+-------+ +-------+
| a = 5 | --copy-->| x = 5 | x = 100; +---------+
+-------+ +-------+ -------> | x = 100 | (discarded when change returns)
+---------+
a is still 5
A parameter is a fresh box holding a copy of the argument.
What happens at every function call.
5 · Worked Examples
Example 1 Easy
What does this print?
int sign(int v)
{
if (v < 0) return -1;
if (v == 0) return 0;
return 1;
}
int main(void)
{
printf("%d %d %d\n", sign(-7), sign(0), sign(42));
return 0;
}
Solution
For −7 the first return fires; for 0 the second; for 42 neither, so the last return runs.
Output
-1 0 1
Example 2 Medium
What does this print?
int add(int a, int b) { return a + b; }
int square(int n) { return n * n; }
int main(void)
{
int r = square(add(2, 3)) - add(square(2), 3);
printf("%d\n", r);
return 0;
}
Solution
add(2, 3) = 5, square(5) = 25. square(2) = 4, add(4, 3) = 7. 25 − 7 = 18.
Output
18
Example 3 GATE
What does this print?
int f(int x)
{
x = x * 2;
return x + 1;
}
int main(void)
{
int a = 3;
int b = f(a) + f(f(a));
printf("%d %d\n", a, b);
return 0;
}
Solution
f(a): x = 3 → 6, returns 7. f(f(a)) = f(7): x = 14, returns 15. b = 7 + 15 = 22. Each call doubled only its own copy, so a stays 3.
Output
3 22
6 · GATE Traps
⚠️
- Arguments are copied: changing a parameter never changes the caller’s variable (C has only call by value).
- A function must be declared (prototype) before its first call.
- Statements after
returnin the same path never run. - The order of evaluating arguments is unspecified;
f(i++, i++)is undefined. - A non-void function that falls off its end without returning leaves the caller an unpredictable value.
8 · Memory Hook
🧠
“Functions get photocopies.” Whatever a function scribbles on its copy, the original on your desk stays clean.
9 · Connect the Dots
Functions package the statements of Lessons 1.1–1.2. Each call made fresh copies of its parameters, which vanished afterwards. Next lesson answers: where exactly is each name visible, how long does each variable live, and can a function remember something between calls?
10 · Self-Test
GATE format. Try every question before opening the vault.
Q1MCQ1 markOutput
What does this print?
int g(int n)
{
n = n + 10;
return n * 2;
}
int main(void)
{
int n = 1;
int r = g(n);
printf("%d %d\n", n, r);
return 0;
}
- (A)
11 11 - (B)
11 22 - (C)
1 2 - (D)
1 22
Q2MCQ1 markPrototype
Why is a prototype such as int square(int n); placed above main when square is defined below main?
- (A) because square returns a value
- (B) to make square run faster
- (C) so the compiler knows square’s types before the call
- (D) to reserve memory for square
Q3MSQ1 markCall by value
Which statements are true about C functions?
- (A) Changing a parameter changes the caller’s variable.
- (B) A function can return only one value with return.
- (C) A void function cannot contain return.
- (D) Arguments are copied into parameters.
Q4NAT2 marksNested calls
What does this print?
int h(int a, int b)
{
return a * 10 + b;
}
int main(void)
{
printf("%d\n", h(h(1, 2), h(3, 4)));
return 0;
}
Numerical answer: ________
Q5MCQ2 marksOutput
What does this print?
void swap(int a, int b)
{
int t = a;
a = b;
b = t;
printf("inside: %d %d\n", a, b);
}
int main(void)
{
int x = 1, y = 2;
swap(x, y);
printf("outside: %d %d\n", x, y);
return 0;
}
- (A)
inside: 2 1thenoutside: 2 1 - (B)
inside: 1 2thenoutside: 2 1 - (C)
inside: 2 1thenoutside: 1 2 - (D)
inside: 1 2thenoutside: 1 2
11 · Rule Card
- type name(params) { … return v; } — void when nothing is returned.
- Call: evaluate args → copy into params → run → value replaces the call.
- Prototype (declaration) before first use; definition = body.
- Call by value only: parameters are copies; caller’s variables unchanged.
- return ends the function immediately.
- Argument evaluation order is unspecified.
12 · Concept Ledger
Unlocked in this lesson. From here on, these terms may be used.
function definitionparameterargumentreturn valuevoidfunction callprototypecall by value
13 · Answer Vault
Answer Vault
Try the questions first. Open when you are ready to check.
Recall Warm-up
- 5 (i = 1, 2, 4, 8, 16).
- −3 (truncation towards zero).
-
Self-Test
Q1 Answer: (D)1 mark
g changes only its copy: returns (1 + 10) × 2 = 22; main’s n stays 1.
Output
1 22
- (A) is wrong: n is unchanged and r = 22.
- (B) is wrong: main’s n is not changed.
- (C) is wrong: The return value is 22.
Re-read: Lesson 1.3.1 — Declaring, defining, calling; parameters; return values; call by value
Q2 Answer: (C)1 mark
The compiler reads top to bottom and must know the function’s declaration before a call.
- (A) is wrong: Even void functions need declarations.
- (B) is wrong: It has no effect on speed.
- (D) is wrong: A prototype reserves nothing.
Re-read: Lesson 1.3.1 — Declaring, defining, calling; parameters; return values; call by value
Q3 Answer: (B) (D)1 mark
C passes copies; return gives one value.
- (A) is wrong: Only the copy changes.
- (C) is wrong: void functions may use a bare return;
Re-read: Lesson 1.3.1 — Declaring, defining, calling; parameters; return values; call by value
Q4 Answer: 1542 marks
h(1, 2) = 12, h(3, 4) = 34, h(12, 34) = 120 + 34 = 154.
Output
154
Re-read: Lesson 1.3.1 — Declaring, defining, calling; parameters; return values; call by value
Q5 Answer: (C)2 marks
The copies are swapped inside; x and y are untouched.
Output
inside: 2 1
outside: 1 2
- (A) is wrong: Swapping copies does not swap x and y.
- (B) is wrong: The originals do not change.
- (D) is wrong: The copies are swapped inside.
Re-read: Lesson 1.3.1 — Declaring, defining, calling; parameters; return values; call by value