当读取或写入缓冲区时,我认为通常需要访问大于缓冲区(指针)类型的数据。到目前为止,我已经提出了三种截然不同的方法,但我想知道是否有这种语言功能或公认的标准做法。选项c
提供了最大的灵活性,它可以处理结构和数组以及整数类型。
#include <stdio.h>
#include <stdint.h>
#define BUFFER_SIZE 10
#define ADDRESS 6
uint8_t buffer[BUFFER_SIZE] =
{
[ADDRESS] = 0x37,
[ADDRESS+1] = 0x42,
};
int main(void)
{
uint16_t a = buffer[ADDRESS] + (buffer[ADDRESS + 1]<<8);
uint16_t b = *(buffer + ADDRESS) + (*(buffer + ADDRESS + 1)<<8);
uint16_t c = *((uint16_t *) (buffer + ADDRESS));
printf("a: 0x%x\n", a);
printf("b: 0x%x\n", b);
printf("c: 0x%x\n", c);
return 0;
}
我不关心字节序,因为与缓冲区的所有交互都在单个嵌入式程序中;具有字节顺序安全性的外部接口是独立提供的。最感兴趣的标准是C99,但欢迎参考任何标准。
答案 0 :(得分:4)
前两个是等效的,此处buffer[ADDRESS]
与*(buffer + ADDRESS)
uint16_t a = buffer[ADDRESS] + (buffer[ADDRESS + 1]<<8);
uint16_t b = *(buffer + ADDRESS) + (*(buffer + ADDRESS + 1)<<8);
最后一个调用未定义的行为,因为它违反了C别名规则(C99, 6.5p7)并且可能会破坏对齐:
uint16_t c = *((uint16_t *) (buffer + ADDRESS));
总而言之,选择第一个,因为它更具可读性。
答案 1 :(得分:3)
a
和b
的代码是等效的,因为a[i]
是*(a + i)
的简写。
c
的代码调用未定义的行为,因为它可能使用非对齐访问。如果您知道您的机器处理未对齐的访问,并且拥有一个愉快的编译器,它可能会起作用。但不建议这样做,因为它可能会意外中断。
答案 2 :(得分:1)
无论数组缓冲区还是malloc
ed缓冲区,底层活动都是从一个位置到另一个位置的任意字节的任意复制。对此的标准方法是memcpy()
。
uint16_t d;
memcpy(&d, &buffer[ADDRESS], sizeof(d));
Ideone example已更新。