深度剖析数据在内存中的存储练习
1. 整型提升:有符号/无符号
int main()
{
char a= -1;
//10000000 00000000 00000000 00000001 - 原码
//11111111 11111111 11111111 11111110 - 反码
//11111111 11111111 11111111 11111111 - 补码
//-1截断后存在a中11111111
signed char b=-1;
//11111111 - b
unsigned char c=-1;
//11111111 - c
printf("a=%d,b=%d,c=%d",a,b,c);
//-1 -1 255
//-1 -1
//11111111 11111111 11111111 11111111 - 补码
//11111111 11111111 11111111 11111110 - 补码-1
//10000000 00000000 00000000 00000001 - 补码-1后取反
//255
//11111111
//00000000 00000000 00000000 11111111 - 无符号整型提升
//正数原、反、补相同
return 0;
}
有符号提升:高位补1;无符号提升:高位补0。
1.1 有符号和无符号数的取值范围如何定?
推而广之:
signed short : -32768 ~ 32767
unsigned short: 0 ~ 65535
//00000000 00000000 0
...
//01111111 11111111 32767
//10000000 00000000 -32768
...
//11111111 111111111 -1
2. %u 的打印
int main()
{
char a = -128;
//10000000 00000000 00000000 10000000
//11111111 11111111 11111111 01111111
//11111111 11111111 11111111 10000000
//10000000 - a
//11111111 11111111 11111111 10000000
printf("%u\n",a);
//%u 打印无符号整型,认为内存中存放的补码对应的是一个无符号的数
//%d 打印有符号整型,认为内存中存放的补码对应的是一个有符号的数
return 0;
}
若改为128 :unsigned char 存不下。
3. 不同类型相加
按照补码的形式进行运算,最后格式化成为有符号整数。
int main()
{
int i = -20;
//10000000000000000000000000010100
//11111111111111111111111111101011
//11111111111111111111111111101100
unsigned int j = 10;
//00000000000000000000000000001010
printf("%d\n", i + j);
//11111111111111111111111111101100
//00000000000000000000000000001010
//11111111111111111111111111110110 -> 相加
//11111111111111111111111111110101 -> 相加后-1
//10000000000000000000000000001010 ---> -10
return 0;
}
4. for循环判断条件
unsigned int i;
//i为无符号整数,i>=0恒成立
for(i = 9; i >= 0; i--)
{
printf("%u\n",i);
}//进入死循环
5. 数组元素限定
int main()
{
//char变量的取值范围:-128~127
char a[1000];
//-1 -2 -3...-128 127 126...5 4 3 2 1 0 -1 -2...
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));//255
//strlen找ASIIC码为0的就停止:128+127=255
return 0;
}
6. 无符号变量造成死循环
#include <stdio.h>
unsigned char i = 0;//全局变量
//unsigned char取值范围:0~255
int main()
{
for(i = 0;i<=255;i++)
//i<=255恒成立
{
printf("hello wolf!\n");
}
return 0;
}