整数溢出
如果整数太大,超出了整数类型的范围会怎么样?下面分别将有符号类型和无符号类型整数设置为最大允许值加略大一些的值,看看结果是什么(printf()函数使用%u说明符显示unsigned int类型的值)
1 #include <stdio.h> 2 int main() 3 { 4 int i = 2147483647; 5 unsigned int j = 4294967295; 6 7 printf("%d %d %d \n", i, i+1, i+2); 8 printf("%u %u %u \n", j, j+1, j+2); 9 while(1); 10 return 0; 11 }
解释:无符号整型j像一个汽车里程指示表,当达到最大值时,她将溢出到起始点。整数i也是同样原理。它们的主要区别是unsigned int变量j的起点是0,而int类型的起始点是-2147483648.注意到当i超过(溢出)它的最大值时,系统并没有给出提示,所以编程时您必须自己处理这个问题。
1 #include <stdio.h> 2 int main(void) 3 { 4 unsigned int un = 3000000000; 5 short end = 200; 6 long big=65537; 7 long long verybig = 12345678909642; 8 9 printf("un = %u and not %d\n", un, un); 10 printf("end=%hd and %d\n", end, end); 11 printf("big=%ld and not %hd\n",big, big); 12 printf("verybig=%lld and not %ld\n", verybig, verybig); 13 14 return 0; 15 } 16 ~
输出:
un = 3000000000 and not -1294967296
end=200 and 200
big=65537 and not 1
verybig=12345678909642 and not 12345678909642
这个例子表明如果使用了不正确的说明符,会造成意想不到的后果。首先,对无符号变量un使用%d说明符导致显示负值!这是由于在程序运行的系统中,无符号数3000000000和有符号数-129496296在内存中的表示方法是一样(这里可以假设它们在内存中 被表示为A)。所以告诉printf()该数值是无符号的,A将打印成某个值;而如果告诉printf()函数该数值是有符号的,A又将打印另外一个值。
另:使用printf()语句时,切记每个要显示的值都必须对应自己的格式说明符,并且 显示值的类型 要和 说明符 匹配