Pointers are variables that contain a storage address. You use them to remap a storage area with different layout. For example, assume you've got records in a single data set that have different layout, say:
dcl 1 RecordType1,
2 RecType char( 01 ),
2 Field01 char( 10 ),
2 Field02 char( 20 ),
2 Number01 decimal packed( 10,2 ),
2 Field03 char( 10 );
dcl 1 RecordType2,
2 RecType char( 01 ),
2 Field01 char( 05 ),
2 * char( 02 ),
2 Number01 bin fixed( 31 ),
2 Numner02 bin fixed( 31 ),
2 Field02 char( 100 );
These declarations set aside two distinct storage areas, one for each type. Note that the records have different lengths. How would you read in the records, if you only know the type, and with this the length after having read the record? You would need to do something like:
- reading into an area long enough for the longest type,
- check the type,
- move to the structure according to the type
- process the individual fields.
This involves a lot of unnecessary data moves.
Using pointers, and the associated based()
attribute in declarations, you can define the structures as mapping, i.e. witout underlying storage. You then use a single pointer for all mappings.
dcl 1 RecordType1 based( pRecord ),
2 RecType char( 01 ),
2 Field01 char( 10 ),
2 Field02 char( 20 ),
2 Number01 decimal packed( 10,2 ),
2 Field03 char( 10 );
dcl 1 RecordType2 based( pRecord ),
2 * char( 01 ),
2 Field01 char( 05 ),
2 * char( 02 ),
2 Number01 bin fixed( 31 ),
2 Numner02 bin fixed( 31 ),
2 Field02 char( 100 );
dcl pRecord prt;
dcl LongestRecord char( 116 );
pRecord = addr( LongestRecord );
Now, you do something like this:
- read the record into the
LongestRecord
field,
- test the type by inspecting the type field
RecType
(assuming the type indicator is at the same position for each type).
- Access the individual files via qualified variable reference, e.g.
RecordType1.Field01
, or RecordType2.Number02
No more unnecessary data moves from input area to mapping area..
If you read the records from a data set, you can even avoid the first move and access the records directly in the input buffer; just tell the read statement to set the pointer, instead of moving the data into the LongestRecord
field:
dcl fInput external file record input;
...
read file( fInput ) set( pRecord );
You can now drop the declaration for the LongestRecord
variable, and the statement setting pRecord
to the address of that variable.
For completeness, only: PL/I offers another way to map a storage area with two or more different layouts: UNION
, but this is not the question here.