C语言本身的声明语法本身实际就是一种小的编程语言。一个声明包括以下几个部分(但是并非都是并不可少的): 存储类型、基本类型、类型限定词和最终的声明符(也可能包含初始化列表)。每个声明符不仅是一个新的标识符,同时也表明标识符是数组、指针、函数还是其他的任意的复杂组合。基本的思想就是让声明符模仿标识符的最终用法。
让一些程序员惊奇的是,尽管C语言是一种相当低级的语言,但是他的类型体系仍然略显抽象。语言本身没有精确定义基本类型的大小和表示法。
问:我该如何决定使用哪种数据类型?
答:如果可能用到很大的数值(大于32767或小于-32767),就使用long型。否则,如果空间很重要(例如有很大的数组或很多的结构),就使用short型。除此之外,就用int型。如果定义明确的溢出的特征很重要而负值无关紧要,或者希望在操作二进制位和字节时避免符号扩展的问题,使用对应的unsigned类型。但是,在表达式中混用有符号数和无符号数时,要特别注意。
尽管字符类型(尤其是unsigned char型)可以当成是"小"整数使用,但是这样做有时会很麻烦,不值得。编译器需要生成额外的代码来进行char型和int型之间的转换(导致目标代码量增大),而且不可预知的符号扩展也会带来一堆麻烦。
在决定使用float还是double型时也有类似的空间/时间权衡(很多的编译器在表达式求值的时候仍然把所有的float型转换为double型进行运算)。但如果一个变量的地址确定且必须为特定的类型时,以上的规则就不再适用。
很多时候,人们错误的认为C语言类型的大小都有精确的定义。事实上,能够确保的只要如下几点:
基本类型 | 最小尺寸(位) | 最小值(有符号) | 最大值(有符号) | 最大值(无符号) |
---|---|---|---|---|
char | 8 | -127 | 127 | 255 |
short | 16 | -32767 | 32767 | 65535 |
int | 32 | -32767 | 32767 | 65535 |
long | 64 | -2147483647 | 2147483647 | 4294967259 |
表中的值是标准的能够确保的最小值。很多系统允许更大的值,但可移植的程序不能依赖这些值。
如果因为某种原因需要声明一个精确大小的变量,确保像C99的<inttypes.h>那种用某种适当的typedef封装这种选择。通常,需要精确大小的唯一的合理的原因就是试图符合某种外部加强的存储布局。