CS210 · Block 2 · Lesson 14

Pass by Value vs Pass by Pointer

Stack frames · Pass-by-value semantics · Pass-by-pointer semantics · Multiple output parameters · Why scanf needs &
At a glance: The third and final pointers introduction lesson. So far you have learned what a pointer is (Lesson 12) and how pointer arithmetic walks through arrays (Lesson 13). Today the payoff: pointers as function parameters. You will see why a function cannot modify its caller's variables without one, why scanf has demanded an & since Lesson 3, and how to write functions that return more than one value. Two short labs cement the mechanics; the call-frame walkthrough in Section 5 makes it visible.
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. Distinguish pass-by-value from pass-by-pointer semantics. (Outcome 2)
  2. Write functions that modify their caller's variables through pointer parameters. (Outcome 2)
  3. Explain why functions like scanf require the address-of operator. (Outcome 2)
2. Assigned Readings

Complete before class. Today's reading revisits two earlier chapters: Beej Chapter 5 (Pointers) for the function-argument section, and Beej Chapter 4 (Functions) for pass-by-value.

Source Sections Why
Beej-C Chapter 5 (Pointers): §5.3 (Dereferencing), §5.4 (Passing Pointers as Arguments) The core mechanism for today. Read 5.4 carefully — this is the section where pointers stop being a curiosity and start being useful.
Beej-C Chapter 4 (Functions): §4.1 (Passing by Value) — review A short refresher. Today's lesson is built on the contrast between 4.1 and 5.4, so come in clear on both.
Beej-C Chapter 5 (Pointers): §5.5 (The NULL Pointer) — review Quick refresher from Lesson 12. Functions that take pointer parameters should check for NULL.
3. Pre-Class Work
Heads up
Quiz 5 covers Lesson 12 (pointers introduction). Review your Lesson 12 notes and replay the pointer walkthrough if it has been a few days. Quiz timing is at the instructor's discretion.
PEX1 due today
Late penalties follow the syllabus policy.

Pre-Class Checklist

1
Read Beej-C 5.3, 5.4, and 4.1
Re-read these three sections in order. Be ready to explain in your own words:
  • What does a function actually receive when you pass an argument to it?
  • Why can a function not change a caller's int just by writing to its parameter?
  • What does passing a pointer let the function do that passing an int does not?
2
Review for Quiz 5
Quiz 5 covers Lesson 12: pointer declarations, the address-of operator, the dereference operator, NULL pointers, and the int *p, q; declaration trap. Twenty minutes max. Replay the Lesson 12 pointer walkthrough if you want a fast refresher.
3
Predict before you arrive
Beej 4.1 ends with a small example where a function called increment tries to modify its parameter. Before class, predict what the program prints. Then predict what changes if you rewrite it to take a pointer. If you can answer both without running code, you are ready for today.
4. Lesson Materials and Overview
Jump to
Slides Pass-by-Value Pass-by-Pointer Multiple Outputs Why scanf Needs & Decomposition of State

Slides

The Lesson 14 deck walks through pass-by-value, the limitation it imposes, how pass-by-pointer overcomes it, and the multiple-output-parameter pattern. The slides are the spine of the lecture; the call-frame walkthrough is where you watch the mechanics in motion.

Open Lesson 14 slides →

Pass-by-value: what your functions have actually been doing

Every function you have written so far receives copies of its arguments. The caller has variables; the function has parameters; the parameters are filled with the values from the caller's variables at the moment of the call. After that, they are independent.

void increment(int n) {
  n = n + 1;  // modifies the copy
}

int main(void) {
  int x = 10;
  increment(x);
  printf("%d\n", x);  // prints 10, not 11
}

The function received a copy. Modifying the copy did nothing to x back in main. This is pass-by-value, and it is the only thing C does. There is no other mode. Every parameter is a fresh local variable initialized from the argument.

Pass-by-pointer: passing the address instead

If you want a function to modify a caller's variable, you cannot hand it the value. You have to hand it the location. Pass the address, and the function dereferences the pointer to read or write through it.

void increment(int *p) {
  *p = *p + 1;  // writes through the pointer
}

int main(void) {
  int x = 10;
  increment(&x);  // pass the address of x
  printf("%d\n", x);  // prints 11
}

Notice the three changes from the value version. The parameter type became int *. The body dereferences with *p instead of using n directly. The call site uses &x to hand over the address.

Pass-by-value is still happening. The function receives a copy — but the copy is a copy of an address, and the address still points to x. Two pieces of paper now have the same address written on them. Either piece of paper can be used to find and modify the house.

Returning more than one value

