通过索引访问结构

时间:2016-03-21 16:49:21

标签: c pointers indexing struct

我正在传递指向结构的指针,前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?
}

3 个答案:

答案 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]访问数组的第三个元素。如果成员的姓名不是onetwo等,您可以定义

enum Member_Names {
    FIRST_NAME = 0,
    SECOND_NAME = 1,
    ...,
    EIGTH_NAME = 7
};

然后使用ptr->members[THIRD_NAME]