在裘宗燕翻译的《程序设计实践》里,这对术语并没有翻译为“大端”和小端,而是“高尾端”和“低尾端”,这就好理解了:如果把一个数看成一个字符串,比如11223344看成"11223344",末尾是个'\0','11'到'44'个占用一个存储单元,那么它的尾端很显然是44,前面的高还是低就表示尾端放在高地址还是低地址,它在内存中的放法非常直观,如下图:
#include <iostream>
using namespace std;
int main()
{
int nNum = 0x12345678;
char chData = *(char*)(&nNum);
if (chData == 0x12)
{
cout << "big" << endl;
}
else
{
cout << "small" << endl;
}
system("PAUSE");
return 0;
}
网络字节序
字节序
大端字节序(BigEndian)
最高有效位(MSB:MostSignificant Bit)存储于最低内存地址处,最低有效位(LSB:Lowest Significant Bit)存储于最高内存地址处。
小端字节序(LittleEndian)
最高有效位(MSB:MostSignificant Bit)存储于最高内存地址 处,最低有效位(LSB:LowestSignificant Bit)存储于最低内存地址处。
主机字节序
不同的主机有不同的字节序,如x86为小端字节序,Motorola 6800为大端字节序,ARM字节序是可配置的。
网络字节序规定为大端字节序
#include <stdio.h>
#include <arpa/inet.h>
int main(){
unsigned long a = 0x12345678;
unsigned char *p = (unsigned char *)(&a);
printf("主机字节序:%0x %0x %0x %0x\n", p[0], p[1], p[2], p[3]);
unsigned long b = htonl(a); //将主机字节序转化成了网络字节序
p = (unsigned char *)(&b);
printf("网络字节序:%0x %0x %0x %0x\n", p[0], p[1], p[2], p[3]);
return 0;
}
关于:htonl
1. #include <arpa/inet.h>
2.
3. uint32_t htonl(uint32_t hostlong);
4.
5. uint16_t htons(uint16_t hostshort);
6.
7. uint32_t ntohl(uint32_t netlong);
8.
9. uint16_t ntohs(uint16_t netshort);
h是主机host,n是网络net,l是长整形long,s是短整形short,所以上面这些函数还是很好理解的
1. #include <stdio.h>
2. #include <arpa/inet.h>
3.
4. int main()
5. {
6. struct in_addr ipaddr;
7. long addr = inet_addr("192.168.1.100");
8. "addr = %u\n", ntohl(addr));
9.
10. ipaddr.s_addr = addr;
11. "%s\n", inet_ntoa(ipaddr));
12. return 0;
13. }
运行结果:
值得注意的是:
in_addr_in inet_addr(const char *strptr);
inet_addr的参数是一个:点分十进制字符串,返回的值为一个32位的二进制网络字节序的IPv4地址,不然的话就是:INADDR_NONE
而返回值为:in_addr_t:IPv4,一般为uint32_t
所以也可以定义为:unsigned long
char * inet_ntoa(struct in_addr inaddr);
参数是一个结构体,所以要调用必须先定义一个结构体。
字节序转换函数
说明:在上述的函数中,h代表host;n代表network s代表short;l代表long |
地址转换函数
|