我正在传递指向结构的指针,前8个成员大小相同,我可以通过索引访问它们吗?
typedef struct example{
uint64_t one;
uint64_t two;
uint64_t three;
uint64_t four;
uint64_t five;
//etc...
uint8_t ninth;
} example_t;
void example_method(example_t *ptr)
{
//can I do this?
&ptr[2] // which would be equal to the uint64_t third?
}
答案 0 :(得分:3)
您无法通过索引可靠地获取struct成员的原因是struct可能在成员之间以及最后一个成员之后包含任意 padding 。根据C11,N1570§6.7.2.1/ p15 结构和联合说明符:
结构对象中可能有未命名的填充,但不在其中 开始。
您可以做的是重新定义您的结构以包含数组成员(或可能flexible array member)。
答案 1 :(得分:1)
代码看起来的方式现在你不能,但如果你以不同的方式构建东西,你可以逃脱:
typedef union example
{
struct {
uint64_t one;
uint64_t two;
uint64_t three;
uint64_t four;
uint64_t five;
//etc...
uint8_t ninth;
};
uint64_t array[9];
}example_t;
现在你可以这样做:
void example_method(example_t *ptr)
{
ptr->array[2]; // access fields by index
}
但是,请注意:由于编译器对齐默认值,您可能会遇到麻烦 - 例如,假设您再添加一个字段,即 char ,编译器可能会尝试对齐它4个字节(有些具有此默认值)会使事情变得混乱,特别是如果字段位于结构中间的某个位置。
答案 2 :(得分:0)
ptr[2]
等同于*(ptr+2)
首先将sizeof(struct example)
添加到地址ptr
,然后解除引用。
当然,你可以在struct中有一个数组,而不是八个成员:
struct example {
uint64_t members[8];
uint8_t ninth;
};
在这种情况下,您可以使用ptr->members[2]
访问数组的第三个元素。如果成员的姓名不是one
,two
等,您可以定义
enum Member_Names {
FIRST_NAME = 0,
SECOND_NAME = 1,
...,
EIGTH_NAME = 7
};
然后使用ptr->members[THIRD_NAME]
。