C小端但产生大端结果?
Posted
技术标签:
【中文标题】C小端但产生大端结果?【英文标题】:C little endian but produce big endian result? 【发布时间】:2016-02-29 12:11:37 【问题描述】:我刚刚使用以下代码在 Raspberry Pi 上做了一个小实验:
//tutorialspoint.com/unix_sockets/network_byte_orders.htm
#include <stdio.h>
int main(int argc, char **argv)
union
short s;
char c[sizeof(short)];
un;
un.s = 0x0102;
if (sizeof(short) == 2)
if (un.c[0] == 1 && un.c[1] == 2)
printf("big-endian\n");
else if (un.c[0] == 2 && un.c[1] == 1)
printf("little-endian\n");
else
printf("unknown\n");
else
printf("sizeof(short) = %d\n", sizeof(short));
exit(0);
我得到的结果是little endian。
现在当我将整数转换为字节数组时,输出的结果是大端序
unsigned char c[4];
int num = 170; // suppose to give 0000 0000 0000 00AA
memcpy(c, (char*)&num, sizeof(int));
printf("c[0] = %04x \n", c[0]);
printf("c[1] = %04x \n", c[1]);
printf("c[2] = %04x \n", c[2]);
printf("c[3] = %04x \n", c[3]);
memcpy((char *)&num, c, sizeof(int));
printf("%d\n", ntohl((long)num));
输出:
c[0] = 00aa
c[1] = 0000
c[2] = 0000
c[3] = 0000
-1442840576
为了让它变成小端序,我不得不做一个转变
//c[0] = (num >> 24) & 0xFF;
//c[1] = (num >> 16) & 0xFF;
//c[2] = (num >> 8) & 0xFF;
//c[3] = num & 0xFF;
现在我很困惑我的树莓派是小端还是大端?
此外,我将通过套接字传递这些数据,所以我需要确保它是网络字节顺序还是可以,只要我标准化了我将在所有文件中使用的字节序我尝试与之通信的设备?
附言。另外,如果我需要手动将整数数组中的所有整数从小端转换为大端,我应该怎么做?我在网上找到的大多数解决方案都只是转换整数而不是整数数组。
【问题讨论】:
代码0000 0000 0000 00AA
是为人类从左到右阅读而编写的,将AA
存储在低字节中,在小端中,这正是你所得到的。
为什么不为两个测试使用相同的值 0x0102?你会看到你得到相同的结果:02 是第一个。
使用正确的序列化和位移/掩码。不要依赖实现定义或可能未定义的行为。使用好的编译器不会有速度损失或只有边际速度损失
【参考方案1】:
在这两种情况下都是小端。
在您的第一种情况下,最低有效字节是 2 并且匹配 c[0] - little-endian。
在您的第二种情况下,最低有效字节为 170(所有其他字节均为零)并且匹配 c[0] - little-endian。
如果您通过套接字复制数据,那么您只需要确保数据格式是一致的。不管它是什么。
对于复制一个数据数组,只需做与单个项目相同的事情,但重复它。
【讨论】:
【参考方案2】:int num = 170; // suppose to give 0000 0000 0000 00AA
没有。它应该给你AA, 00, 00, 00
(或AA, 00, 00, 00, 00, 00, 00, 00
,如果int
是64 位)。 在小端布局中,最低有效字节存储在最低地址。 0x000000AA
(170)的最低有效字节是0xAA
。
【讨论】:
啊,我明白了!谢谢:)以上是关于C小端但产生大端结果?的主要内容,如果未能解决你的问题,请参考以下文章