Table of Contents

1. 第一章
序言
如何在PL/I中定义指针
从哪里得到地址
得到了指针,接下来我们干什么?

Chapter 1. 第一章

序言

指针,相信大家对这个名词一定不陌生,但真正把指针用好的并不多。

记得在大学时代学习C语言,里面用很大篇幅讲述了指针的用法,当时是懂非懂,真是愧对作者谭浩强老师。工作后看到老先生的COBOL语言教材也是绝对堪称经典,真是有才,佩服佩服。但是在这本教材里,通篇没有提到指针的用法,以至于很多学过、用过的COBOL的人认为COBOL不支持指针,其实只是在COBOL里,指针不常用而已。

在主机的传统开发语言中,无论是Assembler,PL/I,或者COBOL都提供对指针的支持。Assembler自不必说,COBOL里,指针用的不多,PL/I编程,指针的使用则比较常见。对于开发人员来说,熟练地掌握指针,或者说理解内存分配方式,大多比较头疼。

利用周末时间和大家聊一聊PL/I中指针常见BASED和ADDR的用法。 (以上废话,可以跳过)

如何在PL/I中定义指针

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地用法基本了解了吗?