Show understanding of the purpose of a record structure to hold a set of data of different data types under one identifier

10.1 Data Types and Records

Objective

Show understanding of the purpose of a record structure to hold a set of data of different data types under one identifier.


1. Primitive data types required by the syllabus

Primitive type (syllabus)Typical use‑caseCambridge pseudocode example
INTEGERCounts, ages, indexesage : INTEGER
REALMeasurements, averages, GPAgpa : REAL
CHARSingle‑character flags (e.g. gender ‘M’/‘F’)gender : CHAR
STRINGNames, addresses, free‑textname : STRING[30]
BOOLEANTrue/false conditionsisFullTime : BOOLEAN
DATECalendar datesenrolDate : DATE
ARRAYHomogeneous collections indexed by an integermarks : ARRAY[1..10] OF INTEGER
FILEExternal storage of records or arraysstudentFile : FILE


2. What is a record?

A record (called a structure in some languages) is a composite data type that groups together a fixed number of elements, called fields. Each field may have a different primitive type, but all fields are accessed through a single identifier – the record variable name.


3. Why use records?

  • Logical grouping of related data (e.g. all information about a student).
  • One identifier is enough when passing the whole entity to a procedure or function.
  • Improves readability and mirrors real‑world objects.
  • Allows a whole entity to be written to or read from a file with a single WRITE/READ statement.
  • Facilitates abstraction – the internal fields can be hidden behind operations (ADTs).


4. Design activity – choosing the right primitive types

For each of the following real‑world situations, list the fields you would need, decide which primitive type is most appropriate for each field, and write the Cambridge‑style record definition.

  1. Library book – think about title, author, ISBN, number of pages, availability.
  2. Network packet header – consider source address, destination address, protocol, length, checksum.
  3. Employee – name, employee ID, date of hire, salary, full‑time status.

Tip: Use CHAR only for a single character (e.g. a grade code). Use STRING[n] when you need more than one character. Use INTEGER for whole numbers, REAL for values that may have a fractional part, and DATE for calendar dates.


5. Defining a record – Cambridge pseudocode format

RECORD Student

name : STRING[30] // full name

age : INTEGER // years

gpa : REAL // grade point average

enrolDate : DATE // date of enrolment

END RECORD


6. Example record – Student – field summary

FieldData typeTypical size (bytes) on a 32‑bit machine
nameSTRING[30]30
ageINTEGER4
gpaREAL8
enrolDateDATE8

Memory layout (no padding)

SizeStudent = 30 + 4 + 8 + 8 = 50 bytes

Memory layout with 4‑byte alignment (common on 32‑bit CPUs)

Two padding bytes are inserted after name to reach the next multiple of 4.

SizeStudent = (30 + 2) + 4 + 8 + 8 = 52 bytes

Suggested diagram: memory layout of a Student record showing each field and any padding bytes.


7. Accessing record fields

DECLARE student1 : Student

student1.name := "Alice Johnson"

student1.age := 20

student1.gpa := 3.75

student1.enrolDate := "2023‑09‑01"


8. File handling with records

8.1 Binary file – writing and reading a whole record

The Cambridge syllabus expects the WRITE and READ statements to operate on a record variable. This stores the record in a binary file, preserving the exact layout (including any padding).

OPEN studentFile FOR WRITE AS "students.dat"

WRITE studentFile, student1 // whole record written at once

CLOSE studentFile

DECLARE student2 : Student

OPEN studentFile FOR READ AS "students.dat"

READ studentFile, student2 // whole record read at once

CLOSE studentFile

8.2 Text file – writing fields individually (useful for debugging)

OPEN studentFile FOR WRITE AS "students.txt"

WRITE studentFile, student1.name, student1.age,

student1.gpa, student1.enrolDate

CLOSE studentFile


9. Procedures and functions that use records

9.1 Procedure that receives a record (by reference)

PROCEDURE printStudent(s : Student) // parameter passed by reference

OUTPUT "Name: " & s.name

OUTPUT "Age: " & s.age

OUTPUT "GPA: " & s.gpa

OUTPUT "Enrolled: " & s.enrolDate

END PROCEDURE

