Programming Fundamentals Using C++

L28 · Structures: `struct` Definition, Members, Nesting, Arrays/Files of Records

Module 14 — Dynamic Memory and Structures · Week 14 · Lecture 28 of 32 · 120 minutes Outcomes: CLO-7 · PF-14.3, PF-14.4 · LEARNING_OUTCOMES.md · Project milestone week

Learning objectives

  1. Define struct types with appropriate members, initialize them (brace form), and access/modify members with . (including through references and pointers with ->) (PF-14.3).
  2. Implement functions that take and return structs (by value, const T&, and T& for write-back), justifying each passing mode per the L26 checklist (PF-14.3).
  3. Build a records-in-collection application — arrays/std::vector of structs with aggregate computations (average, max-by-field, search by field) — the architecture of the capstone project (PF-14.4).

Prerequisites

L26 (passing-mode checklist); M9–M12 (collections + algorithms — now applied to records); L25 (-> preview: (*p).member vs p->member).

Concept sequence

  1. Parallel arrays don't scale: the records motivation
  2. struct definition, member declaration, brace initialization
  3. Member access ., through references, and -> through pointers
  4. Structs with functions: passing modes revisited for real data
  5. Nested structs and struct assignments (whole-object copy)
  6. Collections of records: the capstone architecture

Teaching topics (detailed)

C++ examples required

FileRole
struct_records.cpp ✅Student struct: init, print/promote/factory functions, nested address, vector-of-Student with three aggregate algorithms
(live) roster_stats.cppcapstone-skeleton: load-able roster + menu-less analytics build (M15 adds the file part)

Common student misconceptions

Conceptual explanation (beginner-first)

Arrays taught you to group many values of one type. Real records mix types: a student has a name (string), an ID (int), a GPA (double). Parallel arrays (string names[50]; int ids[50]; double gpas[50];) "work" — until one sort reorders one array and not the others, and the records shred. A struct bundles the fields of one record into a single user-defined type: struct Student { ... }; — and from that line on, Student behaves like a first-class type you can declare, copy, pass, and collect into vectors.

Three mechanical facts organize the lecture. First, define the type before use (types go at the top of the file). Second, access fields with the dot operator: s.gpa. Third, a struct variable passed by value is copied member-by-member — exactly why big records travel by const& (L26's rule, now with a reason students can see). A struct pointer uses -> ("arrow") instead of .: p->gpa means (*p).gpa.

The payoff is data design: functions like printStudent(const Student&) and findByGpa(const std::vector<Student>&, double) make programs read like the domain. And the horizon: a struct is the class-object without behavior — Module 16 adds functions inside and access control on top.

Terminology and definitions

TermDefinition
structA user-defined type bundling named members (fields)
Member / fieldOne named value inside the record
Member accessDot operator: student.gpa
Struct pointer + arrowp->gpa — shorthand for (*p).gpa
Member-wise copyAssignment copies every field (in declaration order)
Nested structA struct with a struct-typed member (Student has Address)
Record designChoosing fields, types, and the functions a record needs
std::vector<Student>A collection of records — every M9–M12 pattern applies
Parallel arraysSame data split across equal-length arrays — fragile anti-pattern
Data-only typeStruct without member functions; OOP (M16) adds behavior + access control

Syntax and C++ examples

struct Student            // the TYPE — define before use, note the semicolon
{
    std::string name;
    int    id;
    double gpa;
};                        // <- semicolon is mandatory and famously forgotten

Student s{"Ada", 1001, 3.9};        // brace-init in member order
Student t{};                        // zero/empty by member

std::cout << s.name << ' ' << s.gpa << '\n';
s.gpa = 4.0;                        // fields are ordinary variables

// records + functions (big records travel by const&)
void printStudent(const Student& s)
{
    std::cout << s.id << "  " << s.name << "  " << s.gpa << '\n';
}

Student makeStudent(const std::string& name, int id, double gpa)
{
    return Student{name, id, gpa};   // return by value: safe copy-out
}

// pointer access: arrow
Student* p{&s};
std::cout << p->gpa << '\n';        // same as (*p).gpa
p->gpa = 4.0;

// a collection of records
std::vector<Student> roster{
    {"Ada", 1001, 3.9}, {"Grace", 1002, 3.8}, {"Alan", 1003, 4.0}
};

Line-by-line code explanation

examples/struct_records.cpp:

  1. The struct block ends in ; — the demo file includes the compile error its omission produces ("expected ';' after struct").
  2. Brace initialization maps values to members in declaration order — reorder the braces and the name becomes a GPA; the printed roster exposes it.
  3. printStudent takes const Student&: no copy (L26), no mutation (the promise). Passing by value would copy every string field.
  4. promote(Student& s) — an in-place mutator via reference: the record version of L26's bump.
  5. The vector section runs three aggregate algorithms: average GPA, highest-GPA student (value-and-index via L18's pattern), count of students on the dean's list — every Module 9 pattern reused unchanged on records.
  6. The nested Address struct shows composition: a record whose member is itself a record; access chains: s.home.city.

Output prediction questions (with answers)

  1. Student a{"Ada", 1, 3.9}; Student b{a}; b.gpa = 2.0; — what is a.gpa? — 3.9: member-wise copy, independent records.
  2. p->name where p = &a — ? — "Ada"; (*p).name is identical.
  3. After promote(a) (bumps GPA by 0.1) — does the caller's a change? — Yes: reference parameter, in-place update.
  4. roster.size() for the three-student roster — ? — 3; vector operations are record-agnostic.
  5. Forgetting the struct's closing ; — ? — Compile error on the next line — the infamous misleading-message bug.

Common errors and debugging examples

ErrorSymptomFix
Missing ; after the struct blockError reported at the following lineMemorize the semicolon
p.gpa on a pointerCompile error: . needs an objectp->gpa or (*p).gpa
Parallel-array sortsRecords shred (name list misaligns)One vector<Student> instead
Big struct by valueSilent copy cost everywhereconst Student& for read-only
Brace-init order mismatchFields silently crossedFollow declaration order; verify by print
Struct used before definition"Unknown type" errorTypes at the top of the file

Classroom demonstrations

  1. The shred: sort a parallel-arrays gradebook by GPA — names no longer match IDs; then the vector<Student> sort that keeps records whole. The struct earns itself.
  2. Copy vs alias: assign b = a then mutate b — the member-wise copy is visible; then Student& alias = a — mutation shows through.
  3. Arrow vs dot: compile p.gpa with a pointer; the error message teaches; fix with ->.

Guided student activities

Record-design workshop (20 min): teams design structs for three domains (bank account, library book, game character) — members, types, which functions (print, search-by, aggregate) the record needs; designs exchange for the "one row one value" test (would parallel arrays be worse here?).

Practice problems

Summary

A struct bundles fields into a new type; dot for objects, arrow for pointers, member-wise copies, const& for big records, and vector<Student> where every array pattern applies unchanged. Records turn parallel arrays into coherent data — and set up Module 16, where structs gain behavior. Next (L29): files — making data outlive the program.

Exit ticket / formative assessment

  1. Write the definition line for a struct type Point with two doubles.
  2. Student* p = &s; — two ways to read gpa through p.
  3. Which passing mode for a print function over Student? Why?

Estimated time allocation (120 min)

SegmentMinutes
Recall (RAII quiz) + parallel-arrays failure10
struct definition/init/access + nesting35
Break10
Structs + functions + collections (capstone skeleton)40
Record-design workshop20
Exit ticket + Module 15 preview5
Programming Fundamentals Using C++ · C++17 · 16 weeksBack to top ↑