Lesson 86 min read

C Functions

A vending machine β€” put something in, get something out

The Vending Machine

Think of a function as a vending machine. You put in some coins (the arguments), press a button (the function call), and out comes a snack (the return value). You don't need to know what gears and motors spin inside β€” you just care about what goes in and what comes out.

In C, every program starts with one function: main(). From there, you break your code into smaller functions β€” each one doing one job well.

Anatomy of a Function

A C function has four parts:

  • Return type β€” what kind of snack comes out (int, float, char, or void for nothing)
  • Name β€” the label on the button
  • Parameters β€” the coin slots (what goes in)
  • Body β€” the machinery inside { }

A Simple Math Function

#include <stdio.h>
// Function: takes two ints, returns their sum
int add(int a, int b) {
return a + b;
}
// Function: takes an int, returns its square
int square(int n) {
return n * n;
}
int main() {
int sum = add(3, 7);
printf("3 + 7 = %d\n", sum);
int sq = square(5);
printf("5 squared = %d\n", sq);
// You can nest calls
printf("sum of squares = %d\n", add(square(3), square(4)));
return 0;
}
Output
3 + 7 = 10
5 squared = 25
sum of squares = 25

Void Functions β€” No Snack Comes Out

Sometimes a vending machine doesn't give you a snack β€” it just does something (like playing music). A void function performs an action without returning a value. You can still use return; to exit early, but you don't return any data.

Void Functions

#include <stdio.h>
void greet(char name[]) {
printf("Hello, %s! Welcome aboard.\n", name);
}
void printLine(int length) {
for (int i = 0; i < length; i++) {
printf("-");
}
printf("\n");
}
int main() {
printLine(30);
greet("Alice");
greet("Bob");
printLine(30);
return 0;
}
Output
------------------------------
Hello, Alice! Welcome aboard.
Hello, Bob! Welcome aboard.
------------------------------

Function Prototypes β€” Declare Before You Use

C reads your file top to bottom. If main() calls a function that's defined below it, the compiler hasn't seen it yet and will complain. The fix? Put a prototype (also called a forward declaration) at the top. It's just the function signature followed by a semicolon β€” a promise that the full definition is coming later.

This is standard practice in C: prototypes at the top (or in a header file), definitions below main().

Function Prototypes

#include <stdio.h>
// Prototypes β€” promises to the compiler
int max(int a, int b);
int clamp(int value, int low, int high);
int main() {
printf("Max of 10, 20: %d\n", max(10, 20));
printf("Clamp 150 to [0,100]: %d\n",
clamp(150, 0, 100));
printf("Clamp 50 to [0,100]: %d\n",
clamp(50, 0, 100));
return 0;
}
// Definitions β€” the actual machinery
int max(int a, int b) {
return (a > b) ? a : b;
}
int clamp(int value, int low, int high) {
if (value < low) return low;
if (value > high) return high;
return value;
}
Output
Max of 10, 20: 20
Clamp 150 to [0,100]: 100
Clamp 50 to [0,100]: 50
Note: C is pass-by-value by default. When you pass a variable to a function, the function receives a copy. Modifying the copy inside the function has zero effect on the original. If you need the function to change the caller's variable, you must pass a pointer β€” which we cover in the pointers lesson.

Pass-by-Value in Action

#include <stdio.h>
void tryToChange(int x) {
x = 999; // Only changes the local copy!
printf("Inside function: x = %d\n", x);
}
int main() {
int num = 42;
printf("Before call: num = %d\n", num);
tryToChange(num);
printf("After call: num = %d\n", num);
// num is STILL 42!
return 0;
}
Output
Before call: num = 42
Inside function: x = 999
After call:  num = 42

Why Break Code Into Functions?

Functions aren't just about avoiding repeated code (though that's a big win). They let you:

  • Name a chunk of logic β€” calculateTax(income) is clearer than 15 lines of math
  • Test pieces independently β€” you can verify max() works without running the whole program
  • Divide work β€” different team members can write different functions
  • Limit scope β€” variables inside a function can't leak out and cause confusion

Good C code is a collection of small, focused functions that each do one thing well.

Challenge

Quick check

What does a void return type mean?
← Strings & CharactersPointers β†’