Functions

Introduction

A function is a named piece of code you can call with different values. It keeps programs short, and each function can be tested on its own.

A long main soon becomes impossible to follow. Functions let you name a piece of work, test it alone and reuse it. In C, they also show you clearly how the program's memory is organised into frames.

How it works

Parameters are copies

C passes copies of values. Changing a parameter inside the function changes only the copy:

#include <stdio.h>

void try_to_double(int n) {
    n = n * 2;
    printf("inside: %d\n", n);
}

int main(void) {
    int n = 21;
    try_to_double(n);
    printf("outside: %d\n", n);
    return 0;
}
Open in compiler

Step into try_to_double and watch: its n doubles, but main's n stays the same. To change the caller's variable, a function needs its address: that is what pointers are for (two lessons from now).

Declare before use

C reads the file from top to bottom. A function must be defined, or at least declared with a prototype, before it is called:

int square(int x);      /* prototype: the definition comes later */

Syntax

int square(int x);            // prototype

int main(void) {
    int y = square(4);
    return 0;
}

int square(int x) {
    return x * x;
}

Example

#include <stdio.h>

double area(double w, double h) {
    double a = w * h;
    return a;
}

int main(void) {
    double room = area(3.5, 4.0);
    double total = room + area(2.0, 2.5);
    printf("room %.2f, total %.2f\n", room, total);
    return 0;
}
Open in compiler

Watch the memory panel when line 9 calls area. A new frame for area appears on top of main's, holding its own w and h. When area returns, its frame disappears and the result comes back to main.

  • double area(double w, double h): the function returns a double and takes two double parameters.
  • return w * h; sends the result back and ends the function.
  • A function that returns nothing is void.

Line by line

  1. area takes two doubles and returns a double.
  2. main calls area(3.5, 4.0), and a new frame appears holding w and h.
  3. area works out the product, returns it, and its frame disappears.
  4. The second call has its own new frame, and its result is added to room.
  5. printf shows both values with two decimals.

Expected result

room 14.00, total 19.00

In the real world

The C standard library is simply a collection of functions, and large systems such as the Linux kernel are built from tens of thousands of small ones. Passing by value keeps a function from changing its caller's data by accident.

Common mistakes

  • Calling a function before C has seen it: put the function above main, or add a prototype.
  • Forgetting return in a function that should return a value.
  • Expecting a function to change the caller's variable through a normal parameter.

Best practices

  • Keep functions short enough to read at a glance.
  • Use prototypes, or define functions before main.
  • Name each function after what it does.

Summary

Functions take copies of their arguments in their own frames, and they can return one value. C reads files from the top, so a function must be declared before it is called.

Quick check

1. What does void mean as a return type?
2. void add_one(int x) { x = x + 1; } After int n = 5; add_one(n); what is n?
3. What is a prototype?

Key takeaways

  • C always passes copies.
  • A function must be declared before it is used.
  • Give each function one job.

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.