Grouping Memory — Structs
"A just balance and scales are the LORD's; all the weights in the bag are his work." — Proverbs 16:11
Why This Matters
Last week you suffered, intentionally. Three parallel arrays — names, centuries, types — and a single bug if you forgot to update any one of them when you updated the others.
This chapter is the relief. Structs let you bundle the data that belongs together under one name. A struct says: a Manuscript is a thing that has a name, a century, and a type — and from now on, when you handle a Manuscript, you handle all three together.
For the apologetics theme: each piece of evidence — for the Resurrection, for the historicity of the Gospels, for any apologetic claim — is itself a bundle: the claim, the source, the type, the strength, the earliest credible date. Treating each piece as a struct is exactly the move scholars make.
The Struct Declaration
struct Evidence {
string claim;
string source;
string type;
int strength_rating;
int year;
}; // ← don't forget this semicolon Read it: "There is a type called Evidence. An Evidence has five fields." The trailing semicolon is required by C++. Forget it and the compiler will yell at you in a confusing way.
Using a Struct
Evidence e;
e.claim = "Empty tomb tradition";
e.source = "Mark 16; 1 Cor 15";
e.type = "textual";
e.strength_rating = 8;
e.year = 35;
// Or all at once with brace initialization:
Evidence creed = {
"1 Corinthians 15:3-7 creed",
"Paul (received/delivered language)",
"textual",
9,
35
}; Access fields with the . operator. Same as accessing object properties in any other language.
Arrays of Structs — The Move That Retires Parallel Arrays
const int MAX = 25;
Evidence inv[MAX];
int count = 0;
// Add a piece
inv[count] = {"Conversion of Paul", "Acts; Galatians 1", "historical", 9, 35};
count++; One array. One count. When you remove an entry and shift the rest down, every field travels together — no risk of name drifting away from strength.
Structs as Function Parameters
void print_evidence(const Evidence& e) {
cout << e.claim << " (" << e.strength_rating << "/litman-books/10)" << endl;
}
The const Evidence& means "by reference, read-only." It's the cheap-and-safe
default for passing structs to functions — no copy, no mutation. Use plain Evidence
& when you do want to modify; plain Evidence when the function needs
its own copy (rare).
Coach's Note — Structs are the smallest unit of object-oriented thinking. From here forward, every design decision in this course will involve "what type should this be? what fields does it have? what operations belong with it?" Master structs and Phase 2 (classes) is mostly vocabulary.
This Week's Project
You're ready for Project 7: Evidence Inventory. You'll build the program version of the widget above — a real inventory of pieces of evidence (Resurrection minimal facts is the canonical example) as a struct array. Add, remove, search, filter, total strength. Use real data with verifiable sources.
This is also the last chapter before the midterm. If you can ship Project 7 cleanly, every procedural-C++ skill the midterm tests is in your hands.
Structs — Quick Check
struct Manuscript {
string name;
int century;
string type;
} }. The compiler's error message will be confusing — usually about whatever comes next in the file. Always check the line above the error. const Evidence& says: pass by reference (no copy — cheap even if the struct grows), and read-only (the compiler enforces you don't modify it). The plain-value version (Evidence e) copies the whole struct unnecessarily. Non-const reference (Evidence&) works but doesn't communicate the read-only intent.