• Keine Ergebnisse gefunden

Records, Classes, and Pointers

10.S. The Expression Statement

11. Records and Pointers

11.1. Records, Classes, and Pointers

Until now, all information used by a program during its execution has had to be maintained either in a file (which may continue to exist after the program completes) or in the outer or local variables declared in the program. Data in a file are clumsier to access than data in named variables (see Example 10.11-4). However, if a program is to deal with information of unknown quantity and structure, it is not possible to create a named variable for every possible datum that may be manipulated during the course of the program's execution.

Records provide a repository for data that can be accessed more easily than data in files, although not so easily as data in named variables. A program may allocate as many records as it needs during execution (within the constraints of the computer's memory size). Since records are stored in the program's memory, they disappear at the end of a MAINSAIL execution unless explicitly stored in a file (the Structure Blaster provides one convenient technique for doing this; see the "MAINSAIL Structure Blaster User's Guide").

The pointer data type is used to access records. A pointer is so named because it "points" to a record; Example 11.1-1 shows how a pointer p pointing to a record r is depicted graphically.

Every record may be thought of as containing zero or more variables, possibly of different data types. Every record has a "class", or shape, telling which variables are present in the record and in which order they occur. The variables are called "fields" of the record or of the record's class. Each field is referred to by a name. The names of classes and of the fields they contain are declared in "class declarations". For example, the class declared in Example 11.1-2 is named "c" and has two integer fields named "inti" and "int2" and a string field named

"stringField". The semicolon preceding the closing parenthesis of a class declaration is optional (such an optional semicolon is allowed in procedure parameter lists as well, although no examples appear in this tutorial).

P ----+

+----> +---+

I I

I r I

I I

+---+

Example 11.1-1. A Pointer p Pointing to a Record r

CLASS c (

INTEGER intl,int2;

STRING stringField; # This semicolon is optional

) ;

Example 11.1-2. A Sample Class Declaration

A record of the class c of Example 11.1-2 would be depicted diagrammatically as shown in Example 11.1-3. Sometimes the data types or values of the fields are shown in the boxes in addition to or instead of the field names ..

+---+

I intl

+---+

I int2

+---+

I stringField I

+---+

Example 11.1-3. A Record of Class c

Most pointers are "classified"; i.e., they are allowed to point to records of only one class. That class is specified when the pointer is declared. Example 11.1-4 shows the declaration of a pointer p declared to point to records of the class c of Example 11.1-2.

POINTER(c) Pi

Example 11.1-4. A Pointer Declared to Be of Class c

At any given moment a pointer variable points either to a record (or a data section, as described in Chapter 15) or to nothing at all; in the latter case the pointer is said to be (or to have the value) "nullPointer". The keyword "NULLPOINTER" represents the value nullPointer;

performing the assignment "p := NULLPOINTER" causes a pointer variable p to have the value nullPointer, i.e., to point to nothing. The value nullPointer is the pointer Zero.

Records may themselves contain fields that are pointers to other records. Example 11.1-5 shows some class and pointer declarations and a data structure built up with pointers and records of the declared classes. "0" is used to depict a pointer that is nullPointer. The structure of Example 11.1-5 contains records with pointers to each other and to themselves.

Note that there is no path in Example 11.1-5 from p or q to REC 6, i.e., there is no expression of the form "p.n.f2.f3 ... " or "Q.n.f2.f3 ... " ("f' stands for "field") that points to REC 6. If there is no path to REC 6 from some named variable, REC 6 is said to be "inaccessible". Such a record is useless, because it can never be referred to from a program. The MAINSAIL garbage collector eventually tracks down inaccessible records and reuses the space they occupy, so REC 6 is doomed.

Example 11.1-5 illustrates the exception to the rule that every identifier in MAINSAIL must be declared before it is used. A class need not be declared before its name is used in other declarations. The class declaration must appear, however, before any pointers of the class are used to reference fields of records of the class. Example 11.1-5 also shows that a named variable (e.g., the pointer p) may have the same name as the field of a class; furthermore, the same field name may be used in different classes. The uses of such names are always distinguishable by context.

CLASS cl ( STRING Si

) i

POINTER(c2) Pi # c2 need not have been declared at

# this point

Example 11.1-5. Some Declarations and a Data Structure (continued)

CLASS c2 (

POINTER(c1) p1;

POINTER(c2) p2;

) ;

POINTER(c2) p,q;

+---+

I

REC2 I REC 3

REC 1

+--> +---+ +--> +---+

P -->

+---+

I I s

=

"Hello" I I p1 0 I

I p1

>-+--+-+ +---+ +---+

+---+

I I P

>---+--+

I p2

>-+--+

I p2

>-+--+

I

+---+

I

+---+

+---+

I I I

I

+---+ +---+

+---+

REC 5 REC 6

REC 4

+--> +---+ +---+

+--> +---+

I p1

>-+--+

I p1 0 I

I p1 0 I

+---+ +---+

+-+ +---+

I p2 0 I I p2

>-+--+

I p2

>-+----+ +---+ +---+

q -+ +---+

A field of a record is referred to by means of the pointer to the record followed by a period (".") followed by the field name. Therefore, the following statements are true of the above diagram:

p.p1.s = "Hello", since p points to REC 1, and p.p1 points to REC 2, and the "s" field of REC 2 has the value "Hello".

p.p2

=

q, since both p.p2 and q point to REC 4; two pointers are equal if and only if they point to the same record.

Example 11.1-5. Some Declarations and a Data Structure (continued)

q.p2.pl = p.pl, since q.p2 points to REC 5, so q.p2.pl points to REC 2, which is also pointed to by p.pl.

p.pl.p

=

p.pl.p.p2, since p.pl.p points to REC 3, and the p2 field of REC 3 points to REC 3.

Example 11.1-5. Some Declarations and a Data Structure (end)