1.简介
内存中存储数据有两种方法:小端模式和大端模式。这取决于CPU,x86的CPU一般为小端模式。
little-endian:将低序字节存储在起始地址;(只需记住小端,就可推出大端。两个都记反而容易混淆)
big-edian:将高序字节存储在起始地址;
术语“大端”和“小端”表示将多字节值的哪一端存储在起始地址。
比如要存储一个两字节的短整数。
short a=0x0102;
小端模式
在内存中是这样的:
0x02 |
0x01 |
VS:
大端模式是这样的;
0x01 |
0x02 |
2.检测当前主机字节序程序:
#include <stdio.h> int main() { union { short s; char c[sizeof(short)]; }un; un.s = 0x0102; if(sizeof(short) == 2) { if(un.c[0] == 0x01 && un.c[1] == 0x02) { printf("big-edian\n"); } else if(un.c[0] == 0x02 && un.c[1] == 0x01) { printf("little-edian\n"); } else { printf("unknow\n"); } } else { printf("sizeof(short) != 2,try other means!"); } return 0; }
3.字节序转换
不同的系统可能用不同的模式,这样通过网络在不同的系统间传输多字节数据时就会出现数据解读错误。幸好规定了网络字节序(大端模式)。在网络上传输数据时,我们可以把数据从本地字节序转换到网络字节序然后再发到网络上。从网络上接收到数据后转化为本地字节序。这样我们就可以避免这些字节序细节问题了。当然传输单字节的字符串时,不许用转换字节序。
windows和Linux平台都提供了转换函数。在Linux下:
#include <netinet/in.h> uint16_t htons(uint16_t host16bitvalue); uint32_t htonl(uint32_t host32bitvalue); /*返回网络字节序的值*/ uint16_t ntohs(uint16_t net16bitvalue); uint32_t ntohl(uint32_t net32bitvalue); /*返回主机字节序的值*/
16:表示是16bit的值;32:表示是32bit的值;
s:短整数,即16bit; l:长整数,即32bit;
h:本地主机字节; n:网络字节;
4.大端模式和小端模式各自的优势:
小端模式 :强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
大端模式 :符号位的判定固定为第一个字节,容易判断正负。
好像对大端小端模式的考察每年都是笔试题的热点。
参考链接:详解大端模式和小端模式