字节序
字节序又称为端序或者尾序,顾名思义就字节的顺序。专业的讲就是指在存储器或者在通信链路中,由多字节组成的数据的排列方式。
对于多字节数据的顺序有两种,一种是数据的高位存储在内存的低地址处,称为小端序,另一种是数据的高位存在内存的高地址出,称为大端序。
小端序
用小端序表示的数据,数据的高位在内存地址的低位。下面用一个unsigned long
类型的数据0x12345678
来举例说明。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include<stdio.h>
#include<arpa/inet.h>
int main()
{
printf("unsigned int:%ld\n",sizeof(unsigned long));
printf("unsigned char:%ld\n",sizeof(unsigned char));
unsigned int a=0x12345678;
unsigned char *pointer=(unsigned char *)(&a);
printf("host :%p:%0x\t%p:%0x\t%p:%0x\t%p:%0x\n",&pointer[0],pointer[0],&pointer[1],pointer[1],&pointer[2],pointer[2],&pointer[3],pointer[3]);
return 0;
}
程序运行结果:
unsigned int:8
unsigned char:1
host :0x7ffee0b4d2dc:78 0x7ffee0b4d2dd:56 0x7ffee0b4d2de:34 0x7ffee0b4d2df:12
|
存储的数据是unsigned long
类型的数据,数据的高位是0x12
,但是在实际的内存分布来看,数据的高位位于低地址而数据的低位在高字节地址。
这样存储的好处就是计算机可以先处理数据低位,在处理数据高位,方便计算机进行运算。
大端序
大端序的高地址位存储的是数据低位,低地址存储数据高位。
大端序方便人们进行阅读,因此在网络传输和存储时都采用大端序。在网络编程,利用socket
通信时,要将主机字节序也就是小端序转换成网络字节序也就是大端序,才能进行发送。同理,接收数据时,也要将网络字节序转换为主机字节序,计算机才能对数据进行处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include<stdio.h>
#include<arpa/inet.h>
int main()
{
unsigned long a=0x12345678;
unsigned char *pointer=(unsigned char *)(&a);
unsigned long b=htonl(a);
pointer=(unsigned char *)(&b);
printf("network :%p:%0x\t%p:%0x\t%p:%0x\t%p:%0x\n",&pointer[0],pointer[0],&pointer[1],pointer[1],&pointer[2],pointer[2],&pointer[3],pointer[3);]
return 0;
}
输出结果:network :0x7ffd9416f4d8:12 0x7ffd9416f4d9:34 0x7ffd9416f4da:56 0x7ffd9416f4db:78
|
通过htonl
函数可以将主机字节序(小端)转换成网络字节序(大端),经过转换后,数据的低地址位存储数据的高位。
判断本机的字节序
下面是一段简单的代码可以判断本机的字节序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#include<stdio.h>
#include<arpa/inet.h>
void judge()
{
int a = 0x12345678;
if( *((char*)&a) == 0x12)
printf("big endian \n");
else
printf("little endian \n");
}
int main()
{
judge();
return 0;
}
|