(1)利用联合的特色。联合中的数据成员是共享存储空间的,所分配的空间为数据成员中最大所需的内存数。程序定义了名为endian_un的联合体,其中包含两个数据成员,一个是short类型的数据成员(在32位系统上,short类型的长度是2字节),一个是字符类型的字符数组,字符数组的元素个数为short类型的字节数。
程序将var赋值为0x0102。因为联合结构的特色,bits字符串数组中一样存储了0x0102这一数值。经过判断字符串中的低位和高位存储的内容,就能够知道系统是little-endian仍是big-endian的。
#includehtml
int main(int argc, char **argv) { union { short s; char c[sizeof(short)]; } un;web
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); }数组
(2)经过强制类型转换实现。程序中经过取flag变量的地址,得到起始空间的存储内容。若是起始空间存储的是数据的低位内容,则表示存储方式为little-endian,不然为big-endian。
程序的具体代码以下:
//使用类型的强制转换实现little-endian与big-endian的判断
int is_little_endian(void)
{
unsigned short flag=0x4321;
if (*(unsigned char*)&flag==0x21)
return 1;
else
return 0;
}
使用gcc编译p13.1.c,得到名为p13.1的可执行文件。执行该程序,具体输出以下。能够看到x86系统的内存数据存储方式为little-endian方式。
[program@localhost charter13]$ gcc -o p13.1 p13.1.c
[program@localhost charter13]$ ./p13.1
judged by first method, little-endian
judged by second method, little-endian
[program@localhost charter13]$
之因此介绍big-endian和little-endian,是由于这一数据存储方式不只影响程序在不一样硬件平台中的移植,并且在网络编程中也要考虑字节顺序的问题。为了不兼容性的问题,网络中的数据传输都使用了从高到低的顺序存储方式。所以,若是要将数据从低位字节优先(little-endian)的机器上发往网络,必须首先进行转换。而big-endian的机器是不须要转换的。
Linux系统提供了htons、htonl、ntohs、ntoh这4个函数用于进行字节顺序的转换。其中,h是host的缩写,n表示network。最后一个字符若是是s,表示short类型,若是是l,表示为long类型。4个函数的具体定义以下: uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); htonl/htons:表示主机字节顺序转换成网络字节顺序,htonl函数和htons函数的区别在于参数长度存在差别。 ntohl/ntohs:表示网络字节顺序转换成主机字节顺序,ntohl函数和ntohs函数的区别在于参数长度存在差别。