主机字节序的判定(三种方法)

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 *)&num;//这个地方加强转防止爆警告

    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 *)&num;
    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;
}

  • 54
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值