大小端的判断

1.关于进制

1.1 进制数与位数

n进制数中,一位最多表示到数字n-1
十进制中1位最多能表示9个数字

满则溢,溢则进位。

拿我们最常用的是10 进制来举例说明,
构成十进制的最小单位数: 1 2 3 4 5 6 7 8 9 0
十进制(其实只有从9到0这几个数字,10本身并不存在,或者说10并不是构成十进制的最小单位数,
10是进位后的结果,由于生活经验我们早就熟烂于心所以认为10进制中10是最小单位数):
用1,2,3,4,5,6,7,8,9,0这几个数字表示想要表达的数,
其中0的含义是满后归为零,进位表示对满的次数的记录拿数数来说,从1数到9,此时的状态还没有满,再数一个数后,
此时状态变满(达到进制要求的最大数),由于满则溢出,溢出则进位(新添一位),
就变成了两位数 10(逢十进一)。

2.字节

二进制中 一位可表示2个数字,分别是0和1,一位表示1比特
1个字节 等于 8 位
计算机存储的最小单位是字节也就是8位比特
因为是存储的最小单位所以读取的时候也是按字节作为最小单位进行读取的。

#include<stdio.h>
int main(){printf("char 占几字节: %d\n",sizeof(char));printf("short 占几字节: %d\n",sizeof(short));}

结果:

#include<stdio.h>
int main(){union {short s;char c[sizeof(short)];} un;printf("un.char 占几字节: %d,地址是: %p\n",sizeof(un.s),&un.s);printf("un.c    占几字节: %d,地址是: %p \n",sizeof(un.c),&un.c);}

short s 和 char c[sizeof(short)] 公用了同一块地址空间,都占用2个字节
union 公用一段内存

3.大小端

一个数字例如十进制的100,从左往右看,1表示最高位,后面俩0依次是次高位和最低位,
所谓小端即: 如果计算机的内存地址空间是从递增式的(举例),

把100存进去,如果从100的最低位开始一个一个存即现存0,再存0,最后存1,
那么这就是小端。
如果是从高位开始存,先存1,再存0,再存0,那么就是大端

判断大小端的代码片断

#include<stdio.h>
int main(){union {short s;char c[sizeof(short)];} un;printf("short 占用的字节数为: %d\n",sizeof(un));un.s=0x0102;if(un.c[0]==1&&un.c[1]==2){printf("big end\n");}else if(un.c[0]==2&&un.c[1]==1){printf("small end\n");}
}

由于union 占用2个字节,
存进去的 short s 的低位字节是02,高位字节是01
读取的时候如果读第一个字节是02,第二个字节是01,那么就是小端,否则是大端。

4.网络字节序

由于不同主机之间使用的不同的主机序,即有的是大端模式,有的是小端模式,
那么通信时如果一个是大端,一个是小端,读取的数据和发送的数据就会出错,
为了保持统一,我们需要在发送数据之前把主机序统一转为网络字节序。

使用函数 htonl来把主机字节序转网络字节序,如下

#include<stdio.h>
#include <arpa/inet.h>
int main(){int a = 0x01020304;short int b = 0x0102;printf("htonl(0x%08x)=0x%08x\n",a,htonl(a));printf("htonl(0x%08x)=0x%08x\n",b,htonl(b));
}


可以看出来网络字节序使用是大端模式

本文链接:https://my.lmcjl.com/post/10287.html

展开阅读全文

4 评论

留下您的评论.