目录
前言
数据在内存中以2进制的形式存储。
对整数来说,整数二进制有3种表示:原码、反码、补码。
正整数,原码、反码、补码相同;负整数,原码九四数据的二进制序列,反码是在原码符号位不变的情况下,其他位按位取反而得,补码是反码加一得到的。整数在内存中存的是整数的补码。
练习典例
练习1:
#include <stdio.h>
int main()
{
char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;
}
这个代码运行的结果是,a= -1, b = -1, c = 255。为什么呢?
a, b, c在内存中的补码都为11111111,但是a是 char,b是signed char,所以a, b最高位为符号位,整型提升后a, b的补码为11111111111111111111111111111111,也就是-1,而c的整型提升后为00000000000000000000000011111111也就是255。
练习2:
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n",a);
return 0;
}
a在内存中反码为10000000,而最后打印的是%u也就是无符号整型,要进行整型提升,按符号位补高位也就是11111111111111111111111110000000,也就是4294967168。
练习3:
#include <stdio.h>
int main()
{
char a = 128;
printf("%u\n",a);
return 0;
}
a在内存中的补码为10000000,在整型提升时,按最高位也就是符号位补高位,也就是11111111111111111111111110000000,与上一题结果相同。
练习4:
int i= -20;
unsigned int j = 10;
printf("%d\n", i+j);
i 原码 10000000000000000000000000010100
i 反码 111111111111111111111111111111101011
i 补码 111111111111111111111111111111101100
j 原码 反码 补码 00000000000000000000000000001010
i+j=00000000000000000000000000010110也就是-10的反码。
要注意整型默认是有符号的整型。
练习5:
unsigned int i;
for(i = 9; i >= 0; i--)
{
printf("%u\n",i);
}
没想到吧,这个代码死循环了。那为什么?
因为i是unsigned int,也就是正整数,所以i永远不可能小于0,条件恒成立,因此就死循环了。
练习6:
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
结果是255,为什么不是1000呢?
因为char类型在内存中占用1个字节,char能存储的数字范围是-128-127。但是i是从0开始的,那就是意味着i只能取0-127???是这样的吗?127是01111111,+1就是10000000,因为符号位是1,那么系统自动读取为-128,那么-128到-1都能取到了,所以从-128到127都能取到,也就是255字符。
练习7:
#include <stdio.h>
unsigned char i = 0;
int main()
{
for(i = 0;i<=255;i++)
{
printf("hello world\n");
}
return 0;
}
结果又死循环了,因为char类型取不到256,所以条件恒成立,会一直打印"hello world"。
结束语
初阶学完了,加油,加油,一切都值得。