将unsigned char数组的元素作为整数访问

时间:2012-05-17 17:53:03

标签: c++

我必须使用只接受*unsigned char作为输入的阅读功能

typedef unsigned char byte;
byte * rx_data;
rx_data = new byte [RX_PACKET_LEN*packets];

如何以简单的方式读取rx_data作为整数数组(4字节)?

5 个答案:

答案 0 :(得分:2)

你可以施展它:

int* pInt = reinterpret_cast<int*>( rx_data);

int* pInt = (int*) rx_data;

或者如果您想保留名称,请在需要阅读时将其强制转换:

((int*)rx_data)[0];

请注意,如果您完全确定自己在做什么,则应该这样做,否则就不安全了。 (嗯,这个ca适用于任何地方,我知道,但这需要特别注意)。想到的事情 - RX_PACKET_LEN*packets应该是sizeof(int)的倍数。

答案 1 :(得分:1)

由于这是C ++,您应该使用reinterpret_cast将unsigned char指针强制转换为int指针:

int * data = reinterpret_cast<int*>(rx_data);

但是,这假定数据以特定的endian格式存储,因此如果chars数组来自具有不同字节序的不同平台,则此代码将不起作用。如果你采用相同的平台,那么你可能会没事的。

答案 2 :(得分:1)

一般情况下唯一安全的方法是制作副本:

std::vector<int32_t> target(RX_PACKET_LET * packets / sizeof(int32_t));

std::copy(rx_data, rx_data + RX_PACKET_LET * packets,
          reinterpret_cast<unsigned char *>(target.data()));

现在,您可以阅读target[0]target[1],...作为整数。

答案 3 :(得分:1)

您可以使用memcpy。

byte *rx_data = ...
size_t rx_data_size = ...

std::array<int, rx_data_size/sizeof(int)> data;

std::memcpy(data.get(), rx_data, data.size() * sizeof(int));

// read and modify data

// if you need to write it back out to rx_data then copy data back when you're done

std::memcpy(rx_data, data.get(), data.size() * sizeof(int));

这样做的一个优点是它不涉及转换,处理未对齐的内存,并且不依赖于神秘的别名规则。

一个缺点可能是复制数据可能导致性能降低。但是这不能保证。现代编译器通常将memcpy实现为编译器内在函数,优化器可以推断其行为。

我刚试了LLVM,发现了这些:

void increment(char *buf) {
    int i;
    memcpy(&i,buf,sizeof(int));
    ++i;
    memcpy(buf,&i,sizeof(int));
}

void increment(int &i) {
    ++i;
}

产生几乎相同的IR表示(clang tmp.cpp -emit-llvm -o - | opt -S -O2)和完全相同的x86_64汇编。

答案 4 :(得分:0)

当您将指针类型从byte *更改为int *时,当您递增指针(p ++)时,您将自动读取4个字节或跳转4个字节。 只需确保字节数组大小为模块4,这样就不会出现分段错误。