1、数据的存储模式
面试题:设计程序判断大小端
这里可以有两种方式:
1、写一个函数通过数据类型
int main()
{
int a = 0x11223344;
char*p = &a;
printf("%x", *p);
}
2、通过联合体(联合体种的变量共用一块内存)
union Un
{
int a;
char ch;
}
int main()
{
union Un uu;
uu.a=0x11223344;
printf("%x",ch);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3cUoytPg-1570687707359)(en-resource://database/516:1)]
1、数据类型:对变量的划分
int main()
{
char a=-1;
unsigned char b=-1;
signed char c=-1;
printf("%d%d%d",a,b,c); //注意观察是以什么进制打印的
}
做法:
-
在32位下
-1的原码: 1000 0000 0000 0000 0000 0000 0000 0001
反码: 1111 1111 1111 1111 1111 1111 1111 1110
补码: 1111 1111 1111 1111 1111 1111 1111 1111
-
由于是char类型,且pc是小端并且存的是补码,只存了后八位1111 1111(ff)
-
打印的时候是%d以十进制并且是int型,故此时需要整型提升
-
关于a:char默认是有符号,%d是以4个字节打印,所以a整型提升为 1111 1111 1111 1111 1111 1111 1111 1111,因为是补码存储的,打印出来变原码,结果仍然是-1;
-
关于b: 无符号的char,每一位都是数值位,1111 1111(255),所以整型提升的时候直接前面补0就ok,结果是0000 0000 0000 0000 0000 0000 1111 1111,这个补码的最高位是0,是正数,因此它也是原码,就不用再转换了,直接输出255
-
关于c可以 参见a
2、几个重要的例子
int main()
{
unsigned int i=9;
for(i=9;i<=0;i--)
{
printf("%u",i);
}
return 0;
}
这里会死循环,i是一个无符号的数,当小于0的时候无符号打印,i的值又会变成这种类型的最大值,因此还会进入循环。
unsigned char i;
int main()
{
for(i=0;i<255;i++)
{
printf("hello word\n")
}
return 0;
}
int main()
{
char a[500];
int i;
for(i=0;i<500;i++)
{
a[i]=-1-i;
}
printf("%d",strlen(a));//这里注意strlen在遇到\0也就是0的时候停止
return 0;
}
可以看看这张图,在-128减一之后变成了127
2、浮点数在内存中的存储
754标准(只能精确保存6位,且是一个范围)
float类型 4个字节存储,遵循IEEE-754格式标准:一个浮点数有两部分组成:底数m和指数e
符号位(S):0、1
底数部分(M):使用二进制数来表示浮点数的实际值
指数部分(E): 占用8bit的二进制数,可表示数值范围为从-126到128
(因为指数可正可负,所以IEEE规定,此处算出的次方必须减去127才是真正的指数。)
科学计数法:
格式 :
SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
S表示浮点数正负,E指数加上127后的值得二进制数据,M为底数
eg: 17.725 在内存中得存储
首先要把17.625换算成二进制: 10001.101(注意整数部分和小数部分得转换规则)因为右移动了四位,这时候得底数和指数再将10001.101右移,直到小数点前只剩一位1.0001101*2^4
底数:因为小数点前必须为1,所以IEEE规定只记录小数点后得就好。所以此处得底数:0001101
指数:实际为4,必须加上127(转出得时候,减去127),所以为131,即 10000011,符号部分是整数,所以是0
综上,17.625存储格式为: 01000001 10001101 000000000 000000000
注意:
- 指数位是原来这个数再加上一个中间数127.
- 指数位全零,则这个数认为是正负零
- 指数位全1,则认为这个数是无穷大或者是无穷小。
这一篇后续还会完善。