1. 程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
char a[] = { 4, 8, 3, 2, 7, 9, 1 };
printf("little-endian=%d, big-endian=%d\n", *((short *)a+1), htons(*((short *)a+1)));
struct test
{
unsigned short a:4;
unsigned short b:5;
unsigned short c:7;
}gg;
gg.a = 2;
gg.b = 3;
gg.c = 0;
printf("==%d\n", *((short *)&gg));
int hexInt = 0x12345678;
printf("===0x%x\n", *((char *)&hexInt));
return 0;
}
2. 运行结果(x86):
little-endian=515, big-endian=770
==50
===0x78
3. 分析:
涉及多字节数据在内存存储大小端问题;所谓大端,MSB,即是内存低地址存数据的高位,高地址存数据低位;而小端LSB,内存低地址存数据低位,内存高地址存数据高位;但给人看的时候大端比较符合我们的阅读顺序。 一般的x86采用小端模式,而网络传输采用大端模式。
*((short *)a+1) 即是数组a转换为short类型再加1的地址处的short值等于多少, 即a[2]=3,a[3]=2所表示short值,因x86cpu小端模式:
3 : 11000000 (低位)
2 : 01000000 (高位)
11000000 01000000 =》 00000010 00000011 == 2^9 + 2^1 + 2^0 = 512 + 2 + 1 = 515
同理大端模式:
3: 00000011 (高位)
2: 00000010 (低位)
00000011 00000010 == 2^9 + 2^8 + 2^1 = 512 + 256 + 2 = 770
那么 *((short *)&gg)你会分析了吧? 仅依小端模式说明:
2 : 0100 (低位)
3 : 11000
0 : 0000000 (高位)
0000000 00011 0010 == 2^4 + 2^5 + 2^1 = 16 + 32 + 2 = 50
0x12345678 的小端模式第一个char即是0x78 而大端模式即为0x12;
那现在大小端和类型转换问题算是明了了。