是否可以使用C中的指针数学访问结构中的数据?

时间:2018-04-06 16:42:35

标签: c pointers struct

是否可以使用指针数学来移动结构并将数据分配给其成员?我有一个只有uint8_t数据的大型结构,并且编写结构的所有这些成员的名称是很多工作。我希望我可以只指定一个指向第一个数据的指针,然后将8添加到该地址。这可能吗?

/* All pieces of data are the same size */
typdef struct 
{
    uint8_t a;
    uint8_t b;
    uint8_t c:
}Mydata;

int main(void){

    /* New struct created */
    Mydata NewData;
    /* Pointer P points to the address of "NewData"*/
    uin8_t *p = &NewData;

    *p = 5;
    p = p + 1; // increment 1 byte to next address where data is stored
    *p = 7;
    p = p + 1;
    *p = 10;

return 0;
}

2 个答案:

答案 0 :(得分:5)

指针数学以 字节 完成,而不是位 所以你建议添加8位,实际上你应该添加1字节

不保证结构布局是连续的。编译器可以选择在结构中间放置额外的空格,以帮助进行对齐和内存访问。即使您可能不知道,也可以:

typdef struct 
{
    uint8_t a;
    char    padding_A[3];
    uint8_t b;
    char    padding_B[3];
    uint8_t c:
}Mydata;

这会抛弃你的假设和数学 您通常可以使用特定于编译器的属性来解决此问题,例如#pragma pack__attribute__((__packed__))

最后,如果您使用过这种技术,很少有工程师能够轻松维护您的代码。如果结构的任何成员的类型已更改,如果添加或删除任何成员,则必须仔细更新之后的每个元素访问。错误的风险是巨大的。

有一个可用的公共宏,称为offsetof,它可以计算从结构开始的成员的字节偏移量。这可以避免我概述的许多问题,偶尔会用来编写高度专业化的代码。

如果 必须 执行此操作,请使用offsetof宏,但在此之前,请采取一切可能的预防措施,以避免首先需要此技术。

答案 1 :(得分:1)

虽然这几乎总是一个糟糕的决定,因为它会导致可移植性和代码可读性方面的错误,但是可以做到。

指针数学,在C中,基于指针的数据类型。编译器需要知道指针中每个元素的大小,以了解如何增加偏移量。

将指针声明为uint8_t *p,因为您正在迭代uint8_t。 然后,只要p++每次想要转到结构中的下一个成员(因为编译器知道指针的类型,它就知道" 1"单位等同于什么)。

我建议研究指针数学(一般指针,因为它们是C的主要部分),更重要的是,出于实用性原因,我建议强烈反对使用指针数学。

编辑:mispells