C语言的内建类型相对比较少。算术类型可以随意混用在表达式里,最终的结果由一个简单的数据类型转换机制来决定。这个数据类型转换表参见本书的附录D。
在解答这一章里的部分谜题时,需要知道某些字符对应的整数值。附录C的ASCII表给出了字符及其对应的八进制和十进制的值。请注意,这一章里的部分谜题在Intel 8086系列和Motorola 68000系列机器上所给出的输出是不一样的,我们将同时给出这两种输出。
谜题2.1 字符、字符串和整数类型
请问,下面这个程序的输出是什么?
#include <stdio.h>
#define PRINT(format,x) printf(#x " = %" #format "\n", x)
int integer = 5;
char character = ’5’;
char *string = "5";
main()
{
PRINT(d,string); PRINT(d,character); PRINT(d,integer);
PRINT(s,string); PRINT(c,character); PRINT(c,integer=53);
PRINT(d,(’5’>5)); (2.1.1)
{
int x = -2;
unsigned int ux = -2;
PRINT(o,x); PRINT(o,ux);
PRINT(d,x/2); PRINT(d,ux/2);
PRINT(o,x>>1); PRINT(o,ux>>1);
PRINT(d,x>>1); PRINT(d,ux>>1); (2.1.2)
}
}

输出:
string = 一个地址值 (2.1.1)
character = 53
integer = 5
string = 5
character = 5
integer=53 = 5
( ’5’>5 ) =1
x = 177776 (2.1.2-Intel 8086)
ux = 177776
x/2 = -1
ux/2 = 32767
x>>1 = 177777 或 77777
ux>>1 = 77777
x>>1 = -1 或 32767
ux>>1 = 32767
x = 37777777776 (2.1.2-Motorola 68000)
ux = 37777777776
x/2 = -1
ux/2 = 2147483647
x>>1 = 37777777777 或 17777777777
ux>>1 = 3777777777
x>>1 = -1 或 2147483647
ux>>1 = 2147483647

解惑2.1 字符、字符串和整数类型
2.1.1
|
PRINT(d, "5") |
“%d”格式将使得printf函数把有关参数输出为一个十进制数值。"5"是一个指向一个字符数组(长度为两个字节,内容是字符’5’和’’)的指针。 |
|
PRINT(d, ’5’) |
“%d”格式将使得字符’5’的十进制值被输出。 |
|
PRINT(d, 5) |
把整数5输出为一个十进制数值。 |
|
PRINT(s, "5") |
“%s”格式将使得printf函数把有关参数解释为一个字符串,即一个指向某个字符数组的指针。因为"5"是一个指向字符数组的指针,所以该数组的内容(字符“5”)将被输出。 |
|
PRINT(c, ’5’) |
“%c”格式将使得printf函数把有关参数转换为该参数的值所代表的字符。因为’5’就是字符“5”的编码值,所以字符“5”将被输出。 |
|
PRINT(c, 53) |
正如刚才看到的那样,十进制数值53其实就是字符“5”的ASCII代码。 |
|
PRINT(d, (’5’>5)) |
’5’对应着整数值53,它大于整数5。 |
2.1.2
|
初始值:x= -2,ux= -2 |
x是一个带符号整数,ux是一个无符号整数。 |
|
PRINT(o, x) |
“%o”格式将使得printf函数把有关参数输出为一个八进制数值。在以二进制补码表示一个八进制整数时,负数的最高位是“1”。在16位的机器(例如Intel 8086)上,这意味着八进制整数的最左边的数字是1。 |
|
PRINT(o, ux) |
无论是带符号整数、还是无符号整数,-2都是一个由1和0构成的字符串。 |
|
PRINT(d, x/2) |
对于带符号的变量,负数的除法运算结果总是与预期的一样。 |
|
PRINT(d, ux/2) |
对于无符号的变量,负数将被解释为一个大的正整数。 |
|
PRINT(o, x>>1) |
我们前面已经见过这样的谜题了。在C语言的某些版本里,带符号整数的向右移位操作会把符号位复制到因为移位而空出来的最高位,操作结果的符号位不发生变化——符合人们的预期。但要注意:这取决于所使用的C语言编译器。 |
|
PRINT(o, ux>>1) |
对无符号整数进行向右移位操作将使得最高位被填充为0。 |
|
PRINT(d, x>>1) |
在十进制里,如果保留符号位,那么对-2右移一位的结果是-1;否则,结果将是32767(对使用二进制补码来表示负数的16位机器而言)。 |
|
PRINT(d, ux>>1) |
对于无符号整数-2,向右移一位的结果总是32767。 |






