你可以使用指向包含结构的指针修改嵌套结构的值吗?

时间:2015-04-05 04:17:12

标签: c pointers struct portability c11

我对C中结构的行为有疑问。

以给定的结构为例:

typedef struct {
    char num1;
    char num2;
} structa;

typedef struct {
    structa innerstruct;
    char num3;
    char num4;
} structb;

我假设,因为structb包含一个structa字段,而不是指向一个字段的指针,所以structb将在内存中布局:

struct {
    char num1; //innerstruct num1
    char num2; //innerstruct num2
    char num3; //num3
    char num4; //num4
};

如果是这样,你可以像这样访问每个字段吗?

*(((char *)&structbvar) + 0) = 1; //innerstruct num1
*(((char *)&structbvar) + 1) = 2; //innerstruct num2
*(((char *)&structbvar) + 2) = 3; //num3
*(((char *)&structbvar) + 3) = 4; //num4

或像这样访问它们?

((structa)structbvar).num1 = 1; //innerstruct num1
((structa)structbvar).num2 = 2; //innerstruct num2

无论这是不好的做法。

它还可靠/便携吗?


编辑,正如Matt McNabb指出的那样,你不能直接施放结构,所以它应该是:

((structa *)&structbvar)->num1 = 1; //innerstruct num1
((structa *)&structbvar)->num2 = 2; //innerstruct num2

2 个答案:

答案 0 :(得分:2)

*(char *)版本定义明确,但您需要在innerstruct结束后num3之前检查填充。

(structa)structbvar格式不正确。我认为*(structa *)&structbvar会好的,因为关于具有共同初始序列的结构的规则(尽管我会仔细检查并更新我的答案)。然而,这有点无意义,因为你可以写structbvar.innerstruct

答案 1 :(得分:2)

如果使用指针强制访问struct字段,代码的可靠性取决于内存的对齐方式。所以不建议这样做,除非你强迫内存按预期对齐。

在不调用嵌套结构名称的情况下访问字段的另一种方法是使用带有union的Anonymous Struct。它是C99标准版,当然也是便携和可靠的,除了你的编译器不支持C99。

您可以使用Anonymous Strct定义一个联合:

typedef union {
    uint32_t wWord;
    struct {
        uint16_t hwLow;
        uint16_t hwHigh;
    };
} test_t;

然后像这样访问每个字段:

test_t tTest;
tTest.wWord = 0x00FF0000;

此外:

tTest.hwHigh = 0x00FF;