【C语言 | 嵌入式】大端序和小端序详解

注:本文拷贝自我个人技术分享公众号【嵌入式技术部落】

一、大端序和小端序概念详解


字节序
字节序,又称端序,英文Endiannnes。字节序,简单点说,就是字节的存储顺序。数据都是单字节,那么不存在字节的存储顺序,对于多字节的数据,就要考虑字节的存储顺序了。典型的情况是int、double等在内存中的存放方式和网络传输的传输顺序。

字节序跟硬件的体系结构有关,和编程语言以及操作系统无关,例如在x86系列的pc上的solaris系统是小端序,sunsparc平台的solaris是大端序。


大端序(Big-endian)
大端字节序,高字节存于内存低地址,低字节存于内存高地址。

小端序(Little-endian)
小端字节序,低字节存于内存低地址,高字节存于内存高地址。


字节的高位与低位
举个例子,int a = 0x3A5C869E;那么左边3A就是高位字节,右边的9E就是低位字节,从左到右,由高到低,(注意,高低乃相对而言,比如86相对于9E是高字节,相对于5C是低字节)
在这里插入图片描述


地址的高位和低位
地址编号小的是低地址,地址编号大的是高地址。读数据永远是从低地址开始的!!!
在这里插入图片描述


二、大端序和小端序数据如何存储


小端序
数据的低字节存于内存低地址,高字节存于内存高地址。
简记:小端序就是低位对应低地址,高位对应高地址

存放二进制数:1011 0100 1111 0110 1000 1100 0001 0101
注意注意:我们在存放的时候是以一个存储单元为单位来存放,存储单元内部不需要再转变顺序啦!!
就例如下面的低位0001 0101存放在0号地址,我们不需要把它变成1010 1000,不需要!!不需要!!
在这里插入图片描述
存放十六进制数:B4F68C15
上面的二进制1011 0100 1111 0110 1000 1100 0001 0101转化为十六进制为B4F68C15。5对应0101,1对应0001,所以在存放的时候两个十六进制位就占用一个存储单元。
在这里插入图片描述


大端序
数据的高字节存于内存低地址,低字节存于内存高地址。
存放二进制数:1011 0100 1111 0110 1000 1100 0001 0101
在这里插入图片描述
存放十六进制数:B4F68C15
在这里插入图片描述


三、判断大端序和小端序

实现32位cpu中存储方式小端字节序和大端字节序的判断

#include <stdio.h>

void endiannessOne()
{
    int a = 0x12345678;
    char *p = (char *)&a;

    if(*p == 0x12)
    {
        printf("%s this is big endian\n", __FUNCTION__);
    }
    else if(*p == 0x78)
    {
        printf("%s this is little endian\n", __FUNCTION__);
    }
    else
    {
        printf("%s unable to determine endian\n", __FUNCTION__);
    }
}

void endiannessTwo()
{
    union test
    {
        short a;
        char b;
    } c;
    c.a = 0x1234;
    if(c.b == 0x12)
    {
        printf("%s this is big endian\n", __FUNCTION__);
    }
    else if(c.b == 0x34)
    {
        printf("%s this is little endian\n", __FUNCTION__);
    }
    else
    {
        printf("%s unable to determine endian\n", __FUNCTION__);
    }
}

int main()
{
    endiannessOne();
    endiannessTwo();
    return 0;
}

pc机cpu是Inter系列,Intel系列的CPU都是按照小端序存储的。系统是ubuntu。上文我们说过,字节序跟硬件的体系结构有关,和编程语言以及操作系统无关。编译运行结果如下:
在这里插入图片描述

  • 28
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言结构体的字节序是由编译器决定的,因此在不同的编译器上可能会有不同的字节序。一般来说,x86架构的CPU采用的是小端序(Little Endian),而一些其他的CPU架构,如ARM和PowerPC,则采用的是大端序(Big Endian)。 要将一个大端序的结构体转换为小端序,可以使用以下步骤: 1. 将结构体中的每个成员按照其在结构体中的顺序逐个取出。 2. 对于每个成员,将其按照小端序的字节序重新排列。 3. 将重新排列后的每个成员按照其在结构体中的顺序逐个放回结构体中。 下面是一个示例代码,将一个包含两个成员的结构体从大端序转换为小端序: ```c #include <stdio.h> #include <stdint.h> // 定义一个包含两个成员的结构体 struct my_struct { uint16_t a; uint32_t b; }; // 将一个大端序的结构体转换为小端序 void convert_to_little_endian(struct my_struct *s) { // 将成员a按照小端序重新排列 s->a = ((s->a & 0xff00) >> 8) | ((s->a & 0x00ff) << 8); // 将成员b按照小端序重新排列 s->b = ((s->b & 0xff000000) >> 24) | ((s->b & 0x00ff0000) >> 8) | ((s->b & 0x0000ff00) << 8) | ((s->b & 0x000000ff) << 24); } int main() { // 定义一个大端序的结构体 struct my_struct s = {0x1234, 0x56789abc}; printf("Before conversion: 0x%x 0x%x\n", s.a, s.b); // 将结构体转换为小端序 convert_to_little_endian(&s); printf("After conversion: 0x%x 0x%x\n", s.a, s.b); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值