1==》整形变量:
整型
有符号整型 无符号整型 数据长度
int unsigned [int] 32位
short[int] unsignedshort [int] 16位
long [int] unsignedlong [int] 32位
设整数在内存中用4个字节存储
10000001 10000001 10000001 1000 0001
00000001 10000001 10000001 1000 0001
如果是有符号数,则最高位是符号位,1表示负数,0表示正数。
数值的表示方法-原码 反码 补码
数值的表示方法-原码 反码 补码
正数的原码、反码和补码相同
1 的补码
0 000 0000 0000 0000 0000 0000 0000 0001
……
2147483647的补码
0 111 1111 1111 1111 1111 1111 1111 1111
负数的原码、反码和补码不同
-1
原码 1 000 0000 0000 0000 0000 0000 0000 0001
反码 1 111 1111 1111 1111 1111 1111 1111 1110 原码取反
补码 1 111 1111 1111 1111 1111 1111 1111 1111 反码+1
-32767
原码 1 000 0000 0000 0000 0111 1111 1111 1111
反码 1 111 1111 1111 1111 1000 0000 0000 0000 原码取反
补码 1 111 1111 1111 1111 1000 0000 0000 0001 反码+1
这些东西其实在哪里都能看到,但是整形存储还是有很多的猫腻的,做几个例题
2==》 小例题
1.
unsigned i;
for(i =9; i >=0; i--)
{
printf(“%u\n”,i);
for(i =9; i >=0; i--)
{
printf(“%u\n”,i);
}
这道题需要注意的是%u %u %u。重要的事情说三遍。
先看看运行的结果
答案很明显是一个死循环,那么这是为什么呢首先可以看到从9到0我们都可以理解。
现在到0了,0这里很关键,因为你是%u打印的,所以现在有32位0的二进制序列,
0000 0000 0000 0000 0000 0000 0000 0000
减去1,这时候的二进制序列为
1111 1111 1111 1111 1111 1111 1111 1111
如果是%d情况下这是补码,需要求出它的原码 求出来的时候刚好等于-1.
但是%u并不会买账,它有自己的打印方式,他不认识符号位,就照着全1的二进制序列输出,
所以值为4294967295,剩下的就以此类推,所以就变成死循环了。
2.
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
printf("%d",strlen(a));
return 0;
}
我们首先知道的是循环什么时候停止,strlen函数在什么时候回停止计数??答案是当a[i]=0的时候,char类型中0的值就是'\0'.现在我们明白了目的,开始计算。
然后开始循环,当i=127的时候知道a[i] = -128.这时候关键问题来了,我们知道char只有8个二进制编码识别,我们来算一算-128+(-1)的值
-128+(-1)
1000 0000
1111 1111
-----------------
1000 0000
1111 1111
-----------------
1 0111 1111
因为char只识别8位所以1被截掉而正数的原码反码补码相等,所以答案是127. 然后进行循环,当i=255的时候 a[i]=0; strlen函数识别位置结束,所以答案为255.
验证一下
short num =32767;
short int a = num +1;
short int a = num +1;
printf("%d\n",a);
首先应该知道short识别多少位,short识别16个二进制编码,然后
// 0111 1111 1111 1111 -> 1000 0000 0000 0000 (系统直接识别为最小值,不进行解码)
验证一下结果