1.1字节序判定的基础知识以及判定
不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):
小端序(little-endian) - 的序字节存储在低地址
将低字节存储在起始地址,称为“Little-Endian”字节序,Intel、AMD等采用的是这种方式;
大端序(big-endian)- 高序字节存储在低地址
将高字节存储在起始地址,称为“Big-Endian”字节序,由ARM、Motorola等所采用
1.1.1字节序判定的原理图
1.1.2字节序判定的方法
#include <stdio.h>
int main(int argc, char const *argv[])
{
int num=0x12345678;
char *p=(char *)#//这个地方加强转防止爆警告
if(*p==0x12){
printf("这是大端字节序\n");
}else if(*p==0x78){
printf("这是小端字节序\n");
}
return 0;
}
1.1.3union联合体是共用一块内存,所以可以使用这种方法测试
#include <stdio.h>
typedef union {
char a;
int b;
}msg_t;
int main(int argc, char const *argv[])
{
msg_t num;
num.b=0x12345678;
if(num.a==0x78){
printf("这是小端字节序\n");
}else if(num.a==0x12){
printf("这是大端字节序\n");
}
return 0;
}
1.1.4使用位域的方法
#include <stdio.h>
struct mybit{
unsigned short a:4;
unsigned short b:5;
unsigned short c:7;
}test;
int main(int argc, char const *argv[], char* envp[])
{
int i;
test.a = 2;
test.b = 3;
test.c = 0;
i = *(short*) &test;
if (i == 50){
printf("小端\n");
}else {
printf("大端\n");
}
}
2.2什么情况下需要考虑字节序转换的问题
2.2.1判定情况
如果数据是1个字节的,无需考虑字节序的问题和如果明确知道通信的双方主机字节序一样,也可以不考虑,如果超过了1个字节的数据作为一个整体时,就需要考虑了。
2.2.2将小端序的无符号四字节整型转换成大端序,也就是转换原理
#include <stdio.h>
int main(int argc, char const *argv[])
{
unsigned int num=0x12345678;
char *p=(char *)#
char *q=p+3;
unsigned char temp;
temp=*p;
*p=*q;
*q=temp;
p++;
q--;
temp=*p;
*p=*q;
*q=temp;
printf("%#x\n",num);
return 0;
}
2.3字节序转换函数
2.3.1函数
h host 主机 n network 网络 l 长 s 短
uint32_t htonl(uint32_t hostlong);//主机转网络 4字节
uint16_t htons(uint16_t hostshort);//主机转网络 2字节
uint32_t ntohl(uint32_t netlong);//网络转主机 4字节
uint16_t ntohs(uint16_t netshort);//网络转主机 2字节
2.3.2函数使用
#include <arpa/inet.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
unsigned int num=0x12345678;
unsigned int m=htonl(num);
printf("%#x\n",m);
return 0;
}