$ gcc -Wall -Wextra hello.c -o hello
$ ./hello
hello from compiled C
Representations, programs, and builds
2026-07-04
Horizontal movement continues the lecture path.
Vertical movement opens details, examples, or exercises on the current topic.
In RevealJS, use right/left for the main path and down/up for deeper material.
make, debugger, memory checker.| Feature | RevealJS | Beamer PDF | Typst handout |
|---|---|---|---|
| Vertical detail slides | interactive | printed as pages | printed as sections |
| Progressive line highlights | stepped | static fallback | static fallback |
| Code annotations | hover/selectable | below code | below code |
| Scrollable long code | live only | avoid for final | avoid for final |
| Executed C example | executed at render | executed at render | executed at render |
This version combines:
make, tools, and style;printf, and undefined behavior;The Berkeley material is used as inspiration for topic order and examples, not as a slide import.
A bit pattern has no meaning by itself.
0b11111111 can mean:
255-1When the size matters, say it.
wrap.c
The result is 0 because unsigned arithmetic is modulo 2^N.
What does this program print?
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint8_t x = 250;
x = x + 10;
printf("%u\n", x);
}
It prints 4.
With an 8-bit unsigned integer, arithmetic is modulo 256, so 250 + 10 = 260, and 260 % 256 = 4.
overflow.c
This is not the same story as unsigned wraparound. Signed overflow is undefined behavior in C.
Warning
For teaching: this is a good moment to separate “what my machine did today” from “what C promises”.
mainargc and argv describe command-line arguments.
argv is just data from the shellprintf: integer first%d asks printf to read the next argument as a signed decimal integer.
printf: then floating point%f asks printf to read the next argument as a floating-point value.
The compiler may warn, but printf itself trusts the format string.
printf specifiers| Specifier | Meaning | Typical argument |
|---|---|---|
%d |
signed decimal integer | int |
%u |
unsigned decimal integer | unsigned int |
%x, %X |
hexadecimal integer | unsigned int |
%f |
floating point | double |
%s |
string | char * |
%p |
address | void * |
%% |
literal percent sign | none |
C:
Java/Python comparison:
build.sh
#include.The generated RevealJS/Beamer/Typst output is static, but this cell compiles and runs C while the document is rendered.
$ gcc -Wall -Wextra hello.c -o hello
$ ./hello
hello from compiled C
Use a plain bash code block when the goal is a readable transcript rather than live execution.
This is deterministic, portable, and easy to print.
main.c
The header lets each .c file compile independently while agreeing on shared declarations.
This slide intentionally scrolls in RevealJS so we can discuss a complete small project without splitting context.
report.c
build.sh
Object files let us rebuild only what changed.
Makefile
This is the kind of reference slide where vertical scrolling can be useful during live teaching.
Makefile
CC = gcc
CFLAGS = -std=c17 -Wall -Wextra -Wpedantic -g
CPPFLAGS = -Iinclude
LDFLAGS =
SRC_DIR = src
TEST_DIR = tests
BUILD_DIR = build
APP = $(BUILD_DIR)/counter-demo
TEST_APP = $(BUILD_DIR)/counter-tests
APP_SRC = $(SRC_DIR)/main.c \
$(SRC_DIR)/counter.c \
$(SRC_DIR)/report.c
TEST_SRC = $(TEST_DIR)/test_counter.c \
$(SRC_DIR)/counter.c
APP_OBJ = $(APP_SRC:%.c=$(BUILD_DIR)/%.o)
TEST_OBJ = $(TEST_SRC:%.c=$(BUILD_DIR)/%.o)
.PHONY: all test clean distclean run
all: $(APP)
run: $(APP)
./$(APP)
test: $(TEST_APP)
./$(TEST_APP)
$(APP): $(APP_OBJ)
$(CC) $(APP_OBJ) $(LDFLAGS) -o $@
$(TEST_APP): $(TEST_OBJ)
$(CC) $(TEST_OBJ) $(LDFLAGS) -o $@
$(BUILD_DIR)/%.o: %.c include/counter.h
mkdir -p $(dir $@)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
clean:
rm -rf $(BUILD_DIR)/**/*.o
distclean:
rm -rf $(BUILD_DIR)The command line under a target starts with a real tab character.
Tip
For class, make the invisible tab visible once, then stop talking about it and let make enforce the rule.
make changessession.sh
Only the affected object and the final executable are rebuilt.
What should students answer?
Undefined behavior can:
The teaching rule: compile with warnings, remove undefined behavior first, then debug logic.
The second form makes scope visible and prevents future edits from changing control flow by accident.
In C17, include <stdbool.h> if you want bool, true, and false.
session.sh
Do not treat warnings as decoration. In this course, students should read them from the top.
This slide is intentionally too long for a fixed slide. The point is to practice reading from the first meaningful diagnostic.
diagnostics.sh
$ gcc -std=c17 -Wall -Wextra -Wpedantic -g src/main.c src/counter.c -o demo
src/main.c: In function 'main':
src/main.c:8:5: warning: implicit declaration of function 'report_value' [-Wimplicit-function-declaration]
8 | report_value("initial");
| ^~~~~~~~~~~~
src/main.c:10:17: warning: format '%d' expects argument of type 'int', but argument 2 has type 'double' [-Wformat=]
10 | printf("%d\n", 3.14);
| ~^ ~~~~
| | |
| int double
| %f
src/main.c:12:9: warning: unused variable 'unused' [-Wunused-variable]
12 | int unused = 0;
| ^~~~~~
src/counter.c: In function 'next_value':
src/counter.c:7:1: warning: control reaches end of non-void function [-Wreturn-type]
7 | }
| ^
/usr/bin/ld: /tmp/ccxT4y0F.o: in function 'main':
src/main.c:8: undefined reference to 'report_value'
/usr/bin/ld: src/main.c:9: undefined reference to 'report_value'
collect2: error: ld returned 1 exit statusStart at the first warning that explains a real source problem, then rebuild after each fix.
gdb-session.sh
Good debugger slides are usually command traces plus a small code fragment, not screenshots.
valgrind-session.sh
The tool is useful after the program compiles and the failure is runtime behavior.
render.sh
| Output | File | Use |
|---|---|---|
| RevealJS | cm3.html |
live lecture with navigation, fragments, scroll, animation |
| Beamer | cm3-beamer.pdf |
slide PDF close to the classroom deck |
| Typst | cm3-handout.pdf |
printable reading handout from the same source |
RevealJS can still be printed from the browser using ?print-pdf, but the student n-up PDFs use the Beamer export as their source. That keeps the printed versions clean, centered, and free of the web background.
handouts.sh
$ chromium --headless --no-sandbox \
--print-to-pdf=cm3-reveal-print.pdf \
"file://$PWD/cm3.html?print-pdf"
$ pdfjam cm3-beamer.pdf --nup 1x2 --paper a4paper \
--frame true --delta "0cm 0.25cm" --scale 0.96 \
--outfile cm3-2up.pdf
$ pdfjam cm3-beamer.pdf --nup 2x2 --landscape --paper a4paper \
--frame true --delta "0.20cm 0.20cm" --scale 0.96 \
--outfile cm3-4up.pdf
$ pdfjam cm3-beamer.pdf --nup 2x3 --paper a4paper \
--frame true --delta "0.18cm 0.18cm" --scale 0.96 \
--outfile cm3-6up.pdf
$ pdfjam cm3-beamer.pdf --nup 3x3 --landscape --paper a4paper \
--frame true --delta "0.12cm 0.12cm" --scale 0.94 \
--outfile cm3-9up.pdfThese PDFs are for students who print. They should not depend on scrolling.
Keep:
Avoid:
Louis Ledoux - OPC - Universite de Rennes