Reputation: 157
I am trying to learn the use of pointers in PL1. However below approach is not working
DCL MYPTR PTR;
DCL MYVAR CHAR(10) INIT('1234567890');
PUT SKIP(2) LIST('DISPLAY MYVAR: ',MYVAR);
MYPTR = ADDR(MYVAR);
PUT SKIP(2) LIST('DISPLAY MYPTR: ',MYPTR);
OUTPUT:
DISPLAY MYVAR: 1234567890
DISPLAY MYPTR:
Upvotes: 0
Views: 1478
Reputation: 2745
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:
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:
LongestRecord
field,RecType
(assuming the type indicator is at the same position for each type).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.
Upvotes: 3