C,创建一个指向8位数组的32位指针

时间:2016-05-31 14:06:34

标签: c arrays pointers

我有一个缓冲区,缓冲区中的每个条目大小为8位:

uint8_t Buffer[10] = {0x12,0x34,0x56,0x78,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6};

我需要做的是创建指向该数组的指针,例如16位和32位指针。例如:

uint32_t *x;
x = Buffer;

uint32_t *y;
y = Buffer+4;

uint16_t *z;
z = Buffer+8;

然后,每个变量将从数组中读取,例如:

x = 0x78563412
y = 0xf4f3f2f1
z = 0xf6f5

这完全正常,问题是我收到有关不兼容指针类型的警告。所以我想知道是否有另一种方法可以做到这一点,或者我是否只需要接受警告?或者我只是完全以错误的方式做这件事?

请注意,此代码将在单一类型的平台上执行,其中字节顺序始终相同且数据类型的大小始终相同。

3 个答案:

答案 0 :(得分:6)

你应该留意警告;你正在做的是未定义的行为。像这样的类型别名是未定义的行为,特别是因为无法保证Buffer具有正确的对齐方式,因此可以将其作为int / short进行访问。如果Buffer具有正确的对齐方式,那么您可以明确地投射并且它没问题(并且警告将消失)。

您有两种选择:

首先,将缓冲区对齐为两种类型中较大的一种。请注意,指针算术不会抛弃对齐:

#include <stdalign.h>

alignas(int) unsigned char Buffer[10] = {0x12,0x34,0x56,0x78,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6};

unsigned int *x;
x = (unsigned int*)(Buffer);

unsigned int *y;
y = (unsigned int*)(Buffer+4);

unsigned short *z;
z = (unsigned short*)(Buffer+8);

两,你创建一个unsigned int / unsigned short变量,然后memcpy你感兴趣的字节到变量中:

unsigned int x;
memcpy(&x, Buffer, 4);

unsigned int y;
memcpy(&y, Buffer + 4, 4);

unsigned short z;
memcpy(&z, Buffer + 8, 2);

答案 1 :(得分:2)

您的方法的问题在于它假定底层硬件的特定字节序。不同的计算机将解释十六进制字节序列

01 23 45 67

as eiter

01234567 or 67452301

您的程序可以在两个系统上编译和运行,但由于结果是特定于硬件的,编译器必须警告您这种可能性。

强制使用特定字节序的正确方法是使用整数数组,使用hton和ntoh函数转换它们,并通过将指针转换为unsigned char *或使用memcpy直接设置单个字节。

答案 2 :(得分:2)

您可能想要使用联合

#include <stdint.h>
#include <stdio.h>

typedef union{

    uint8_t Buffer[10];
    struct{
        uint32_t x;
        uint32_t y;
        uint16_t z;
    };

}MYSTRUCT;


int main(){

    MYSTRUCT b = {0x12,0x34,0x56,0x78,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6};

    printf("x=%#x y=%#x z=%#x\n",b.x,b.y,b.z);

 return 0;

}