2016-02-29 39 views
0

我只是做了树莓派一个小实验我正在用下面的代码:C小端,但产生大端结果?

//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); 
} 

,我得到的是小尾数结果。

现在,当我转换的整数字节数组,出来的结果是在大端

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; 

我现在很困惑,如果我的树莓派是小endian或big endian?

此外,我要通过套接字传递这些数据,所以我需要确保它是网络字节顺序,还是没关系,只要我标准化了我将使用哪个endian我正在尝试与之通信的所有设备?

PS。另外,如果我需要手动将整数数组中的所有整数从小端转换为大端,我应该怎么做?我在网上找到的大多数解决方案只是转换整数而不是整数数组。

+1

代码'0000 0000 0000 00AA'为人类从左向右读取的方式将在低字节中存储'AA',小字节中给出了您准确得到的结果。 –

+0

为什么不使用相同的值0x0102进行两种测试?你会看到你得到相同的结果:02是第一个。 –

+0

使用正确的序列化与位移/掩码。不要依赖实现定义的或可能未定义的行为。使用好的编译器不会有或者只是边际速度惩罚 – Olaf

回答

4

这两种情况都是小尾数。

在你的第一个案例中,最不重要的字节是2,并且匹配c [0] - 小尾数。

在你的第二种情况下,最不重要的字节是170(所有其他都是零)并且匹配c [0] - 小尾数。

如果您通过套接字复制数据,那么您只需确保数据格式一致。它并不重要。

对于复制数据数组,只需执行与单个项目相同的操作,但重复该操作即可。

1
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

+0

好吧我知道了!谢谢 :) –