在C语言中将字节数组转换为整型数组

3
我有一些代码,旨在将C(Arduino)8位字节数组转换为16位int数组,但似乎只能部分工作。我不确定我做错了什么。
字节数组按小端字节顺序排列。如何将其转换为int(每个条目两个字节)数组?
通俗地说,我想合并每两个字节。
目前,它输出输入BYTE ARRAY:{0x10, 0x00, 0x00, 0x00, 0x30, 0x00}。 输出INT ARRAY是:{1,0,0}。输出应该是一个INT ARRAY:{1,0,3}
以下是我目前拥有的代码:
我根据Stack Overflow问题将C数组中的字节转换为长整型的解决方案编写了此函数。

我还有一个基于相同代码的解决方案,可将字节数组转换为长整型数组(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;
    }

1
为什么不直接将输入数组的指针转换为int*类型? - SomeWittyUsername
1
@icepack 可能是将 2 字节转换为 int,而 int 可能是 4 字节。 - Olaf Dietsche
1
@AkiSuihkonen 可能有效,如果 short 是2个字节并且字节序允许。 - Olaf Dietsche
1
@alk aa,我明白你的意思。在这种情况下,使用int可能不是最好的选择,16位类型可能更适合(就像AkiSuihkonen建议的那样)。 - SomeWittyUsername
@alk 可移植性问题无论如何都是一样的。 - SomeWittyUsername
显示剩余9条评论
4个回答

2
这行代码的含义是什么?
if(i + 1 < sizeOfB) currentInt = (currentInt << 8) + byte_slice[i+1];

在这里,currentInt 总是 0,而 0 << 8 = 0
另外,你要做的是,对于每一对 bytes(让我从现在开始称它们为 uint8_t),通过执行以下操作来打包一个 int(让我从现在开始称之为 uint16_t):
  1. 取最右边的 uint8_t
  2. 将其向左移动 8 个位置
  3. 添加左侧的 uint8_t
这真的是你想要的吗?
假设你有 byte_slice[] = {1, 2},你会打包一个值为 513 的 16 位整数(2<<8 + 1)!
此外,你不需要返回指向 uint16_t 数组的指针,因为调用者已经将其提供给函数。
如果你使用你的函数的返回值,就像 Joachim 所说的那样,你会得到一个指针,它从 uint16_t 数组的一个位置开始,而不是位置 [0]

我根据这个解决方案编写了这个函数:http://stackoverflow.com/questions/11295728/convert-bytes-in-a-c-array-as-longs/11295756#11295756 - frazras
我也有一个基于同样代码的解决方案,可将字节数组转换为长整型数组(32位),链接为http://pastebin.com/TQzyTU2j。 - frazras
@frazras也许你应该澄清一下你所说的“但它似乎只部分工作”是什么意思 :)! - Vincenzo Pii

2

Vincenzo有一点(或两点)道理,你需要清楚你想要做什么;

将两个字节组合成一个16位整数,其中一个字节是MSB,另一个字节是LSB

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

将字节数组转换为16位

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

将一个数组的数据复制到另一个数组中

memcpy(dest, src, num_bytes);

这将(可能是平台/编译器相关的)具有与我的第一个示例相同的效果。

此外,要注意不要使用int类型,因为它们表示带符号的值,应该使用无符号整型uint,更安全且可能更快。


他说这是第一个...但是你的按位或肯定比加号好 - SwiftMango

1
考虑使用结构体。虽然这有点像是一种hack。
我能想到的大致如下。
struct customINT16 {
    byte ByteHigh;
    byte ByteLow;
}

所以在你的情况下,你需要写:

struct customINT16 myINT16;

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

但是,您将不得不通过指针进行转换:

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

1
问题很可能是您增加了ret_array,然后返回它。当您返回它时,它将指向目标数组之外的一个位置。
在函数开始处保存指针,并使用该指针。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接