整形在内存中的存储
1.计算机中有符号数表示方法:原码、反码、补码。三种表示方法均由符号位和数值位组成,用0表示“正”,1表示“负”。
原码:数据直接二进制转换得到
反码:原码符号位不变,其他位依次按位取反
补码:反码+1就是补码
注:正数的原码、反码、补码相同
对于整形来说:数据在内存中存放补码
int main()
{
int a=1;
int b=-1;
printf("%d\n",a-b);
return 0;
}
//1-1=1+(-1) (-1)的转换存储
// 1000 0001 原码
// 1111 1110 反码
// 1111 1111 补码
//+ 0000 0001
//1 0000 0000 只保存32位,丢掉最高位1
// 0000 0000
大小端
大端:低地址存放高数据; 小端:低地址存放低数据
大小端判断程序:
int Islittle()
{
int a=0x11223344;
char *pc=(char*)&a;
if(*pc==0x44)
{
return 0;
}
return 1;
}
union Un
{
int a;
char ch;
};//定义联合体
int Islittle1()//联合体:公用同一块内存,也叫共同体
{
union Un uu;
uu.a=0x11223344;
if(uu.ch==0x44)
{
return 0;
}
return 1;
}
int main()
{
int ret=Islittle();
if(ret==0)
{
printf("is little");
}
else
{
printf("is big");
}
return 0;
}
实例分析存储关系
//输出什么?
int main()
{
char a= -1;
//原码 10000000 00000000 00000000 00000001
//反码 11111111 11111111 11111111 11111110
//补码 11111111 11111111 11111111 11111111
//是char类型,只存储后8位 1111 1111
//打印时是%d,需要进行整形提升
//补码 11111111 11111111 11111111 11111111
signed char b=-1;
unsigned char c=-1;
//原码 10000000 00000000 00000000 00000001
//反码 11111111 11111111 11111111 11111110
//补码 11111111 11111111 11111111 11111111
//是char类型,只存储后8位 1111 1111
//打印时是%d,需要进行整形提升
//补码 00000000 00000000 00000000 11111111
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;
}
总结:%d %u(无符号整形)打印char数据
整形提升补0还是补1,取决于当前变量类型和最高位是0还是1;
提升之后是否求原码取决于是什么类型
浮点数在内存中的存储
浮点数包括:float、double、long double 类型
任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位
int main()
{
int n = 9;
//00000000 00000000 00000000 00001001
float *pFloat = (float *)&n;
printf("n的值为:%d\n",n);//9
printf("*pFloat的值为:%f\n",*pFloat);//0.000000
//%f以浮点数据类型去读数据
//0符号位00000000指数位00000000000000000001001尾数
//E全为0 这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,
//有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。
//这样做是为了表示±0,以及接近于0的很小的数字。
//E全为1
//这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)
*pFloat = 9.0;//将9.0以浮点型存入
//1.001*2^3
//0 10000010 00100000000000000000000
printf("num的值为:%d\n",n);//二进制转10进制 1091567616
printf("*pFloat的值为:%f\n",*pFloat);//9.0
return 0;
}