Loading
0x70Lesson 8 of 20

Functions

Break programs into named, reusable pieces - and learn why C functions get copies of their arguments.

14 min 5-question quiz 2 code exercises
By the end of this lesson you can
  • Define functions with parameters and return values
  • Declare functions with prototypes
  • Explain pass-by-value and variable scope

A function is a named block of code that does one job. You have used printf and written main; now you will write your own. Functions let you name an idea once and reuse it, and they keep each part of a program small enough to understand.

Defining and calling

square.c
1#include <stdio.h>
2
3int square(int x) {
4    return x * x;
5}
6
7int main(void) {
8    int result = square(7);
9    printf("7 squared is %d\n", result);
10    printf("3 squared is %d\n", square(3));
11    return 0;
12}
Output
7 squared is 49
3 squared is 9

Reading int square(int x) from left to right:

  • int is the return type: the kind of value the function hands back.
  • square is the name.
  • (int x) is the parameter list: square takes one int, called x inside the function.

return x * x; ends the function and sends the value back to the caller. A function that returns nothing has return type void; one that takes nothing has (void) as its parameter list - just like main.

Prototypes

C reads your file top to bottom, and it must know a function's signature before you call it. If you want main first (many people do), put a prototype - the signature followed by a semicolon - near the top:

prototype.c
1#include <stdio.h>
2
3void greet(const char *name);   // prototype
4
5int main(void) {
6    greet("Ada");
7    greet("Linus");
8    return 0;
9}
10
11void greet(const char *name) {  // definition
12    printf("Hello, %s!\n", name);
13}
Output
Hello, Ada!
Hello, Linus!

This is also exactly what header files like stdio.h contain: prototypes for functions defined somewhere else. (const char *name is how C passes a string - more on that in the strings lesson.)

Pass by value

When you call a function, C copies each argument into the parameter. The function works on its copy; the caller's variable is untouched. This surprises almost everyone the first time:

copy.c
1#include <stdio.h>
2
3void try_to_double(int n) {
4    n = n * 2;
5    printf("inside:  %d\n", n);
6}
7
8int main(void) {
9    int value = 10;
10    try_to_double(value);
11    printf("outside: %d\n", value);
12    return 0;
13}
Output
inside:  20
outside: 10

To get a result out, return it: value = doubled(value);. (The other way - passing an address so the function can change the original - is what pointers are for, and it is coming up in unit 5.)

Scope

A variable declared inside a function (or any { } block) is local: it exists only while that block runs and is invisible outside it. Two functions can each have their own count without interfering. Variables declared outside every function are global; they are visible everywhere, which makes programs harder to reason about. Prefer passing values in and returning results out.

Key takeaways

  • A function has a return type, a name and parameters. Use void for "returns nothing" and (void) for "takes nothing".

  • Declare a prototype before use if the definition comes later in the file - that is what headers are made of.

  • Arguments are copied (pass by value). Return results instead of expecting the caller's variables to change.

Lesson quiz

5 questions · pass with 4 correct · up to 50 XP

Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.

Practice: write C

These run for real. Write the program, press Run tests, and read what the compiler tells you - learning to read compiler messages is half of learning C.

Exercise 1

Is it prime?

+25 XP

Write a function int is_prime(int n) that returns 1 if n is prime and 0 otherwise (numbers below 2 are not prime). The main function is written for you: it reads a number and prints prime or not prime.

  • 13 is prime
  • 21 is not prime
  • 1 is not prime
  • 2 is prime
main.c
Loading editor…

Your code is compiled with gcc 14 (-Wall -Wextra) and run on Compiler Explorer (godbolt.org), a free public service.

Exercise 2

Write your own power()

+25 XP

Write long power(int base, int exponent) that computes base raised to a non-negative exponent using a loop (no <math.h>). Read two integers and print the result.

For input 2 10 print 1024.

  • 2^10
  • 5^0
  • 3^4
main.c
Loading editor…

Your code is compiled with gcc 14 (-Wall -Wextra) and run on Compiler Explorer (godbolt.org), a free public service.

Questions about this lesson

Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.

Loading posts…