软考中级-嵌入式系统工程师-错题解析1
错题:
1、某处理器按照大端方式工作,以下C语言代码执行后的输出是______。
char iArr[10]={0,1,2,3,4,5,6,7,8,9};
short tVal;
short *pVal=NULL;
pVal=(short*)(iArr+2);
tVal=*pVal;
printf("tVal=%#x\n", tVal);
A.tVal=0x203
B.tVal=0x302
C.tVal=515
D.tVal=770
答案:A。
解析:
1.首先要知道char类型和short类型的字节数:
Char 用于C或C++中定义字符型变量,只占一个字节,
short 标准定义短整型变量不得低于16位,即两个字节。
2.pVal=(short*)(iArr+2); 这一句好理解。
pVal指向iArr数组中的第三个存储元,即数值【2】的存储地址。
3.然后我们来理解 tVal=*pVal; 这句。
pVal存储的是地址,*pVal就是存储在这个地址上的值。那为啥这个值不是2呢?这就是上面提到的数据类型在作怪了,如果tVal也是char类型,那么输出就是0x2。如下图运算结果:
但是现在是short类型,所以要补齐16位,那个【2】的地址里面只存了8位即0000 0010(0x02),所以要继续读取后面地址上的数据,即读取【3】(0x03)。知道这些后,是不是下意识的就觉得0x02应该在0x03前面,所以输出应该是0x0203,这里其实是歪打正着。
其实题干中有说大端工作模式,刚好是这么排序。
4.那么简单介绍一下大小端模式:
所谓的大端模式,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
所谓的小端模式,是指数据的低位保存在内存的低地址中,而数 据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
①Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
②Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
举一个例子,比如数字0x12 34 56 78在内存中的表示形式为:
低地址 -----------------> 高地址
大端模式: 0x12 | 0x34 | 0x56 | 0x78
小端模式: 0x78 | 0x56 | 0x34 | 0x12
可见,大端模式和字符串的存储模式类似。
小结一下:
在iArr这个数组中0x02相对于0x03是高位字节,0x03相对于0x02是低位字节,所以在大端模式下0x02存放在低位地址,0x03存放在高位地址,组合一下就是0x0203了,此时tVal=0x0203
5.最后就是printf(“tVal=%#x\n”, tVal); 这个打印就比较好理解了。
重点解释一下%#x的意识:c语言中的%#x意思是带格式0x的16进制输出(最前面一位是0打印时不用补)
6.所以最后输出结果为:tVal=0x203
参考:
1.https://blog.csdn.net/jeffade/article/details/7958014
2.https://blog.csdn.net/sunshaodong_1988/article/details/9766731#comments
3.https://zhidao.baidu.com/question/1667964228570821347.html