A C function can return exactly one value. That is a real constraint. When a function naturally produces two or more results, you have two choices: return a struct (Lesson 18) or use pointer parameters as output channels. Today we use pointers.

// Split an angle in degrees into degrees, arc-minutes, arc-seconds.
void split_angle(double degrees, int *deg, int *min, int *sec) {
  *deg = (int)degrees;
  double remainder = (degrees - *deg) * 60.0;
  *min = (int)remainder;
  *sec = (int)((remainder - *min) * 60.0);
}

// Caller:
int d, m, s;
split_angle(38.7625, &d, &m, &s);
// Now d, m, s are filled in.

The function returns void. Its actual outputs travel back through the three pointer parameters. This is the pattern Lab 2 uses today, and it is one of the most common things you will see in real C code: an input value goes in, several derived results come out through pointers.

Why scanf needs &

Since Lesson 3 you have been writing scanf("%d", &x) without a real explanation for the &. We called it a syntactic ritual. Now the ritual ends.

scanf reads a value from input and has to store it somewhere — namely, in one of your variables. To store into your variable, it needs to know the variable's address. So it takes a pointer parameter, and you have to give it an address. That is what & does.

If you wrote scanf("%d", x) by mistake, you would hand scanf the value of x (uninitialized garbage), it would treat that garbage as an address, and it would try to write to that random memory location. The result is undefined behavior and, usually, a crash. The compiler will warn you with -Wall enabled. Read the warning.

Exception: when you read a string with %s, you pass the array name itself with no &. That is because an array name already is an address — the array-pointer duality from Lesson 13. Same mechanism, just a different surface.

Decomposition of state: function boundaries

Every function call draws a boundary. On the caller's side: local variables, the caller's frame. On the callee's side: parameters and the callee's locals. The question pass-by-pointer answers is: what crosses that boundary?

With pass-by-value, only the value crosses. The caller's variable is invisible to the callee; the caller's state is protected. With pass-by-pointer, an address crosses, and through that address the callee can reach back into the caller's frame and modify what is there.

This is a design decision, not just a syntactic one. When you write a function, decide first what it needs: does it need to know a value, or does it need to be able to change a value? The answer chooses the parameter type. Pass-by-value when the function should compute and return. Pass-by-pointer when the function legitimately needs to modify what the caller owns — or when it needs to return more than one result.

5. In-Class Work

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

  • Take Quiz 5 (Pointers Introduction). Twenty minutes max. Covers Lesson 12 content. Instructor will tell you when to start.
  • Work through the call-frame walkthrough below. Nine tasks across three sections: pass-by-value, pass-by-pointer, and the multi-output pattern. About 20 minutes.
  • Complete Lab 14-1: Swap by Value vs by Pointer. Implement two functions that try to swap two integers — one by value, one by pointer — and compare what happens. Auto-graded through GitHub Classroom.
  • Complete Lab 14-2: Make Change. Write a function that calculates how many quarters, dimes, nickels, and pennies make up a given number of cents, returning all four counts through pointer parameters. Auto-graded through GitHub Classroom.

Call-Frame Walkthrough

Nine tasks across three sections. Watch two memory frames side-by-side as functions are called: the caller's frame on the left, the callee's frame on the right. See pass-by-value copying values and pass-by-pointer reaching back through arrows.

Before you begin

Enter your name (first and last). It will appear on your completion screen so the screenshot is linked to you.

Call-Frame Walkthrough

Watch what crosses the boundary when a function is called. Pass-by-value, pass-by-pointer, and multi-output pointers, with a stack-frame view that makes the difference visible.
Task 1 of 9
Section 1: Pass by Value
Task 1
Loading task...
Press Step to begin executing the program.
Caller frame
main()
Callee frame
(not called yet)
Step 0 of 0
6. After Class
  • PEX1 is due today. If you have not submitted yet, push your final commit and submit through GitHub Classroom before the deadline on the syllabus.
  • Finish Labs 14-1 and 14-2 if you did not complete them in class. Submit through GitHub Classroom before Lesson 15.
  • Submit the Lesson 14 reflection in Blackboard. Enter your completion code from the call-frame walkthrough and answer the reflection prompt.
  • Read Beej-C Chapter 12 (Manual Memory Allocation) for Lesson 15. We move from stack-allocated variables to heap-allocated memory.
  • Heads up: Quiz 6 at Lesson 16 covers pointer arithmetic (Lesson 13) and pass-by-pointer (today). GR2 / Midterm is Lesson 17.
Need help? Schedule EI with your instructor. Bring specific code or specific screenshots, and the exact error message or output you do not understand. Specific questions get unstuck quickly.