关于牛客网C语言结构体位域(bit-fields)的一道题

题目链接地址:

https://www.nowcoder.com/questionTerminal/f4e20747a2dd4649bac0c028daa234f4
来源:牛客网

低地址字节 Byte Byte
高地址字节 Byte Byte

x86是小段模式,LSB(最不关键的字节)存放在低地址,MSB(最关键的字节)存放在最高位。

大小端模式都是针对于字节而非位来说的,对于字节,顺序如平常书写顺序。

这种“:4”的写法,是结构体位域(bit-fields)语法。

题目中的a,b,c按照内存的地址自然的从低往高分配。

分配结果如下:

低地址字节 b3b2b1b0 a3a2a1a0
高地址字节 c6c5c4c3 c2c1c0b4

a=a3a2a1a0=2=(0010)2

b=b4b3b2b1b0 =3=(00011)2

c=0

低地址字节(LSB) 0011 0010
高地址字节(MSB) 0000 0000

因而最后这一段内存中的数据视作short的时候为0x(0032)=50.

 

另外,纠正一下其它题解的一些错误。

1. 大端小端是针对字节而非位。

2. 这道题和栈的内存分配是从高位到低位分配没有任何关系。

 

为什么说和栈的内存分配没关系。

因为首先test这个结构体是全局变量,占用的是堆空间而非栈空间。其次,即使test放在main函数内部声明,依旧和栈的内存分配没关系,因为test是一个struct mybitfields类型的结构体,栈分配内存地址的时候是作为一个整体,而test内部的内存布局依然是要遵循结构体成员变量的内存分布,和栈的内存分配没有关系。只有多个mybitfields结构体的时候才需要考虑这一点。

例如——

#include 
#include 
struct mybitfields {
  unsigned short a : 4;
  unsigned short b : 5;
  unsigned short c : 7;
};

int k, i; /*使用全局变量,占用堆空间,避免干扰下面的栈分配地址的输出分析。其实放进去也不是不能分析,主要是懒 */

int main(void) {
  struct mybitfields high, test, low;
  /* high,test,low在栈中占用的空间由高到低。但是它们内部的空间占用仍然符合结构体的位域的规则。*/
  test.a = 2;
  test.b = 3;
  test.c = 0;
  high.a = 4;
  high.b = 5;
  high.c = 0;
  low.a = 1;
  low.b = 2;
  low.c = 0;

  i = *((short *)&test);
  printf("short test: %08X\n", i);
  k = *((int *)&test);
  printf("int test: %08X\n", k);
  k = *((int *)&high);
  printf("int high: %08X\n", k);
  k = *((int *)&low);
  printf("int low: %08X\n", k);
}

输出如下

输出结果
short test: 00000032
int test: 00540032
int high: CCD00054
int low: 00320021

 

 

 

 

其中high由于在栈中的高地址(占据16位),更高的16位未知,所以输出的高16位是CCDD.

你可能感兴趣的:(小记,学习笔记,牛客网,C语言,计算机组成原理)