整型数据在内存中的存放形式
数据在内存中是以二进制形式存放的
而signed int 表示有符号基本整型
unsigned int 表示无符号基本整型
数值都是以补码形式表示的,一个正数的补码就是其本身,一个负数的补码就是对这个数按位取反然后加1
unsigned int 类型整数其值表示法
范围为::0~ 2^32 -1
unsigned char类型整数其值表示法
范围为::0~ 2^8-1
这两个好理解 int型的是32位从0开始所以是0~ 2^32 -1 char型的是8为即是0~255
而
signed int 类型整数其值表示法
范围为::-2^31 ~ 2^31 -1
signed char类型整数其值表示法
范围为::-2^7~ 2^7-1
这是一种补码规则
就char型的来说
正数部分 数值 在内存中的表现形式
0 00000000
1 00000001
2 00000010
...
127 011111111
再加个1 就成为了负数的--128
-128 10000000
-127 10000001
-126 10000010
...
-1 11111111
-1~-128 正好128个数 0~127也正好为128个数 加起来是256个数
有了补码就可以实现正常的相加减 如 1+(-128) = -127 用补码相加 00000001+10000000=10000001 而10000001就是-127 正好符合。
-0和+0的区别
零在计算机里就是0,不存在正负一说。
0和正数的补码都等于原码,也就是平时说的2进制数。
负数的补码是符号位置一的情况下,对原码求反,再加一得到的。
-0 就是对1 0000 0000 取反加1 得到结果还是00000000 即为+0;
举两例子下面是摘抄下来的
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
打印的结果是255
按照负数补码的规则,可以知道-1 的补码为0xff,-2 的补码为11111110……当i 的值为127
时,a[127]的值为-128,而-128 是char 类型数据能表示的最小的负数。当i 继续增加,a[128]
的值肯定不能是-129(1 0111 1111)。因为这时候发生了溢出,-129(1 0111 1111)需要9 位才能存储下来,而char 类型数据只有8 位,所以最高位被丢弃。剩下的8 位是原来9 位补码的低8 位的值,即0x7f。
当i 继续增加到255 的时候,-256 的补码的低8 位为0。然后当i 增加到256 时,-257 的补
码的低8 位全为1,即低八位的补码为0xff,如此又开始一轮新的循环……
按照上面的分析,a[0]到a[254]里面的值都不为0,而a[255]的值为0。strlen 函数是计
算字符串长度的,并不包含字符串最后的‘\0’。而判断一个字符串是否结束的标志就是看
是否遇到‘\0’。如果遇到‘\0’,则认为本字符串结束。
分析到这里,strlen(a)的值为255 应该完全能理解了。这个问题的关键就是要明白char
类型默认情况下是有符号的,其表示的值的范围为[-128,127],超出这个范围的值会产生溢
出。另外还要清楚的就是负数的补码怎么表示。弄明白了这两点,这个问题其实就很简单了。
在看一个
#include <stdio.h>
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b>6)? puts(">6"):puts("<=6");
}
int main()
{
foo();
return 0;
}
问输出什么?
打印出>6
问题很好解决b=-20 先要求它的的补码然后进行相加。