Loading
0x70Lesson 8 of 15

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 real 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.

Sign in to ask questions, help other learners, and earn XP for taking part.

Loading posts…

Did you like the lesson? 😆👍
Consider a donation to support our work: