0

我正在使用这段代码:

int number; //=smth
unsigned char sendBuffer[255];
sendBuffer[0] = number & 0xFF;
sendBuffer[1] = (number  >> 8) & 0xFF;
sendBuffer[2] = (number  >> 16) & 0xFF;
sendBuffer[3] = (number  >> 24) & 0xFF;

放入number字节数组sendBuffer

我的问题是:

  1. 假设我现在想在字节数组中嵌入两个数字,我应该这样进行吗?

    sendBuffer[0] = number & 0xFF;
    sendBuffer[1] = (number  >> 8) & 0xFF;
    sendBuffer[2] = (number  >> 16) & 0xFF;
    sendBuffer[3] = (number  >> 24) & 0xFF;
    sendBuffer[4] = number2 & 0xFF;
    sendBuffer[5] = (number2  >> 8) & 0xFF;
    sendBuffer[6] = (number2  >> 16) & 0xFF;
    sendBuffer[7] = (number2  >> 24) & 0xFF;
    

    即使 number 大小为 8 或 6 个字节,这也能工作吗? (我这么说是因为在某些平台上 int 可能是 4 个字节或 6 个字节对吗?所以我在想上面的代码在数字为 6 个字节时是否也有效?另外需要注意的是,即使它是 6 个字节,但我只在其中存储 4 字节整数,上面的代码可以工作吗?)。

    我通常将这个缓冲区存储在卡的某些内存中,并且我在读取它时没有问题(例如,字节序等问题,读取时的字节数组似乎按照我保存的顺序出现)。

  2. 最后,如何从字节数组中重构整数sendBuffer

4

3 回答 3

1

1)是的,就这样进行。不,它只适用于 4 个字节。

有一种更简单、更好的方法可以做到这一点,尽管如果缓冲区从一台计算机发送到使用不同架构的另一台计算机,它可能会导致字节顺序问题。假设您知道 的类型number,将另一个数组覆盖在sendBuffer.

unsigned char sendBuffer[255];
number_type *sendBufferNum = (number_type*) sendBuffer;
sendBufferNum[0] = number;
sendBufferNum[1] = number2;

读一个数字也可以用同样的方法。

unsigned char receiveBuffer[255];
//read values into receiveBuffer
number_type *receiverBufferNum = (number_type*) receiveBuffer;
number_type number = recieveBuffer[0];
number_type number2 = receiveBuffer[1];
于 2013-09-24T09:22:25.550 回答
0
  1. 这仅适用于 32 位(4 字节)整数。如果要支持大 int,则必须编写 64 位(8 字节)版本。

  2. 您可以使用按位或来反转该过程。

    #define BigEndianGetUInt32(ptr)  ( ((uint32)((uint8*)(ptr))[0]) << 24 | \  
                                       ((uint32)((uint8*)(ptr))[1]) << 16 | \  
                                       ((uint32)((uint8*)(ptr))[2]) <<  8 | \  
                                        (uint32)((uint8*)(ptr))[3]) )
    number  = BigEndianGetUInt32(sendBuffer);
    number1 = BigEndianGetUInt32(sendBuffer+4);
    

附带说明一下,如果您只是为同一设备序列化数据,则可以将 memcpy'ednumbersendBuffer.

memcpy(sendBuffer, &number, sizeof(number));
memcpy(sendBuffer+sizeof(number), &number1, sizeof(number1));
于 2013-09-24T09:20:08.507 回答
0

即使数字大小为 8 或 6 个字节,这是否有效?

它有效,但显然您需要添加更多行来保存值中的所有字节。这是大量的手动工作,不是很可扩展。改用程序化方法

auto num = number;
for (size_t i = 0; i < sizeof(number); i++, num >>= CHAR_BIT)
    sendBuffer[i] = number & 0xFF;

但是,当您已经拥有 时,为什么还要这样做memcpy()?这样你只需要1 行,更好的是,它可以很容易地扩展到多个值

memcpy(&sendBuffer[0],               number1, sizeof number1);
memcpy(&sendBuffer[sizeof(number1)], number2, sizeof number2);

最后,如何从字节数组sendBuffer中重构整数?

简单的。只需将字节移回

number  = (sendBuffer[3] << 24) | (sendBuffer[2] << 16) | (sendBuffer[1] << 8) | sendBuffer[0];
number2 = (sendBuffer[7] << 24) | (sendBuffer[6] << 16) | (sendBuffer[5] << 8) | sendBuffer[4];

再次,避免像那样繁琐的工作并使用for循环

number = 0;
for (size_t i = 0; i < sizeof(number); i++)
    number = (number << 8) | sendBuffer[i];

memcpy也有效,强烈推荐

memcpy(&number, &sendBuffer[numberIndex], sizeof number);
于 2013-09-24T09:19:08.203 回答