所以,我的问题非常简单:
我需要用一些信息填充char/unsigned char数组.中间的一些值取自short/int类型,这就是:
码:
int foo = 15; //0x0000000F
unsigned char buffer[100]={0};
..
memcpy(&buffer[offset], &foo, sizeof(int)); //either memmove
...
Run Code Online (Sandbox Code Playgroud)
输出:
... 0F 00 00 00 ..
Run Code Online (Sandbox Code Playgroud)
所以到现在为止我编写了一个函数来反转这些字段,但我认为这不是一个聪明的解决方案,因为它会影响执行时间,资源和开发时间.
有更简单的方法吗?
编辑:正如你们许多人所指出的,这种行为是由于小端处理器产生的,但我的问题仍然存在.我需要在big-endian中使用int/short值来填充此缓冲区,因为我需要将数据序列化以传输到以小/大端工作的机器,因为此协议已经定义,所以无关紧要.
注意:用于在C++中进行编译
这是因为您使用的处理器架构是小端.多字节数字(大于a的任何数字uint8_t)与最低有效字节一起存储在最低地址.
编辑
你做什么真的取决于缓冲区的用途.如果你只是在内部使用缓冲区,忘记字节交换,你将不得不在两个方向上进行,这是浪费时间.
如果是某些外部实体,例如文件或网络协议,则文件或网络协议的规范将说明字节顺序是什么.例如,所有Internet协议的网络字节顺序实际上是大端.网络库提供了一系列功能,用于转换用于发送和接收Internet协议消息的值.例如,硒
https://linux.die.net/man/3/htonl
如果你想自己动手,可移植的方法是使用比特移位,例如
void writeUInt32ToBufferBigEndian(uint32_t number, uint8_t* buffer)
{
buffer[0] = (uint8_t) ((number >> 24) & 0xff);
buffer[1] = (uint8_t) ((number >> 16) & 0xff);
buffer[2] = (uint8_t) ((number >> 8) & 0xff);
buffer[3] = (uint8_t) ((number >> 0) & 0xff);
}
Run Code Online (Sandbox Code Playgroud)
既不memcpy,也不memmove 反向复制对象时的数据.转储字符数组时观察到的字节值对应于32位值15(0F十六进制)存储在环境中的内存中的方式.
它似乎是小端序,这在台式机和笔记本电脑中很常见.其他系统,如许多智能手机,可能会以big-endian顺序存储整数值00 00 00 0F,您认为这更自然,但两种方法都同样正确.这只是一个惯例问题.Little-endian顺序表示首先存储具有最低值位的字节,而big-endian则相反:首先存储具有最高值位的字节.
维基百科上的综合性文章深入探讨了这一主题.
在您的应用程序中,您必须指定预期存储二进制值的顺序,如果您决定使用big-endian,我建议您使用此代码实现跨环境的可移植性:
#include <stdint.h>
int foo = 15; //0x0000000F
unsigned char buffer[100] = { 0 };
..
buffer[offset + 0] = ((uint32_t)foo >> 24) & 0xFF;
buffer[offset + 1] = ((uint32_t)foo >> 16) & 0xFF;
buffer[offset + 2] = ((uint32_t)foo >> 8) & 0xFF;
buffer[offset + 3] = ((uint32_t)foo >> 0) & 0xFF;
...
Run Code Online (Sandbox Code Playgroud)