第2章 类型、操作符和表达式
变量和常量是程序里操作的基本数据对象。声明列出了要使用的变量,并指出它们的类型,还可能赋初始值。而操作符指定了要对它们做什么。表达式把变量和常量结合起来产生新的值。一个对象的类型决定了它的取值范围以及能对它做的操作。这些基本单元是本章的内容。
ANSI标准对基本类型和表达式做了很多的增加和小改动。现在所有整型都有 signed 和 unsigned 形式,也有了无符号常量和十六进制字符常量的表示法。浮点数操作可以在单精度下完成;还有long double 类型可以用于扩展精度。字符串常量可以在编译期间连接。枚举成为语言的一部分,使这个存在许久的特性成为正式的。对象可以声明为const,以防止被修改。算术类型之间的强制类型转换规则也已得到了加强,以支持更丰富的类型。
2.1 变量名
尽管第1章没说,但对变量名和符号常量名还是存在一些约束的。它们的名字只能由字母和数字组成,第一个字符必须是字母。下划线“_”算作字母;有时可以用它来提高长变量名的可读性。但是,你自己的变量名不要用下划线开头,因为库函数经常使用这样的名字。大小写是区分的,故 x 和 X 是两个不同的名字。传统的C实践中,使用小写做变量名,全大写做符号常量名。
内部名字的至少前31个字符是有效的。对于函数名和外部变量,也许会小于31,因为外部名称可能会被汇编器和加载器使用,这是语言无法控制的。对于外部名称,标准只保证6个字符和一个大小写的唯一性。关键字如 if,else,int,float 等是被保留的,你不能用它们做变量名。关键字都是小写的。
选择与变量的意图相关的变量名是明智的,这样看着不容易混淆。我们倾向于为局部变量特别是循环变量起短名字,而为外部变量起长名字。
2.2 数据类型和大小
C语言只有几种基本数据类型:
char 单字节,能够存入本地字符集的一个字符
int 整数,通常反映主机上整数的自然长度
float 单精度浮点数
double 双精度浮点数
另外,还可以对这些基本类型加上一些修饰符。short 和 long 可以用于整数:
short int sh;
long int counter;
这样声明时 int 可以省略,而大家也通常是这么做的。
short 和 long 的意图是为了在适合的情况下提供不同长度的整数;而 int 通常是特定机器的自然长度。short 经常是 16 位,long 是 32位,而 int 是 16位 或 32 位。编译器可以根据对应的硬件自由选择合适的长度,只要满足这些约束即可:short 和 int 至少 16位, long 至少32位,short 不能比 int 长, int 不能比long长。
修饰符 signed 和 unsigned 可以用于 char 和 任意整型。 unsigned 的数字总是大等于0,并遵循对 2的n次方做模运算的法则,其中n是该类型的bit数。因此,如果char是 8 位,则 unsigned char变量的值在 0 到 255 之间,而 signed char变量的值在 -128 到 127 之间(在使用2的补码的机器上)。无修饰符的 char 是否有符号,这取决于特定的机器,但可打印字符都是正数。
long double 类型指定了扩展精度的浮点数。和整数类似,浮点数对象的大小也是由实现定义的,float,double,long double 可能表示一种,两种或三种不同的大小。
标准头文件 <limits.h> 和 <float.h> 包含所有这些类型的符号常量,以及机器和编译器的其他属性。在附录B中讨论。
练习2-1:写个程序来确定 char,short,int 和 long 变量的范围,包括 singed 和 unsigned 的,通过打印标准头文件中合适的值,以及直接计算来实现。提高难度:确定不同浮点类型的范围。