您可以使用指向包含结构的指针修改嵌套结构的值吗?
Can you modify a nested struct's value using a pointer to the containing struct?
我有一个关于 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
不管这是否是不好的做法。
也是reliable/portable吗?
编辑,正如 Matt McNabb 所指出的,您不能直接转换结构,所以它应该是:
((structa *)&structbvar)->num1 = 1; //innerstruct num1
((structa *)&structbvar)->num2 = 2; //innerstruct num2
*(char *)
版本定义明确,但您需要检查 innerstruct
结束后和 num3
.
之前的填充
(structa)structbvar
格式错误。我认为 *(structa *)&structbvar
可以,因为关于具有公共初始序列的结构的规则(尽管我会仔细检查并更新我的答案)。然而,这有点毫无意义,因为你可以只写 structbvar.innerstruct
.
如果您使用指针强制访问结构字段,则代码的可靠性取决于内存的对齐方式。所以不推荐,除非你强制内存按照你的预期对齐。
另一种无需调用嵌套结构名称即可访问字段的方法是使用带联合的匿名结构。它是 C99 标准,当然可移植且可靠,除非您的编译器不支持 C99。
您可以像这样使用匿名 Strct 定义联合:
typedef union {
uint32_t wWord;
struct {
uint16_t hwLow;
uint16_t hwHigh;
};
} test_t;
然后像这样访问每个字段:
test_t tTest;
tTest.wWord = 0x00FF0000;
还有:
tTest.hwHigh = 0x00FF;
我有一个关于 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
不管这是否是不好的做法。
也是reliable/portable吗?
编辑,正如 Matt McNabb 所指出的,您不能直接转换结构,所以它应该是:
((structa *)&structbvar)->num1 = 1; //innerstruct num1
((structa *)&structbvar)->num2 = 2; //innerstruct num2
*(char *)
版本定义明确,但您需要检查 innerstruct
结束后和 num3
.
(structa)structbvar
格式错误。我认为 *(structa *)&structbvar
可以,因为关于具有公共初始序列的结构的规则(尽管我会仔细检查并更新我的答案)。然而,这有点毫无意义,因为你可以只写 structbvar.innerstruct
.
如果您使用指针强制访问结构字段,则代码的可靠性取决于内存的对齐方式。所以不推荐,除非你强制内存按照你的预期对齐。
另一种无需调用嵌套结构名称即可访问字段的方法是使用带联合的匿名结构。它是 C99 标准,当然可移植且可靠,除非您的编译器不支持 C99。
您可以像这样使用匿名 Strct 定义联合:
typedef union {
uint32_t wWord;
struct {
uint16_t hwLow;
uint16_t hwHigh;
};
} test_t;
然后像这样访问每个字段:
test_t tTest;
tTest.wWord = 0x00FF0000;
还有:
tTest.hwHigh = 0x00FF;