我正在尝试学习PL1中指针的使用。然而,以下方法不起作用
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);
输出:
DISPLAY MYVAR: 1234567890
DISPLAY MYPTR:
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 );
这些声明留出两个不同的存储区域,每种类型一个。请注意,这些记录具有不同的长度。如果你只知道记录的类型,以及读取记录后的长度,你会如何读取记录?你需要做一些类似的事情:
- 读入足够长的区域以用于最长类型
- 检查类型
- 根据类型移动到结构
- 处理各个字段
这涉及到大量不必要的数据移动。
使用指针和声明中关联的based()
属性,可以将结构定义为映射,即没有底层存储。然后对所有映射使用一个指针。
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 );
现在,你做这样的事情:
- 将该记录读取到CCD_ 2字段中
- 通过检查类型字段
RecType
来测试类型(假设每个类型的类型指示符处于相同的位置( - 通过限定的变量引用访问各个文件,例如
RecordType1.Field01
或RecordType2.Number02
不再有不必要的数据从输入区域移动到映射区域。。
如果您从数据集中读取记录,您甚至可以避免第一次移动,直接访问输入缓冲区中的记录;只需告诉read语句设置指针,而不是将数据移动到LongestRecord
字段:
dcl fInput external file record input;
...
read file( fInput ) set( pRecord );
现在可以删除LongestRecord
变量的声明,以及将pRecord
设置为该变量地址的语句。
为了完整性,只有:PL/I提供了另一种方法来映射具有两个或多个不同布局的存储区域:UNION
,但这不是问题所在。