从另一个结构改变结构的价值

时间:2014-03-06 13:04:25

标签: c struct

我刚刚阅读Extending a struct in C,我似乎不明白代码的某些部分是做什么的。
这是他目前的代码:

typedef struct A {
  int x;
}A;

typedef struct B {
  A a;
  int d;
}B;

void fn(){
  B *b;
  ((A*)b)->x = 10;
}

我想知道,((A*)b)->x = 10;b->a.x = 10;如何相同?

你如何解释这行代码?

修改

(A*)(A*)b做了什么?

3 个答案:

答案 0 :(得分:3)

根据标准,指向结构的指针必须等于指向该结构的初始成员的指针。换句话说,在其专用于存储struct B内容的区域前面的struct A中不得插入填充。这就是演员阵容有效的原因:

Layout of struct B

  

第6.7.2.1.13节

     

在结构对象中,非位字段成员和位域所在的单元具有按声明顺序增加的地址。指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。结构对象中可能有未命名的填充,但不是在其开头

答案 1 :(得分:2)

尝试可视化struct B如何存储在内存中,您将理解为什么它们是平等的。

内存中的

struct B放置为a,结构A后面跟着成员d

现在,当您查看((A*)b)时,它是str B转换为struct A,其内存中的成员x为零偏移。

下面是典型内存布局中的struct B

+--------------+
|      |       |
|  A   |   d   | 
|      |       |
+--------------+

现在如果你再扩展一下,

+--------------+
|      |       |
|  x   |   d   | 
|      |       |
+--------------+

答案 2 :(得分:2)

如果检查结构A的内存布局,它看起来像这样

+---+
| x |
+---+

如果你将它与B的内存布局进行比较,它看起来像这样:

+---+---+
| x | d |
+---+---+

当你看到它时,更容易看出它为什么会起作用。