《C Primer Plus 》例题解析 程序清单3.4 print2.c 程序


/* print2.c--更多printf()的特性 */#includeint main(void ){unsigned int un = 3000000000; /* int为32位和short为16为的系统 */short end = 200;long big = 65537;long long verybig = 12345678908642;printf("un = %u and not %d\n", un, un);printf("end = %hd and %d\n", end, end);printf("big = %ld and not %hd\n", big, big);printf("verybig = %lld and not %ld\n", verybig, verybig);return 0;}

运行结果:

un = 3000000000 and not -1294967296end = 200 and 200big = 65537 and not 1verybig = 12345678908642 and not 1942899938

解析:

总结:1个字节 = 8位 n表示位

整数有符号取值范围:[-2^(n-1), 2^(n-1) -1]

整数无符号取值范围:[0, 2^n-1]

详细看下面整型的类型和取值范围:

一、整型(int、short、long、long long)
1、有符号整型
有符号整型的数据类型通常包括 int、short、long、long long 四种,因为是有符号类型,所以前面要加上 signed ,但是通常省略,也就是说在代码中直接打出 int 类型就代表是有符号类型的。

(1)int类型
数据类型大小是 4 字节,能表示的数值范围是
-2^(32-1) – 2^(32-1)-1 (即 -2147483648 ~ 2147483647)
打印类型是 %d ,使用格式为 int 名 = 值;

(2)short类型
数据类型大小是 2 字节,能表示的数值范围是
-2^(16-1) – 2^(16-1) -1 (即 -32768 ~ 32767)
打印类型是 %hd ,使用格式为 short 名 = 值;

(3)long类型
数据类型大小是 4 字节,能表示的数值范围是
-2^(32-1) – 2^(32-1)-1 (即 -2147483648 ~ 2147483647)
打印类型是 %ld ,使用格式为 long 名 = 值;

(4)long long类型
数据类型大小是 8 字节,能表示的数值范围是
-2^(64-1) ~ 2^(64-1)-1

打印类型是 %lld ,使用格式为 long long 名 = 值;

2、无符号整型
无符号数用 unsigned 表示 ,只表示数据量,而没有方向(没有正负,且无符号数最高位不是符号位,而就是数的一部分,无符号数不可能是负数。

(1)unsigned int 类型
数据类型大小是 4 字节,能表示的数值范围是
0 – 2^(32)-1 (即 0~4294967295)
打印类型是 %u ,使用格式为 unsigned int 名 = 值;

(2)unsigned short 类型
数据类型大小是 2 字节,能表示的数值范围是
0 ~ 2^16 -1 (即 0~65535)
打印类型是 %hu ,使用格式为 unsigned short 名 = 值;

(3)unsigned long 类型
数据类型大小是 4 字节,能表示的数值范围是
0 – 2^(32)-1 (即 0~4294967295)
打印类型是 %lu ,使用格式为 unsigned long 名 = 值;

(4)unsigned long long 类型
数据类型大小是 8 字节,能表示的数值范围是
0~2^64-1
打印类型是 %llu ,使用格式为 unsigned long long 名 = 值;

printf("un = %u and not %d\n", un, un);

%u 指打印无符号int类型,取值范围为:[0, 2^32-1] (即 0~4294967295)

30 0000 0000并未超出这个类型的取值范围,所以结果un = 30 0000 0000

%d 指打印有符号的int类型,取值范围为:[-2^31, 2^31 -1](即 -2147483648 ~ 2147483647)

30 0000 0000 超出了它的取值范围,求30 0000 0000的反码

un = 3000000000 and not -1294967296

原码 :最高位符号位,0代表正数,1代表负数,非符号位为该数字绝对值的二进制。

反码:正数的反码与原码一致,负数的反码是对原码按位取反,只是最高位(符号位)不变。

补码:正数的补码与原码一致,负数的补码是该数的反码加1。

printf("end = %hd and %d\n", end, end);

%hd 指打印有符号short类型,%d 指打印有符号int类型,200没有超出它们的取值范围,所以输出结果:

end = 200 and 200
printf("big = %ld and not %hd\n", big, big);

%ld 指打印有符号long类型,long类型有32位,long big = 65537 没有超出其取值范围

%hd 指打印有符号short类型,只有16位,long big = 65537 为32位,此处将65537转为二进制1000 0000 0000 0000 1,取其后16位0000 0000 0000 0001,转换成十进制是+1,所以输出结果:

big = 65537 and not 1
printf("verybig = %lld and not %ld\n", verybig, verybig);

%lld 指打印有符号long long类型,有64位,long long verybig = 12345678908642 没有超出其取值范围

%ld 指打印有符号long类型,有32位,此处将12345678908642转换为二进制

1011 0011 1010 0111 0011 1100 1110 0100 1100 1110 0010,取后32位0111 0011 1100 1110 0100 1100 1110 0010,转换为十进制是1942899938

所以输出结果为:

verybig = 12345678908642 and not 1942899938