简体   繁体   English

您能否使用指向包含结构的指针来修改嵌套结构的值?

[英]Can you modify a nested struct's value using a pointer to the containing struct?

I've got a question regarding the behavior of structs in C. 我对C语言中的结构行为有疑问。

Take the given structs as an example: 以给定的结构为例:

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

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

I assume since structb contains a structa field, rather than a pointer to one, that structb would be laid out in memory as such: 我假设由于structb包含一个structa字段,而不是一个指向它的指针,因此structb将这样布置在内存中:

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

If so, can you access each field like this? 如果是这样,您可以像这样访问每个字段吗?

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

or access them like this? 或像这样访问他们?

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

Regardless of if that's bad practice or not. 不管这是否是错误的做法。

Also is it reliable/portable? 还可靠/便携吗?


Edit, as pointed out by Matt McNabb you can't directly cast structs so it should be: 编辑,正如Matt McNabb指出的那样,您不能直接转换结构,因此应为:

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

The *(char *) version is well-defined although you will need to check for padding after the end of innerstruct and before num3 . *(char *)版本定义明确,尽管您需要在num3结束之后和innerstruct之前检查填充。

(structa)structbvar is ill-formed. (structa)structbvar I think *(structa *)&structbvar would be OK, because of the rule about structs with common initial sequence (although I'll double-check that and update my answer). 我认为*(structa *)&structbvar可以,因为关于具有共同初始序列的结构的规则(尽管我会仔细检查并更新答案)。 However that is a bit pointless as you could just write structbvar.innerstruct . 但这有点没有意义,因为您可以编写structbvar.innerstruct

If you use pointer to force access a struct field, the reliability of your code depends on the alignment of your memory. 如果使用指针强制访问结构字段,则代码的可靠性取决于内存的对齐方式。 So it's not recommended, unless you force the memory to align as you expected. 因此,不建议您这样做,除非您强制内存按预期对齐。

Another way to access the field without calling the nested struct name, is using the Anonymous Struct with union. 访问该字段而不调用嵌套结构名称的另一种方法是使用带有Union的Anonymous Struct。 It's C99 Standard and of course portable and reliable, except your compiler doesn't support C99. 它是C99 Standard,并且当然可移植且可靠,除非您的编译器不支持C99。

You can define a union with Anonymous Strct like this: 您可以使用Anonymous Strct定义一个联合,如下所示:

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

Then access each field like this: 然后像这样访问每个字段:

test_t tTest;
tTest.wWord = 0x00FF0000;

Also: 也:

tTest.hwHigh = 0x00FF;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM