1.大小端问题
大端字节序的概念是,把一个数据低位字节处的数据放在高地址处,高位字节处的数据放在低地址处
小端字节序的概念是,把一个数据低位字节处的数据放在低地址处,高位字节处的数据放在高地址处
举个例子 123,1是高位 百位, 3 是低位 个位
设计一个小程序来判断当前机器的字节序
int main()
{
int i = 1;
//00000000000000000000000000000001
/*0x 00 00 00 01*/
//大段 00 00 00 01
//小段 01 00 00 00
char* p = (char*)&i; /*判断大小端取出第一位判断*/
if (*p == 1)
{
printf("小段");
}
else if (*p == 0)
{
printf("大段");
}
return 0;
}
在32位大端模式处理器上变量b等于( )
unsigned int a= 0x1234;
unsigned char b = *(unsigned char *)&a;
大端存储 00 00 12 34,在int中是这样存的,正着存是大端(高位在低地址,低位在高地址)
强制类型转化成char类型,只能访问一个字节,只能访问前面的00
结果就是0x00
2.整形在内存中的存储
下面是有符号char的范围和无符号char的范围,char是1个字节,8个比特位.
有符号char的范围是-128到127,无符号char的范围是0到255
这里有个题
int main()
{
char a[1000] = {0};
int i=0;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
这样的题画图做,有符号char的范围是 -128到127 , 127+1成了-128了
-1到-128之间有128个,1到127有127个,加一起是255,这是数组下标
3. int类型下无符号整形里面放负数的情况
int main()
{
unsigned int i = -10;
//10000000000000000000000000001010
//11111111111111111111111111110101
//11111111111111111111111111110110 补码
printf("%u\n", i);
//虽然无符号数里面可以放负数,但是打印出来的数不是负数
//这里打印无符号数,无符号数的原反补一样跟正数一样
//补码11111111111111111111111111110110 也是原码直接打印
//4, 294, 967, 286
}
int main()
{
unsigned int i = -10;
//10000000000000000000000000001010
//11111111111111111111111111110101
//11111111111111111111111111110110 补码
printf("%d\n", i);
//%u是打印无符号数,意思是你要我打印的一定是无符号数,不是无符号数,我也认为是无符号数
//‰d是打印有符号数,意思是你要我打印的一定是有符号数,不是有符号的数,我也认为是有符号数
//这个结果是-10,看成有符号数算,补码转化成原码再进行打印
}
4.char类型下%d的打印(要进行整形提升)
(%d打印的是一个有符号整数)
int main()
{
char a = -1;
signed char b = -1;
//10000000000000000000000000000001 原
//11111111111111111111111111111110 反
//11111111111111111111111111111111 补
//%d就意味着打印一个整形,而char类型不够一个整形,进行整形提升
//char类型8个比特位最多可以放11111111
//整形提升,补符号位,11111111.符号位是1,前面都补1
//
//11111111111111111111111111111111 补码 打印的是原码,再转换成原码
//10000000000000000000000000000000
//10000000000000000000000000000001 原
//结果是-1
//a和b结果一样,都是有符号数
unsigned char c = -1;
//char类型8个比特位最多可以放11111111,进行整形提升
//这里有个重点是无符号数整形提升的时候高位直接补0
//00000000000000000000000011111111
//因为是无符号数,无符号数的原反补码都一样,所以这就是原码。
//打印出来结果是255
printf("a=%d,b=%d,c=%d", a, b, c);
}
5. char类型下%u的打印
(%u是一个无符号整数的打印)
int main()
{
char a = -128;
//10000000000000000000000010000000 原
//11111111111111111111111101111111 反
//11111111111111111111111110000000 补
//char类型发生截断
//10000000
//%u打印无符号整数
//进行整形提升(这里看的是char a是有符号数,有符号数整形提升补符号位)
// (注意看的不是打印出来的%u,无符号整数就补0哦)
// 看类型是不是有符号数,是的话补符号位,10000000,这里1是符号位
//如果是无符号数的话,直接补0
//11111111111111111111111110000000 补码
//打印的是无符号数,原反补一样直接打印、
//结果是4,294,967,168
printf("%u\n", a);
return 0;
}
6.浮点型在内存中的存储
浮点型家族有浮点数家族包括: float、double、long double 类型。
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
M表示有效数字,大于等于1,小于2,写成科学计数法
2^E表示指数位。
e可以为负数,m要写成科学计数法,小数点向左做移动几个单位,乘以几次方,向右移动几个单位,乘以负几次方
看下面两个例子
以int存储,*pfloat打印时 。 先写出二进制,写出E M S然后还原回来。
(如果E里面都是0的话,用1-127,E里面不全为1或者0时,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。
(M还原的时候省了小数点前面的值1或0,只还原小数点后面的值)
(S就是符号位)
以*pfloat存储,int打印时,要转化成浮点型的存储
先写成二进制1001.0 ,然后利用公式进行转化,求出S M E,再求出二进制,求二进制的时候下面正好反过来
(E里面不全为1或者0时,即指数E的计算值加去127(或1023),得到真实值,再将有效数字M前减上第一位的1)
(M还原的时候省了小数点前面的值1或0,只还原小数点后面的值)
(S就是符号位)
130的二进制为10000010