Lecture 18: Records


Record

In the last lecture we learned how an array can store variables of the same type in a nicely ordrered, indexed way, like in a file cabinet with in each drawer the same type of information. If we want to group variables together that are not of the same type, we can do this in a record.
 

The three file cabinets store things of the
same type, just like arrays. The left one
could be "bytes", the middle one
"integers" and the right one "reals".

 

The file cabinet in the center is used for
storing things of mixed type. In the same
way, a record is used for storing variables
of different type, integers, real, or
whatever, all together in the same box.


 
 A record is a set of variables of mixed type. 


Declaring a record


A visualization of a record, namely a motley set of variables. Each variable inside a record is called a field. Here we have 5 fields: a byte (b), a real (f), a boolean (c), a single array of reals (r) and a double array of reals (m).

To declare a record we do the following
 

 Var name:
   record
       item1: type1; 
       item2: type2;
          |
       itemN: typeN;
   end;
with
name: the name for the variable holding the record.
item1..itemN: the name for the fields in the record. These have the same rules as the other identifiers for variables, constantes, procedures, etc. Note that we can put as many fields in the record as we want, with any combination of types.
type1..typeN: the type of the fields of the records.

As an example, the definition of a record containing the information of a student might have fields for name, year, and tuition fees paid:
 Var student:
   record
     name: string;
     year: integer;
     propinas: boolean; 
   end;
This record can only contain the information of a single student. With the information of the previous lecture (lecture 17), however, we know how to build an array that can store the information of may equal objects of any type, even records. let's build an array of 1000 students:
 
 Var students: array[1..1000] of 
   record
     name: string;
     year: integer;
     propinas: boolean;
   end;

Later we will see that we can much more easily do this with a new type definition (see lecture 19).


Using a record

To access a record we use the format
 
 name.field 

For example, to assign values to the record student we can do the following

  student.name := 'Peter Stallinga';
  student.year := 2002;
  student.propinas := TRUE;

or in the example of the array of records students:

  i := 1055;
  students[i].name := 'Peter Stallinga';
  students[i].year := 2002;
  students[i].propinas := TRUE;

Note the structure of arrays of records. students is an array of records, therefore, students[i] is one of these records and if we want to assign something to a field we use the period and the fieldname, so students[i].name is a string containing the name of student number i.
Wrong syntax would be students.name[i] (we could use this if we had a single record students containing a field name that is an array)
Also wrong: students.[i]name, which doesn't make sense at all.

Another example:

  Var coordinate:
    record
      x: real;
      y: real;
    end;

  coordinate.x := 1.0;
  coordinate.y := 0.0;

This is not exactly a set of variables of mixed type, so in principle we could also do this with an array:

  Var coordinate: array[1..2] of real;

  coordinate[1] := 1.0;
  coordinate[2] := 0.0;

but, the first version, with the record is more logical.
Another example:

  Var address:
    record
      street: string;
      housenumber: integer;
      andar: integer;
      porta: char;
    end;

  address.street := 'Rua Santo Antonio';
  address.housenumber := 34;
  address.andar := 3;
  address.porta := 'E';

  writeln(address.street, '  ', address.housenumber);
  writeln(address.andar, address.porta);

In the above example we had to write many time the word "address". To save time, in PASCAL exists the combination with recordname do, which means that in the instruction after it (everything between begin and end) the variables (that the compiler doesn't know otherwise!) get the recordname in front of it. Therefore, the above two lines of code can be rewritten in a more readable form as

  with address do
     begin
       writeln(street, '  ', housenumber);
       writeln(andar, porta);
     end;


Quick Test

To test your knowledge of what you have learned in this lesson, click here for an on-line test.

Peter Stallinga. Universidade do Algarve, 15 Abril 2002