Table of Contents
Table of Contents
指针,相信大家对这个名词一定不陌生,但真正把指针用好的并不多。
记得在大学时代学习C语言,里面用很大篇幅讲述了指针的用法,当时是懂非懂,真是愧对作者谭浩强老师。工作后看到老先生的COBOL语言教材也是绝对堪称经典,真是有才,佩服佩服。但是在这本教材里,通篇没有提到指针的用法,以至于很多学过、用过的COBOL的人认为COBOL不支持指针,其实只是在COBOL里,指针不常用而已。
在主机的传统开发语言中,无论是Assembler,PL/I,或者COBOL都提供对指针的支持。Assembler自不必说,COBOL里,指针用的不多,PL/I编程,指针的使用则比较常见。对于开发人员来说,熟练地掌握指针,或者说理解内存分配方式,大多比较头疼。
利用周末时间和大家聊一聊PL/I中指针常见BASED和ADDR的用法。 (以上废话,可以跳过)
DCL EXAMPLE_P POINTR;
EXAMPLE_P在内存中占四个字节,它可以存储数据的地址。它就是指针。 地址大家一定不陌生吧?前几天我在三菱東京UFJ銀行申请了一个账户,说过两周后把卡做好了给我邮送过来,地址如下:
邮编:273-0025 地址:千葉県 船橋市 印内町 643 エクセレント 西船 101
两个小时前邮递员按地址把信给我送了过来,签收之后,OK。
主机中地址是用四个字节的二进制数来表示的。
数据就是通过地址来引用的。我们在程序中定义的变量其实就是地址。
只不过因为我们不是骇客帝国中的厉害角色,看满屏幕的1和0就能看出五彩缤纷的世界。所以给地址起了个友好的名字,这样我们才能更明白。
定义完了指针,我们需要给它一个真正的地址。地址可能来自于某个程序的参数,或者是这个参数的一部分,或者是程序内部的某个地方,总之得给它才行。
DCL FLOUR_ITEM CHAR(6);
EXAMPLE_P = ADDR(FLOUR_ITEM);
这里我们用ADDR函数取得数据FLOUR_ITEM的地址,然后把这个地址给了EXAMPLE_P。
我们定义一个STRUCTURE,使用这个指针。
DCL 01 FISH_STRUCTURE BASE(EXAMPLE_P),
05 FISH_STAGE1 CHAR(2),
05 FISH_STAGE2 CHAR(2),
05 FISH_STAGE3 CHAR(2);
FISH_STRUCURE是一个DUMMY SECTION。
什么叫DUMMY SECTION?DUMMY,顾名思义,虚拟的,假的;SECTION,部分,区域。DUMMY SECTION就是虚拟的部分。为了说明FLOUR_ITEM和FISH_STRUCTURE的关系,我给大家举个例子:
以前东北有的地方结婚的时候,娘家需要做一些面鱼。做法就是把面和好,然后用鱼形的模具扣到上头,一条面鱼就做成了。有钱的人家就用上等的白面,条件差一点的用高粱米面。因为用同样的模子,做出来的面鱼形状相同,只是外观、色泽、口感迥异。
白面或者高粱米和的面就是FLOUR_ITEM,它是实际要吃的东西。
这个鱼形的模子就是FISH_STRUCTURE。本身没有没有提供实际的原料,只是用的时候扣到白面或高粱米面上,所以是DUMMY SECTION。
我们可以把FLOUR_ITEM分成两类,白面和高粱米面:
DCL FLOUR_ITEM1 CHAR(6) INIT(‘AABBCC’);/*(白面)*/ DCL FLOUR_ITEM2 CHAR(6) INIT(‘aabbcc’);/*(高粱米面)*/
当 EXAMPLE_P = ADDR(FLOUR_ITEM1)的时候, FISH_STAGE1 = ‘AA’, FISH_STAGE2 = ‘BB’, FISH_STAGE3 =’CC’。
当 EXAMPLE_P = ADDR(FLOUR_ITEM2)的时候, FISH_STAGE1 = ‘aa’, FISH_STAGE2 = ‘bb’, FISH_STAGE3 =’cc’。
在EXAMPLE_P没有被赋予实际地址之前,FISH_STRUCTURE是不能被使用的。更不能给FISH_STRUCTURE的数据项初始化。
FISH_STRUCTURE的长度跟FLOUR_ITEM没有关系,既可以大于、小于,也可以等于FLOUR_ITEM的长度。
当然你也可以定义一个小兔子模具,象下面这样:
DCL 01 RABBIT_STRUCTURE BASE(EXAMPLE_P), 05 RABBIT _STAGE1 CHAR(1), 05 RABBIT _STAGE2 CHAR(2), 05 RABBIT _STAGE3 CHAR(3);
当 EXAMPLE_P = ADDR(FLOUR_ITEM1)的时候, RABBIT _STAGE1 = ‘A’, RABBIT _STAGE2 = ‘AB’, RABBIT _STAGE3=’BCC’。
当 EXAMPLE_P = ADDR(FLOUR_ITEM2)的时候, RABBIT _STAGE1 = ‘a’, RABBIT _STAGE2 = ‘ab’, RABBIT _STAGE3=’bcc’。
DUMMY SECTION并不实际分配内存。而且DUMMY SECTION定义的数据项的类型可以与作为基底的数据的类型完全不同。
到此为止,大家对BASE和ADDR地用法基本了解了吗?