在C中将字节数组转换为int数组

时间:2012-11-01 11:35:36

标签: c arrays type-conversion arduino

下面我有一些代码应该将C(Arduino)8位字节数组转换为16位int数组,但它似乎只能部分工作。我不确定我做错了什么。

字节数组采用小端字节顺序。如何将其转换为int(每个enty两个字节)数组?

用外行人的话说,我想合并每两个字节。

目前正在输出输入BYTE ARRAY:{0x10, 0x00, 0x00, 0x00, 0x30, 0x00}。输出INT ARRAY是:{1,0,0}。输出应该是INT ARRAY:{1,0,3}

以下代码是我目前的代码:

我根据a solution in Stack Overflow question Convert bytes in a C array as longs编写了这个函数。

我也有这个基于相同代码的解决方案,它适用于字节数组到长(32位)数组http://pastebin.com/TQzyTU2j

/**
* Convert the retrieved bytes into a set of 16 bit ints
**/
int * byteA2IntA(byte * byte_slice, int sizeOfB, int * ret_array){

    //Variable that stores the addressed int to be stored in SRAM
    int currentInt;
    int sizeOfI = sizeOfB / 2;

    if(sizeOfB % 2 != 0) ++sizeOfI;
        for(int i = 0; i < sizeOfB; i+=2){
            currentInt = 0;
            if(byte_slice[i]=='\0') {
                break;
            }
            if(i + 1 < sizeOfB)
                currentInt = (currentInt << 8) + byte_slice[i+1];
            currentInt = (currentInt << 8) + byte_slice[i+0];
            *ret_array = currentInt;
            ret_array++;
        }
        //Pointer to the return array in the parent scope.
        return ret_array;
    }

4 个答案:

答案 0 :(得分:2)

这行代码的含义是什么?

if(i + 1 < sizeOfB) currentInt = (currentInt << 8) + byte_slice[i+1];

此处currentInt始终为00 << 8 = 0

另外,对于每对bytes(我从现在开始称呼他们为uint8_t),你所做的就是打包int(让我称之为uint16_t从现在开始)通过执行以下操作:

  1. 你走最右边的uint8_t
  2. 你将它向左移动了8个位置
  3. 添加最左边的uint8_t
  4. 这真的是你想要的吗?

    假设您有byte_slice[] = {1, 2},则打包一个16位整数,其值为513(2<<8 + 1)!

    此外,您不需要将指针返回到uint16_t数组,因为调用者已将其提供给函数。

    如果你使用函数的返回,正如Joachim所说,你得到一个从uint16_t数组的位置开始的指针,它不是位置[0]

答案 1 :(得分:2)

Vincenzo有一点(或两点),你需要明确你要做的事情;

将两个字节合并为一个16位int,一个字节为MSB,一个字节为LSB

int16 result = (byteMSB << 8) | byteLSB;

将字节数组转换为16位

for(i = 0; i < num_of_bytes; i++)
{
    myint16array[i] = mybytearray[i];
}

将数据数据复制到另一个数据

memcpy(dest, src, num_bytes);

那将(可能是平台/编译器依赖)与我的第一个例子具有相同的效果。

另外,谨防使用整数表示签名值,使用uints,更安全,可能更快。

答案 2 :(得分:1)

问题很可能是您增加ret_array然后返回它。当您返回它时,它将指向目标数组之外的一个位置。

将指针保存在函数的开头,然后使用该指针。

答案 3 :(得分:1)

考虑使用结构。不过,这有点像黑客。

我的头顶看起来就像这样。

struct customINT16 {
    byte ByteHigh;
    byte ByteLow;
}

所以在你的情况下你会写:

struct customINT16 myINT16;

myINT16.ByteHigh = BYTEARRAY[0];
myINT16.ByteLow = BYTEARRAY[1];

你必须通过一个指针来投射它,但是:

intpointer = (int*)(&myINT16);
INTARRAY[0] = *intpointer;