2.2 内部类型
计算机程序可以看成作用于某些输入,产生某些期望的结果(输出)的函数。在传统的语言中,函数计算是分步进行的,每一步都可能产生中间结果(Intermediate Result),并将它存储在程序变量中。语言之间的差异在于,其使用的数据类型、对数据所能进行的操作及存储和使用数据的方法等方面的不同。
通常,语言提供一些内部类型,这些类型又称语言定义类型(Language-defined Type),它们多数都能反映基本硬件特性。在语言级,一种内部类型标识共用某些操作的数据对象的抽象表示。例如,整数表示能实现+,-,*和/等定点操作的数据对象的集合。语言的编译器把这些抽象表示映射到实际的实现。例如,抽象表示“25”被映射成位串“00011001”(二进制序列),两个整数相加被映射成机器的定点加操作。
按照抽象的观点,内部类型至少具有4个方面的优越性。
1.基本表示的不可见性
程序员不能访问表示某类型的值的基本位串,这些基本位串对程序员是不可见的。通过作用于位串的操作使位串改变,这种改变的结果作为内部类型的新值对程序员是可见的,但新位串仍是不可见的。例如,整数加
25+9
属抽象层,对程序员是可见的,而对于翻译后的基本表示(二进制位串)
0001 1001 + 0000 1001
对程序员是不可见的,机器运算后的结果的基本表示
0010 0010
对程序员也是不可见的,但这个基本表示经翻译后的结果“34”作为计算结果的新值对程序员是可见的。
基本表示的不可见性至少具有下列4个优点。
(1)不同的程序设计风格
在传统硬件中,任何对象都可看成不加解释的位串,任何机器指令均可对这样的位串进行操作。一个存储单元的内容(位串)到底是一个整数还是其他什么,该进行什么样的操作,完全由程序员来管理。然而,数据类型的管理完全由实现来进行,这使得程序设计风格完全不同。
(2)可写性
可写性是一个难以度量的性质,一般是指对某个问题以习惯和自然的方式来表述一个程序的可能性,以便程序员不必注意语言的细枝末节和技巧,把精力集中在问题求解上。虽然这是一个很主观的准则,但“25”比“00011001”的可写性好。可写性好可使程序员减少书写错误,从而使程序容易调试。
(3)可读性
语言的可读性表现在用该语言编制的程序可进行逻辑跟踪,通过跟踪程序进行校验,发现程序中所出现的错误。可读性也是一个主观准则,它在很大程度上依赖于感觉和风格。显然,“25”比“00011001”的可读性好。
(4)可修改性
数据的抽象摆脱了许多机器的细节,使得程序便于修改。如果抽象的表示有改变,不会影响使用这种抽象的程序,不需要修改程序。因此,也提高了程序的可移植性,程序可以向使用不同内部数据表示的机器移植。
语言提供了读/写内部类型值的语句,大多数语言还提供了格式输出功能。实际机器以一种结构复杂的方法解释这些格式,让外部设备来执行输入/输出,不同的机器有不同的解释方法,而高级语言掩盖了包含在输入/输出中的复杂物理资源(例如寄存器、通道等)。
2.编译时能检查变量使用的正确性
若语言中包含变量说明,那么对变量的非法操作可以在编译时查出。编译程序在编译时要对类型进行检查,编译时的类型检查称为静态类型检查(Static Type Checking)。静态类型检查不可能将一个程序中的所有数据操作错误检查出来,有的错误还需在运行时检查。例如,表达式i/j在静态检查时可能被认为是正确的,只要i和j都是实数。但在运行时尚需做进一步的检查,一旦j为0,表达式就不再正确。
3.编译时可以确定无二义的操作
通常,语言都用少数几个运算符来表示大量的操作,例如运算符“+”可以表示整数加,也可以表示实数加,有的语言甚至用来表示逻辑加。涉及执行表达式A+B的机器操作可由编译器来确定,因为编译时A和B的类型是确定的,编译器可根据A和B的类型来确定相应的操作。运算符的意义依赖于操作数的类型,它称为超载(或重载)(Overload)或多态(Polymor-phic)。运算符“+”是超载的例子,它对整数加和实数加都有意义,编译时以不同的机器指令来实现。如果一个语言不允许运算符出现超载,那么,对不同的操作就要引入不同的运算符,这就使得语言定义变得冗长,程序员记忆的符号也要增加。若语言使一个运算符表示过多的操作,那么程序就变得难于理解。因此,合理地使用超载,可以提高语言的可读性和可用性(Usability)。
4.精度控制
在某些语言中,程序员可以通过数据类型来显式定义数据的精度(Accuracy)。例如,FORTRAN语言允许用户选择单精度或双精度浮点数;ALGOL 68语言允许使用long real,long long real,long int和long long int来选择浮点数和定点数的精度;Ada语言的数字数据类型的精度也可由程序员来选择。精度说明可以看成编译程序实施空间优化的命令,也可以看成对编译程序插入监控变量值的运行时检查。后者为估计计算结果的正确性提供了有效途径。精度说明也为程序员提供了不同情况采用不同存储字长的手段,以便有效地利用存储空间。程序的修改也很容易,若只需改变相应的字长,就仅限于改变源程序中的相关类型说明。
传统的程序设计语言都定义了内部类型,读者应当很好地了解和掌握这些类型。