CALL printStudent(student1)

9.2 Function that returns a value derived from a record

FUNCTION isHonours(s : Student) : BOOLEAN // returns TRUE if GPA ≥ 3.5

IF s.gpa >= 3.5 THEN

RETURN TRUE

ELSE

RETURN FALSE

END IF

END FUNCTION

DECLARE honours : BOOLEAN

honours := isHonours(student1)

OUTPUT "Honours student? " & honours

9.3 Parameter‑passing note

  • By reference (default in Cambridge pseudocode) – the procedure works on the original record; any change is reflected outside the call.
  • By value – a copy of the record is passed; changes inside the procedure do not affect the original. Use the keyword VALUE if you need this behaviour.


10. Records as concrete implementations of an ADT

A record describes the data representation of an abstract data type. The ADT also defines the operations that can be performed on that data.

AspectRecord (concrete)ADT (abstract)
Data representationRECORD Student … END RECORD“Student” ADT – a logical entity that stores name, age, GPA, enrolDate.
OperationsProcedures/functions such as printStudent, isHonoursInsert, Delete, Search, Update (defined in the specification of the Student ADT).
Implementation exampleArray of Student records used as a simple list.List ADT that stores Student objects.

10.1 Storing several students in a list (array‑based ADT)

CONST MAX_STUDENTS = 100

DECLARE studentList : ARRAY[1..MAX_STUDENTS] OF Student

DECLARE n : INTEGER := 0 // current number of students

PROCEDURE addStudent(s : Student)

IF n < MAX_STUDENTS THEN

n := n + 1

studentList[n] := s

END IF

END PROCEDURE

FUNCTION findByName(searchName : STRING[30]) : INTEGER // returns index or 0

FOR i FROM 1 TO n DO

IF studentList[i].name = searchName THEN

RETURN i

END IF

END FOR

RETURN 0

END FUNCTION


11. Step‑wise refinement – decomposing a problem using records

Task: Store a set of student results in a file.

HIGH‑LEVEL: storeStudentResults()

1. Define the Student record ← see §5

2. Open the binary file for writing ← see §8.1

3. For each student:

a. Read data from the keyboard

b. Fill a Student variable

c. WRITE the variable to the file

4. Close the file

Each step can be turned into its own procedure (e.g. readStudentData, writeStudentRecord), illustrating the decomposition required by the syllabus.


12. Relationship to other syllabus topics

  • Arrays – homogeneous collections. A record may contain an array as a field (e.g. marks : ARRAY[1..5] OF INTEGER).
  • Abstract Data Types (ADTs) – a record provides the concrete representation; the ADT specifies the allowed operations.
  • File handling – records are the natural unit of persistence; binary WRITE/READ demonstrates the link between memory and storage.
  • Structured programming & procedures – records are passed to and returned from procedures/functions, supporting modular design.


13. Glossary (key terminology)

Record: a composite data type that groups a fixed set of fields of possibly different primitive types.

Field: an individual component of a record, identified by a name and a data type.

Identifier: the name given to a variable, record type, or field.

Dot operator (.): syntax used to access a field of a record (e.g. student.age).

Padding: unused bytes added by the hardware to satisfy alignment requirements; they increase the total size of a record.

ADT (Abstract Data Type): a logical description of a data structure that specifies the operations that can be performed, without fixing the implementation.

Parameter passing: the method by which arguments are supplied to procedures/functions (by reference – default, or by value).


14. Key take‑aways

  • A record groups related data of different primitive types under a single identifier, simplifying data handling.
  • Choosing the most appropriate primitive type for each field is part of the design process.
  • Cambridge‑style pseudocode uses RECORD … END RECORD and the dot operator (.) for field access.
  • Whole records can be written to or read from a binary file with a single WRITE/READ statement.
  • Records can be passed to procedures (by reference) and returned from functions, supporting modular programming.
  • Records are concrete implementations of an ADT; they can be stored in other ADTs such as lists, stacks, or queues.
  • Understanding memory layout (including padding) helps predict storage requirements and explains why binary I/O works as expected.
  • Step‑wise refinement shows how a high‑level task can be decomposed into smaller procedures that each manipulate a record.