[cpp]
#include<stdio.h>
int main(void)
{
int i = 2147483647;
unsigned int j = 4294967295;
printf("%d*%d**%d\n",i,i+1,i+2);
printf("%u*%u**%u\n",i,i+1,i+2);
printf("%d*%d**%d\n",j,j+1,j+2);
printf("%u*%u**%u\n",j,j+1,j+2);
getchar();
return 0;
}
运行结果如下
2147483647*-2147483648**-2147483647
2147483647*2147483648**2147483649
-1*0**1
4294967295*0**1
知识点讲解如下:
当一个整数超过他所能表示的最大值以后,就会循环回去继续从开头开始,就像是一个环一样。所以,对于第一个printf和第四个printf不用讲解了吧。
那么对于第二个和第三个printf语句呢?没错,还是涉及到数据的存储管理。可以看我的上一篇帖子,当然有兴趣的可以这么理解。如下
对于第二个,我没什么说的,很明显,u的正数范围比较大,所以,i会一直加一。
对于第三个,因为超出范围了,所以变为-1。至于为什么变为-1,也很简单,
为了帮助大家理解,先举个相同范围输出,正常的例子,比如说范围是0-9,那么我现在数字是10,那么循环一圈过去,相当于是0。实际上,同样的,对于不同的数据类型的输出,也是遵循这种规律的。
针对上面的输出的第三个为什么是-1呢,那你也可以这么想,实际上是4294967295,计算机编译的时候,发现不是%d类型,比较大,那么就循环几圈吧,先循环一圈吧(这里所说的全就是指的是数据可表示的长度范围,对于4294967295,一圈就是4294967296),减小到-1,发现-1在%d的范围内,所以就是-1了,除以的得到的余数,不同意的可以自己去验证,本人已经验证过了。
总之一句话,如果编译运行没错误,那么你就需要按照计算机的思想去理解,他不会出错,因为他也只是程序而已,既然可以运行,那么就肯定有可以运行的规则。上面我说的就是一个规则,当然只是理解而已,实际上,计算机只是取位不同,%d取得是低位16个1(注意,我机子32位系统,int型占32个字节),然后低位中的最高一位0代表正,1代表-,然后计算机内部计算,取得都是补码-1,所以值变成-1喽。(注意,一个是无符号,一个是有符号,补码值按照不同的公式算)(注意,跟我刚才说的,减一圈,实际上减的就是高位的数据,一直到减为0,实际上计算机根本没有减为0,直接就舍去了,但是我们可以这样理解,比较方便)有兴趣的可以看上篇帖子,比较详细。还有这篇帖子http://bbs.csdn.net/topics/340253678还有这篇帖子http://blog.csdn.net/wang6279026/article/details/8114805大部分都是这样的,都看一遍估计就明白了。
再举个例子:
printf函数不管你的变量类型,只管按照格式符的含义来解释数据
例如:
int i=-1;
printf("%u\n",i);
32位平台会输出4294967295,因为-1的 源码是32个1(在32平台上)
16位的输出65535
个人理解,欢迎大家批评指正。可能有些地方转不过去,欢迎交流。
2.格式化输出
[cpp]
#include<stdio.h>
int main(void)
{
unsigned int un = 3000000000;
short end = 200;
long big = 65537;
long long verybig = 12345678908642;
printf("%u,%d\n",un,un);
printf("%hd,%d\n",end,end);
printf("%ld,%hd\n",big,big);
printf("%lld,%ld\n",verybig,verybig);
getchar();
return 0;
}
这个程序也可以按照我的自创的那种方法理解。注意:h代表short(16位),l代表long
输出结果是:
3000000000,-1294967296
200,200
65537,1
12345678908642,1942899938
3.显示八进制和十六进制
[cpp]
#include<stdio.h>
int main(void)
{
int x = 100;
printf("%d*%o**%x\n",x,x,x);
printf("%d*%#o**%#x\n",x,x,x);
getchar();
return 0;
}
输出结果:
100*144**64
100*0144**0x64
4.好了,那我总结一下精髓吧
无符号与有符号数据都是循环的,但是如果两个类型不匹配输出,实际上是没有问题的,因为,一个计算机内部的二进制数,既可以是有符号数,也可以是无符号数,仅此而已。这才是真正的核心。
最后举个小例子:假设平台是8位的,11111111的无符号数是127,有符号数是-1.他们在计算机内部的二进制是一样的。
|