有一种“好的”方法可以将一个结构的指针推进一个字节吗?

时间:2017-07-05 07:43:42

标签: c lvalue pointer-arithmetic

我有一个指向我希望移动的结构的指针 地址范围,逐字节。我有一种方法可行,但是 它在我眼里难看。不幸的是,“好”的方式不起作用。这是一个最低限度的例子:

#include <stdint.h>

typedef struct {
    uint32_t a;
    uint32_t b;
} s_t;

int main( int argc, char** argv )
{
    uint32_t address = 17;
    s_t* ps = (s_t*) address;

    // ugly
    uint8_t* gna = (uint8_t*) ps;
    ++gna;
    ps = (s_t*) gna;

    // nice
    ++((uint8_t*) ps);
}

编译器在“nice”部分报告错误:

% gcc test.c -o test.bin
test.c: In function 'main':
test.c:17:5: error: lvalue required as increment operand
     ++((uint8_t*) ps);
     ^

我理解错误,但我想要转换为uint8_t *会 创造一个左值。显然,我错了。

有没有办法让它变得更好?

5 个答案:

答案 0 :(得分:5)

这没有多大意义。如果要将结构指针增加1个字节,则最终会出现未对齐的地址,这在大多数系统上都会出现问题。我将不得不假设您的系统任何主流的32/64位CPU(不是x86,ARM,PowerPC等),否则您的问题毫无意义。

要将地址增加一个字节,只需执行以下操作:

ps = (s_t*) ((uintptr_t)ps + 1);

答案 1 :(得分:1)

因为解决方案可以定义指向结构的char*指针。然后通过添加此指针,您可以访问指向结构的字节。

 s_t a;
 unsigned char *b = (unsigned char*)&a;
 unsigned char next_byte = *(++b);

然后通过添加b,您可以获得a的字节。此解决方案的不足是您可能会在某些编译器中收到错误或警告,以通过char指针将指针传递给struct。

答案 2 :(得分:0)

怎么样:

ps = (s_t*) (1 + (uint8_t*) ps);

答案 3 :(得分:0)

关于发布的代码:

self

答案 4 :(得分:-2)

显然,(uint8_t*)之类的类型转换不会产生左值。由于您的代码是使用C ++编写的,因此您可以使用此转换(uint8_t*&)