• 【基础知识系列】用示例一窥字节序-大小端


    代码示例

    示例代码分别在mac与android的开发环境下测试主机的字节序,还有通过IDE分析一个Int整型在内存的实际存储,于"肉眼可视"的方式去观察数据在内存的存储情况,加深与理解字节大小端。代码示例了两种方式判断主机字节序是否为小端字节序

    mac 环境示例

    代码

    #include 
    
    using namespace std;
    
    bool isLittleEndian() {
        int i = 1;
        //强转char指针,即指向int的首字节,可访问int的首字节的内容/值
        char *a = (char *) &i;
        return *a == 1;
    }
    
    bool isLittleEndian2() {
        union {
            int i;
            char c;
        } un;
        //char跟int是共用内存块,然后内存对的,即char跟int的首字节是同一块内存空间
        un.i = 1;
        return un.c == 1;
    }
    
    int main() {
    
        int x = 0x12345678;
        char *p = (char *) &x;
    
        cout << "逻辑上的顺序: 0x 12 34 56 78" << endl;
        printf("内存中的顺序: 0X %0x % 0x %0x %0x \n", p[0], p[1], p[2], p[3]);
    
        cout << "当前主机序字节序是: ";
        if (isLittleEndian()) {
            cout << "小端"<< endl;
        } else {
            cout << "大端" << endl;
        }
    
        cout << "当前主机序字节序是: ";
        if (isLittleEndian2()) {
            cout << "小端"<< endl;
        } else {
            cout << "大端" << endl;
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    运行结果

    在这里插入图片描述

    结论:OSX 系统的主机字节序是小端/ little-endian

    PS: 苹果官网文档也有说明的,MAC电脑,包括最新出M1、M2 都是小端序
    在这里插入图片描述

    运行时内存

    使用Clion IDE的Memory View功能!
    在这里插入图片描述
    如下是上述代码示例中x变量在内存中的存储情况
    在这里插入图片描述

    Android环境示例

    代码

    native-lib.cpp文件的内容

    #include 
    #include 
    #include 
    
    using namespace std;
    
    static char* TAG = "Demo";
    
    bool isLittleEndian() {
        int i = 1;
        char *a = (char *) &i;
        return *a == 1;
    }
    
    bool isLittleEndian2() {
        union {
            int i;
            char c;
        } un;
        un.i = 1;
        return un.c == 1;
    }
    
    void testEndian() {
    
        int x = 0x12345678;
        char *p = (char *) &x;
    
        __android_log_print(ANDROID_LOG_INFO, TAG, "0x %x %x %x %x", p[0], p[1], p[2], p[3]);
    
        if (isLittleEndian()) {
            __android_log_print(ANDROID_LOG_INFO, TAG, "小端");
        } else {
            __android_log_print(ANDROID_LOG_INFO, TAG, "大端");
        }
    
        if (isLittleEndian2()) {
            __android_log_print(ANDROID_LOG_INFO, TAG, "小端");
        } else {
            __android_log_print(ANDROID_LOG_INFO, TAG, "大端");
        }
    }
    
    
    extern "C" JNIEXPORT jstring JNICALL
    Java_com_example_myapplication_MainActivity_stringFromJNI(
            JNIEnv *env,
            jobject /* this */) {
        std::string hello = "Hello from C++";
        testEndian();
        return env->NewStringUTF(hello.c_str());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    运行结果

    在这里插入图片描述
    结论:Linux/Android 系统 的主机字节序是小端/little-endian

    运行时内存

    PS: 使用AS的Memory View功能!
    在这里插入图片描述

    大小端 big/little enidan

    为什么会存大小端字节序呢?
    大小端的来由主要是多个字节单位的数据类型单元需要约定在内存如何存放,如32位Int整型为四个字节,然后计算机存储与读取数据最小单位是Byte(一个字节,8个Bit),故32位四个字节的整型就需要分四个单玩按规定的顺序放置到内存中。目前是存在两种存放的规侧:分别是大小端字节序,如下是示图:
    在这里插入图片描述

    什么是大端字节序?
    比较符合人类阅读习惯的字节序为大端序,是从左到右扫描,看到的多字节的数据类型(如32位整型),每个字节单位是从大到小的排列,非常直观,符合人类的直觉感观(这里的大是指高位字节,小是指低位字节),即字节单元从大到小的排列,就是高位字节数排在内存的最前(存诸在内存的低地址位)低位节数排到后面(低字节存储在内存的高地址位)。内存在横向空间/左到右是低位地址到高位地址空间来分布!

    什么是小端字节序?
    主机/计算机字节序通常是小端,有些主机同时支持大小端字节序,通道配置开关指定当前支持大端还是小端
    为方便计算机存储处理的字节序为小端序,也是说从左到右扫描,看到的多个字节的数据,每个字节单位是倒着排序的,从小到大的排列;低位字节存放在内存的前面(内存的低地位),高位字节存放在内存的后面(内存的高地位)

    什么是网络字节序?
    网络字节序是网络上传输所约定的统一的字节序,便于不同字节序的主机交换数字。网络字节序是大端序,即网络过来的字节顺需要通过字节转换接口换为主机序,然后当主机序数据发送到网络时也需要转换为网络序。
    注意:
    1、只有多字节单位的数据类型才需要做字节序的转化,如char、byte或char、byte数据这类是一个字节单位的就无须关注与处理;
    2、字节序转接接口是没有副作用的,即当主机序也是大端序时,调用网络序化主机序的接口时,内部是没有做任何处理的( 即接口内部判断逻辑,如果当前主机序是大端就不需要做任何的转化操作)
    在这里插入图片描述

    相关文章

  • 相关阅读:
    一键自动化博客发布工具,用过的人都说好(51cto篇)
    8.WPF命令
    SPI和API还在傻傻分不清楚?
    golang中map赋值
    Axure 9 实战案例,动态面板的应用 6,导航菜单栏的手风琴效果
    MySQL 3 环境搭建 MySQL 5.7版本的安装、配置
    Pytorch迁移学习训练病变分类模型
    全球南方《乡村振兴战略下传统村落文化旅游设计》许少辉八一新著作——2023学生开学季辉少许
    Java多线程同步工具类:Semaphore、CountDownLatch 、CyclicBarrier、Exchanger原理剖析
    Linux虚拟机 & Docker 安装 RabbitMQ
  • 原文地址:https://blog.csdn.net/SCHOLAR_II/article/details/127537626