所以,我的问题非常简单:
我需要用一些信息填充char / unsigned char数组。中间的一些值取自short / int类型,这就是:
代码:
int foo = 15; //0x0000000F
unsigned char buffer[100]={0};
..
memcpy(&buffer[offset], &foo, sizeof(int)); //either memmove
...
输出:
... 0F 00 00 00 ..
所以现在我写了一个函数来反转这个字段,但我发现这不是一个聪明的解决方案,因为它会影响执行时间,资源和开发时间。
有更简单的方法吗?
编辑: 正如你们许多人指出的那样,这种行为是由于小端处理器产生的,但我的问题仍然存在。我需要在big-endian中使用int / short值来填充此缓冲区,因为我需要将数据序列化以传输到以小/大端工作的机器,因为此协议已经定义,所以无关紧要。
注意:用于在C ++中编译
答案 0 :(得分:6)
这是因为您使用的处理器架构是little endian。多字节数字(任何大于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);
}
答案 1 :(得分:6)
复制对象时,memmove
和15
都不会反转数据。转储字符数组时观察到的字节值对应于32位值0F
(十六进制00 00 00 0F
)存储在环境内存中的方式。
它似乎是小端序,这在台式机和笔记本电脑中很常见。其他系统(如许多智能手机)可能会以大端顺序#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;
...
存储整数值,您认为它们更多自然,但这两种方法同样正确。这只是一个惯例问题。 little-endian顺序表示首先存储具有最低值位的字节,而big-endian则相反:首先存储具有最高值位的字节。
关于Wikipedia的综合性文章深入探讨了这一主题。
在您的应用程序中,您必须指定预期存储二进制值的顺序,如果您决定使用big-endian,我建议您使用此代码实现跨环境的可移植性:
AlarmManager am = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(ctxt, AlarmService.class);
PendingIntent pen = PendingIntent.getBroadcast(ctxt, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.setExact(AlarmManager.RTC_WAKEUP, nextRing.getTime(), pen);
答案 2 :(得分:2)
在x86架构中,内存中的整数是小端。首先是最低字节。例如0x12345678在内存中将是78,56,34,12。
答案 3 :(得分:1)
&#34;更简单的方式&#34;是停止呼唤它&#34;逆转&#34;。为什么,真的吗? 0F
是多字节值中最不重要的部分,您会看到它存储在&#34;不太重要的&#34; (即较低的)地址。看起来非常一致和自然。你为什么称之为&#34;逆转&#34;?
唯一看起来&#34;逆转&#34;这就是&#34;奇怪&#34;您的原始符号0x0000000F
在评论中,您出于某种原因&#34;以从右到左的顺序记录字节:右边最不重要,左边更重要。
换句话说,这里的逆转完全是你的感知/想象力的产物。你,人类,从右到左的顺序写数字,但同时按从左到右的顺序输出字节(和写C程序)。两者之间的不一致是在这种情况下造成逆转的错觉。