Function calls Ready
One function, called twice from main.
main.c

                

Ready

Statements run 0 Lines printed 0
Ready

Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode

How it works

The ideas behind the lab

Exactly what you watched happen, in plain steps.

The three places a function appears

A function is written once (the definition), announced to the compiler before it is used (the prototype), and run whenever you write its name with brackets (the call). The definition has a head — return type, name, parameters — and a body in { }. A program can have as many functions as you like, but exactly one main.

int square(int x);          // 1. prototype — "this function exists"

int main(void)
{
    int s = square(5);      // 2. call — run it, use the result
    printf("%d
", s);     //    prints 25
    return 0;
}

int square(int x)           // 3. definition — head …
{
    return x * x;           //    … and body
}
The parts of a function head
Part Example Meaning
Return type int The type of the value sent back (void = nothing comes back)
Name square Follows the identifier rules; describe what it does
Parameter list (int x) Variables that receive the values sent in; (void) = none
Body { return x * x; } The statements that run on every call
Prototype int square(int x); The head + ; — written before the first call
Call square(5) Runs the function; its value replaces the call

Why functions?

  1. Write once, use many times — no copy-and-paste of the same code.
  2. Split a big problem into small, named steps that are easy to read.
  3. Test and fix each piece on its own.
  4. A fix inside the function fixes every place that calls it.
  5. You already use them: main, printf, scanf are all functions.

What happens on a call

  1. The arguments are worked out first: square(a + 1) sends one value.
  2. C remembers where to come back to, then jumps into the function.
  3. A new frame is put on the call stack for the parameters and local variables.
  4. return value; (or the closing }) ends the function; the frame is removed.
  5. Back in the caller, the call is replaced by the returned value.

void, return and prototypes

  1. void line(void) — returns nothing and takes nothing.
  2. A void function may use return; on its own to leave early.
  3. A non-void function must return a value of its type on every path.
  4. The compiler reads top to bottom: a function must be declared before it is called.
  5. Either define it above main, or put its prototype above main (the usual style).
Walkthrough

A prototype, a void function and a function with a result

Every line, explained.

1 #include <stdio.h>
2
3 int max(int a, int b); Prototype: main may now call max, although it is defined below.
4
5 void greet(void) Defined above main, so no prototype is needed.
6 {
7 printf("Welcome!\n");
8 } The end of a void function — back to the caller.
9
10 int main(void) The program starts here.
11 {
12 greet(); Prints Welcome!
13 int m = max(7, 12); max returns 12, so m = 12.
14 printf("max = %d\n", m); Prints max = 12
15 printf("%d\n", max(m, 20)); A call can be an argument: prints 20.
16 return 0;
17 }
18
19 int max(int a, int b) The definition: the same head as the prototype.
20 {
21 if (a > b)
22 return a; return ends the function at once …
23 return b; … so this line runs only when a > b is false.
24 }
Common mistakes

Spot the bug

Mistakes almost every beginner makes — and how to fix them.

Calling before declaring

✗ Wrong
int main(void) { printf("%d", add(2, 3)); }
int add(int a, int b) { return a + b; }
✓ Right
int add(int a, int b);   // prototype first
int main(void) { printf("%d", add(2, 3)); }
int add(int a, int b) { return a + b; }

The compiler reads from the top. Without a prototype it does not know add yet: "implicit declaration of function".

Forgetting the brackets

✗ Wrong
greet;      // does nothing
✓ Right
greet();    // calls the function

Without ( ) the name only refers to the function; nothing runs. Most compilers warn "statement with no effect".

Missing return in a non-void function

✗ Wrong
int square(int x)
{
    int r = x * x;
}
✓ Right
int square(int x)
{
    return x * x;
}

Without return the caller gets a garbage value. Every path of an int function must return an int.

A semicolon after the definition head

✗ Wrong
int square(int x);
{
    return x * x;
}
✓ Right
int square(int x)
{
    return x * x;
}

With ; the head is only a prototype, and the { } block that follows is outside any function — a compile error.

Using the result of a void function

✗ Wrong
int n = greet();   // greet is void
✓ Right
greet();           // just call it

A void function returns nothing, so there is no value to store: "void value not ignored as it ought to be".

Practice

Check your understanding

Answer each question — you will see the explanation straight away.

0 / 5 correct
Question 1

Where does every C program start running?

Question 2

What does the prototype int add(int a, int b); tell the compiler?

Question 3

int sq(int x) { return x * x; } — what does sq(3) + sq(4) give?

Question 4

What does void mean in void greet(void)?

Question 5

A function is called 3 times. How many times was its code written?

Assessment

Functions: The Basics quiz

Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.