简体   繁体   中英

Is it possible to access data in a struct using pointer math in C?

Is it possible to use pointer math to move through a struct and assign data to its members? I have a large struct with exclusively uint8_t data and writing the names of all these members of the struct is a lot of work. I was hoping I could just assign a pointer to the first data and then add 8 to the address. Is this possible?

/* 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;
}

Pointer math is done in bytes , not bits.
So where you suggested adding by 8-bits, you should actually be adding 1-byte

Structure layout is not guaranteed to be contiguous. The compiler may choose to put additional blank spaces in the middle of structures that help with alignment and memory access. Even though you may not know it, it is possible to have:

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

This will throw off your assumptions and math.
You can often get around this with compiler-specific attributes such as #pragma pack or __attribute__((__packed__))

Finally, if you ever used this technique, very few engineers would be comfortable maintaining your code. If any member of the structure ever has its type changed, if any member is added or removed, then every single element-access after that has to be carefully updated. The risk of a bug is enormous.

There is a common macro available, called offsetof that can calculate the byte offset of members from the start of the structure. This can avoid many of the problems I outlined, and is occasionally used to write highly specialized code.

If you must do this, use the offsetof macro, but before that, take every possible precaution to avoid needing this technique in the first place.

Although it is almost always a bad decision, since it leads to faults in portability, and in code readability, it can be done.

Pointer math, in C, is based on the datatype of the pointer. The compiler needs to know the size of each element in your pointer to know how to increment the offset.

Declare your pointer as uint8_t *p since your are iterating over uint8_t . Then, just p++ everytime you want to go to the next member in your struct (since the compiler knows the type of your pointer, it know what "1" unit is equivalent to).

I would recommend studying up on pointer math (and pointers in general since they are a major part of C) and, more importantly, I would advise strongly against using pointer math for practicality reasons.

Edit: mispells

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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