Teaching a language like C—which is essentially about how a machine manages its physical reality (memory and addresses)—actually lends itself beautifully to tactile, physical metaphors.
Since your students are working on secure tablets with no compiler, you aren't just teaching "coding"; you are teaching Computational Thinking and Systems Architecture.
Here is how you can use Modern C, Quipu, and Beadwork to teach the "nuts and bolts" of C in a prison environment.
The Peruvian Quipu (knotted strings) is perhaps the best physical metaphor for one of the hardest concepts in C: The Linked List and Pointers.
The Concept: In C, a "Node" is a piece of data plus a memory address (a pointer) to the next piece of data.
The Physical Lab:
Each student gets a main cord (the "Bus").
They attach pendant strings (the "Nodes").
The "Nuts and Bolts": The type of knot and its position represents the Data (integers, chars). The sequence of strings represents the Pointer to the next element.
The "Modern C" Connection: You can have them "read" a PDF page on Structs, then ask them to "encode" a specific Struct (like a person's age and ID) into a Quipu string.
C treats memory as one long, continuous row of "mailboxes." Beadwork is the perfect 1:1 physical representation of an Array.
The Concept: Memory addresses and offsets.
The Physical Lab:
The Array: A single string of beads. If a char is 1 bead and an int is 4 beads, how do you find the 3rd integer? They have to physically count the "offset."
The Stack: Using a vertical bead-loader (or a narrow tube). You can only add (push) a bead to the top and only take (pop) the top bead off. If you want the bead at the bottom, you must pop everything else first. This perfectly illustrates LIFO (Last-In, First-Out).
Buffer Overflows: This is a "weird application" of C. If you have a string of 5 beads and try to force 3 more onto a thread that is tied off, you break the "memory."
Since they cannot run code, they need to become "Human Compilers." Jens Gustedt’s Modern C is very structured, which helps.
Encounters (Level 1): Focus the PDFs on the syntax of declaration. Have students draw "Memory Maps" on paper. If the code says int x = 5;, they draw a box, label it x, give it a fake address (like 0x100), and put the number 5 inside.
The "Dry Run" Method: Provide them with short snippets of C code in PDF form and a "Trace Table" (a grid). Their job is to read the code line-by-line and manually update the values in the grid, mimicking how the computer’s memory changes.
If you need PDFs and Videos/Audio:
Harvard CS50 "Memory" Lectures: If you can get the video files for "Week 3" and "Week 4" of CS50, they are the gold standard for explaining pointers visually. David Malan uses physical props (milk cartons and lockers) which will resonate with your tactile approach.
Programming from the Ground Up (Jonathan Bartlett): This is an OER book (GFDL license). While it focuses on Assembly, it explains why C works the way it does by looking at the CPU. For students without computers, understanding the "gears" of the CPU is often more intuitive than abstract high-level code.
Low-Level Learning (YouTube/Video): If you can acess his "C Fundamentals" videos, he uses very clear visual overlays to show how memory moves.
When providing beadwork or quipu materials, ensure they are safety-cleared (e.g., specific string lengths, plastic vs. glass beads, etc.). If "loose" beads are a security concern, you can use Lego bricks or even playing cards to achieve the same logic:
Cards: A deck of cards is an array. A "pointer" is a sticky note with a number written on it that tells you which card in the row to look at.
Course Structure - A "Conversation" Between Assembly and C
This "conversation" approach can be especially helpful for Electrical Engineering students. In the EE world, C isn't just a "programming language"—it’s a way to manipulate voltages and gates without having to flip every switch by hand.
By teaching them concurrently, you effectively remove the "magic" from C. A pointer isn't a "scary abstract concept" anymore; it's just a hex address in a register. A for loop isn't just "syntax"; it’s a COMPARE and a JUMP instruction.
Here is how you can structure this "C-to-Assembly Conversation" for an offline, tactile environment.
Since learners don't have computers, every student should have a printed "Paper CPU" Worksheet. This is their "computer."
Registers: 4–8 boxes labeled R0 through R7.
The Program Counter (PC): A box they update with a pencil to show which "line" of code they are on.
The ALU: A space to do manual math (Beads can be used here for binary addition).
Memory (RAM): A grid representing addresses.
Each module should follow a "Concept → Assembly → C" flow. Here’s an example of how that conversation looks:
The Assembly Side: "We have a physical bucket (Register R0). We want to put the number 5 in it."
Action: Student puts 5 beads in the R0 box on their paper.
Instruction: MOV R0, #5
The C Side: "In C, we don't care which bucket it is. We just name the bucket x."
Instruction: int x = 5;
The Connection: The student learns that the Compiler is just a clerk who decides that "x" lives in "Register 0."
The Assembly Side: We use "Indirect Addressing." Register R1 doesn't hold a value; it holds the index number of a memory slot.
The Physical Lab: Use the Quipu.
String A has a knot representing the number 10.
String B has a knot representing the position of String A.
The C Side: int *p = &x;
The Conversation: "A pointer is just a Register holding the address of a Bead String."
To make this work asynchronously, you can create "Translation Challenges."
PDF provides a C snippet: if (x > 10) { x = 0; }
Student Workbook asks: "Translate this to Assembly instructions using CMP (Compare) and BNE (Branch if Not Equal)."
The Tactile Step: "Now, execute your Assembly. If your 'Register' beads are greater than 10, move the PC (Program Counter) to the 'Reset' line."
Most CS students learn C to build software. EEs learn C to talk to hardware. By teaching Assembly first or alongside C, you are teaching them:
Memory Mapping: How a specific address in C corresponds to a physical pin on a microcontroller.
Bitmasking: Use beadwork to show how a char (8 beads) can represent 8 different "On/Off" switches (GPIO pins).
Interrupts: You can simulate an "Interrupt" by having an audio cue in their lesson that tells them to "Stop whatever code you are running, save your registers, and go to the 'Safety' string on your Quipu."
Even though the full course requires a computer, the first half of the book (Nand to Tetris) is the gold standard for this "Bottom-Up" approach.
It starts with a NAND gate (Hardware).
Builds to ALU/Registers.
Builds to Assembly.
Ends with C-like Jack language.
Learners can print the chapters on Boolean Logic and Machine Language. It’s incredibly empowering for a student in a cell to realize they can "build" a computer logic-gate-by-logic-gate using nothing but a pencil and a stack of paper.
Teaching pointers without Assembly is like teaching someone to drive by showing them a map but never opening the hood. They’ll get where they’re going, but the first time the engine makes a "clunk" sound (a Segfault), they’ll be totally lost. With our approach, students should know exactly which "gear" just stripped.