一、
题目:
请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。
思路:
数据是存储在内存当中,假设将1存储到内存之中,小端存储和大端存储区别就在于第一个字节内容是1/0;而我们知道指针类型的作用有解引用操作时访问几个字节,char类型的指针就访问一个字节。
指针类型的意义:
1、指针类型决定了指针解引用操作符能访问几个字节:char *p;*p 访问了一个字节,int *p; *p 就访问4个字节。
2、指针类型决定了指针+1,-1,加的或者减的是几个字节; char *p;p+1, 跳过一个字节,int *p;p+1;跳过一个整型4个字节
解答:
大端字节序:数据的低位存储在内存的高地址中,数据的高位存储在内存的低地址中。
小端字节序:数据的低位存储在内存的低地址中,数据的高位存储在内存的高地址中。
#include<stdio.h> int check_sys() { int a = 1; char* p = (char*)&a;//强制类型转换为char return *p; } int main() { int ret = check_sys(); if (ret == 1) { printf("小端\n"); } else { printf("大端\n"); } return 0; }
二、
题目:
以下代码输出结果是什么?
解析:
-1是整型,但要存储在char里面,所以肯定需要进行缩减,首先将-1的反码计算出来(因为在内存中存储的是补码形式),并且-1的补码全是1,需要牢记!缩减时根据最后结果需要的比特位数从低位开始选取。又因为输出结果是整型类型,所以又需要整型提升(有符号数按照符号位补全,无符号数直接补0),所以a,b都是有符号数,因此整型提升之后全是1,而输出结果使用的是原码,因此直接输出-1。而c无符号整型,整型提升后前缀是0,所以原码反码补码一致,按照整型提升后的结果直接翻译输出即可。
结论:
- char和signed char本质上是一样的,因此答案也相同。
- 无符号和有符号位的区别在于整型提升时,补位是0,还是按照符号位。并且无符号数的原码反码补码相同,不需要在考虑打印时转换,直接翻译补码即可,而有符号数在打印时需要考虑将补码转换为源码再进行打印
答案:
-1,-1,255
三、
题目:
解析:
本题前面思路与上一题一致,首先需要,缩减,然后根据数据类型进行整型提升。唯一区别在于本题输出结果是%u,因此是无符号整型,所以整型提升后的结果不需要再翻译成原码,因为无符号整型原码补码反码相同,直接补码即可!
小结论:
只要有%u或者unsigned char其中一个,就可以直接翻译,不需要考虑原码反码补码的转换。
总结:
原先数据类型决定整型提升时需要补位的数字,而输出结果如果是无符号整型,直接打印补码,不需要像有符号数那样还需要输出时将反码翻译成补码!
四、char类型表示数据范围
有符号的char范围:-128~127
无符号的char的范围:0~255
TIP:
128是存储不到char类型,但我们可以看成127+1就是-128,因此两者输出结果一样!
五、
题目:
请问以下代码输出结果?
int main() { unsigned char a=200; unsigned char b=100; unsigned char c=0; c=a+b; printf("%d %d",a+b,c); return 0; }
解析:
先将200转换为补码形式:00000000000000000000000011001000,因为将200存储在char类型的变量,所以需要截断,只留下一个字节,即8个比特位:11001000
100同理,最后存储在b里面的形式是:01100100
当进行加法运算时,需要整型提升(这是规则,防止最后结果溢出)!
所以最后结果就是:00000000000000000000000000100101100
注意最后输出结果的区别一个是直接a+b的形式,而另一个先把内容存储在一个char类型里面,因此需要截断,所以最本质的区别在于一个需要截断,而另一个不需要截断。而刚才的结果恰好经过截断(只保留最后8个比特位)把1给去掉了,造成两者差别的根源!
TIP:
也可以根据无符号char类型的区间范围是0~255,可以看出最后的相加结果肯定是超出范围的!
六、
题目:在32位大端模式处理器上变量b等于?
int main() { unsigned int a=0x1234; unsigned char b=*(unsigned char*)&a; return 0; }
解答:
注意一个完整的整型十六进制表达有8个十六进制位,所以应该先把a的形式补充完整。
就是0x 00 00 12 34 (两个十六进制位就表示一个字节,因此就是4个字节一个整型)。
题目又说大端处理器,所以数据的低位存储在内存的高地址中,数据的高位存储在内存的低地址中
又因为强制类型转换为unsigned char*类型,所以我们在访问时只访问一个字节,注意都是从内存的低地址开始访问(所以把00取走),结果就是0.