CS210 · Block 1 · Lesson 6

Functions

Defining and calling functions · Prototypes · Parameters and return values · const parameters · Compilation model preview
At a glance: Functions are how you organize C programs into named pieces that call each other. Today you learn the syntax (definition, prototype, parameters, return value), the mental model (every call pushes a frame on the stack; every return pops one off), the meaning of const on a parameter, and the four phases of compilation. The in-class call stack walkthrough makes the mental model concrete, the quiz checks your understanding, and two labs put you in the seat: one writing your first multi-function C program from scratch, one refactoring an existing monolithic one.
Contents
  1. Lesson Objectives
  2. Assigned Readings
  3. Pre-Class Work
  4. Lesson Materials and Overview
  5. In-Class Work
  6. After Class
1. Lesson Objectives

By the end of this lesson, cadets will be able to:

  1. Define and call C functions with parameters and return values. (Outcomes 1, 2)
  2. Write a function prototype and explain why C requires one before the call site. (Outcome 2)
  3. Apply const to a function parameter and explain the promise it makes. (Outcome 2)
  4. Describe the four phases of C compilation (preprocess, compile, assemble, link) and what each produces. (Outcome 2)
2. Assigned Readings

Complete before class. These set the vocabulary we will use.

Source Sections Why
Beej-C Chapter 4 (Functions) Definitions, prototypes, parameters, return values
King, C Programming: A Modern Approach Chapter 9 (Functions) Optional deeper dive into scope and storage class
3. Pre-Class Work
Do this first
Plan on 30 to 45 minutes for the reading and the pre-class self-check. The walkthrough and lab in class will move faster if you arrive with the vocabulary already in your head.

Pre-Class Checklist

1
Read Beej-C Chapter 4.
All of it. The chapter is short. Pay attention to the parts on prototypes and on what parameters actually are. Those are the two things cadets get wrong first.
2
Finish Lab 05 if you have not.
Today's labs assume you are comfortable with conditionals, loops, and writing a small program that reads input and produces output. If Lab 05 is still open, finish it before you start the Lab 06 work.
3
Take the functions self-check (in Section 5 below).
Eight questions covering prototypes, parameters vs arguments, return values, const, the compilation phases, and how locals behave on return. You need 6 of 8 (70%) to pass. The score card gives you a completion code to enter on the Blackboard reflection quiz.
4. Lesson Materials and Overview

Up to this point your programs have lived entirely inside main. Today that changes. Functions are how C programs grow past a few dozen lines without becoming unreadable. The mental model matters as much as the syntax: every function call pushes a frame onto a stack, and every return pops one off. The walkthrough in Section 5 makes that visual.

Jump to
Slides Anatomy Parameters & Return Prototypes The Call Stack const Parameters Compilation Model

Slides

The Lesson 6 deck covers everything in this section. The slides are the spine of the in-class lecture; the call stack walkthrough is where the mental model becomes concrete.

Open Lesson 6 slides →

Anatomy of a C function

A C function has four parts: a return type, a name, a parameter list, and a body in curly braces. Here is the smallest useful example.

int add(int a, int b) {
    int sum = a + b;
    return sum;
}

Reading left to right: int is the return type (this function gives back an int). add is the name. The two items inside the parentheses are the parameters. The body, inside curly braces, runs each time the function is called and ends with a return statement.

If a function returns nothing, you write void as the return type and either omit return or use a bare return; with no value. You have already been doing this implicitly: main is itself a function, and the int in front of it is its return type.

The DFCS C Programming Standard introduces three rules at this lesson that apply to every function you write from now on. §5.2 requires function names in snake_case, descriptive of what the function does (compute_total, not ct and not computeTotal). §2.2 requires a function header block directly above each function prototype that names what the function does (@brief), each parameter (@param), and the return value (@return). §2.3 requires a documentation statement in the file containing main (the comment header block you have been writing since Lesson 1 already counts). The full standard lives in the course Resources section.

Parameters and return values

Two terms that mean similar things and often get used loosely: a parameter is the name that appears in the function definition. An argument is the value the caller passes in at the call site. In add(int a, int b), a and b are parameters. In add(3, 4);, the values 3 and 4 are arguments.

The important property: parameters in C are copies. When you call add(x, y), the function receives the current values of x and y in its own local parameters a and b. If add changes a inside its body, the caller's x does not change. This is called pass by value. Scenario 2 in the in-class walkthrough makes this concrete.

The return value flows in the opposite direction. The function computes a value with return expr;, the function ends immediately, and the value of expr arrives at the call site. So int result = add(3, 4); assigns the returned 7 to result.

Parameters and return values are how functions share data with each other in C. Some of you wrote Python where a function reads or writes a variable defined at the top of the file and the code "just works." The DFCS C Programming Standard §7.2 forbids that pattern in CS210: when it is reasonably possible to avoid a global variable, avoid it. Pass what the function needs as parameters and return what it produces. Global state hides what a function actually depends on and is one of the most common sources of hard-to-find bugs in C code.

Prototypes: the rule C needs that Python doesn't

Python is happy to find a function definition anywhere in the file. C is not. When the C compiler hits a call to add(3, 4), it must already know the function's signature: what types it takes and what it returns. The prototype is how you tell the compiler that information ahead of time.

A prototype is just the function header followed by a semicolon, with no body.

int add(int a, int b);   // prototype (parameter names optional)
int add(int, int);       // also valid: names dropped

Put the prototype near the top of your .c file, above main. The full definition (with the body) can come later in the file. If you forget the prototype and call the function anyway, the compiler will warn you with something like:

lab.c:8:18: warning: implicit declaration of function ‘add’ [-Wimplicit-function-declaration]

Always fix this warning. "Implicit declaration" means the compiler had to invent a signature for your function because no prototype was visible. The fix is short: write the prototype above the call. Quiz Question 4 in Section 5 walks through one of these errors in detail.

The call stack: a mental model

Every function call in a C program pushes a frame onto a structure called the call stack. The frame holds that function's parameters, its local variables, and a note about where to return to. When the function returns, its frame is popped off the stack and disappears, taking its locals with it.

When main calls add, the stack briefly looks like this (top frame is the function currently running):

  [ add  ]   ← running. params: a=3, b=4. local: sum=7
  [ main ]   ← paused, waiting for add to return

When add returns 7, its frame is popped, main is back on top, and the 7 flows into whatever variable was waiting for it. Two things to internalize: locals exist only while their frame is on the stack, and a function does not have access to another function's locals. The walkthrough in Section 5 makes both of these visible.

const parameters: a promise to the compiler

If a parameter will not be modified inside the function body, mark it const:

double circle_area(const double radius) {
    return 3.14159265 * radius * radius;
}

The const is a promise: the function will not assign a new value to radius inside its body. If you accidentally write code that does, the compiler stops you. This catches bugs and documents intent in one go. We will use it on at least one parameter in today's lab.

The compilation model (preview)

When you type gcc lab.c -o lab, four things happen in sequence:

Phase Produces What it does
Preprocess Expanded C source Expands #include directives and macros into a single big source file.
Compile Assembly code Turns C into the assembly language for your machine architecture.
Assemble Object file (.o) Turns assembly into machine code in an object file. Not yet runnable.
Link Executable Combines object files with library code (like printf) into a runnable program.

gcc runs all four phases for you in one command. You do not need to memorize each step's flags; you do need to recognize the names so the error messages make sense (a "linker error" is different from a "compiler error" and the fix is different too). Lesson 7 introduces make, which automates running these phases across multiple files.

5. In-Class Work

Four things to do in class. Use the checklist to track your progress.

  • Work through the call stack walkthrough below. Five short scenarios with prediction checkpoints. Watch frames push and pop as functions call each other. About 20 minutes.
  • Take the functions self-check. Eight questions on prototypes, parameters, return values, const, and the compilation phases. About 10 minutes. The score card produces your completion code.
  • Complete Lab 06.1: Projectile Energy. Write four small functions with prototypes and one const parameter. Single file. About 20 minutes. Worth 1 point.
  • Complete Lab 06.2: Refactor Mountain Hike Planner. Start with a working monolithic program. Refactor it into well-named functions so main() is under 15 lines. About 25 minutes. Worth 1 point.

Call Stack Walkthrough

Five short C programs. Step through them one line at a time and watch the call stack change. Before each return, the widget asks you to predict the value coming back. Get it right to keep stepping.

Before you begin

Enter your name. It will appear on the completion screen so you can include it in your screenshot for the Blackboard reflection quiz.

CS210 Lesson 6 · Call Stack Walkthrough

Step through five short programs and watch the call stack grow and shrink as functions call other functions and return. Predict what happens at each checkpoint before stepping forward.
Scenario 1 of 5
Scenario 1 · Simplest call
Predict, then step
Loading scenario...
Press Step to begin.
Call stack · top frame is the function currently running
Stack is empty. Press Step to call main().
Stuck? The status line tells you what just ran and what's next. The current line in the code pane has a yellow highlight. The stack pane shows every function that has been called but not yet returned. When a function returns, its frame is removed from the stack and its return value goes back to whoever called it.

Functions Self-Check

Eight questions covering everything in this lesson. You need 6 of 8 (70%) to pass. The score card at the end gives you a completion code to enter on the Blackboard Lesson 6 test.

Before you begin

Enter your name. It will appear with your completion code on the score card so you can include it in your screenshot for the Blackboard reflection quiz.

CS210 Lesson 6 · Functions Self-Check

Eight questions covering function prototypes, parameters vs arguments, return values, const parameters, the compilation phases, and how locals behave when a function returns. You need at least 6 of 8 (70%) for a passing completion code.
How this works: One question per card. Pick or type your answer and click Submit. The feedback appears, then click Next to move on. Answers are locked once submitted, so think before you submit. When you finish all eight, you get a score, a recap, and a completion code.
6. After Class
  • Finish Lab 06.1 and Lab 06.2 if you did not complete them in class. Submit each through its GitHub Classroom assignment before Lesson 7.
  • Read MTBE (Modern C for Absolute Beginners) "Getting Started" through the chapter on Variables in preparation for Lesson 7.
  • Replay any scenario in the call stack walkthrough. Use the Back button to step backward through a return and see the frame come back. The mental model pays off in Lesson 11 (recursion) and Lesson 14 (pointers).
  • Heads up: Quiz 2 at Lesson 7 covers Lessons 5 and 6 together.
Need help? Schedule EI with your instructor. Bring a specific scenario from the walkthrough, a specific compiler error message, or a specific line of your lab code. Specific questions get unstuck quickly.