zoukankan      html  css  js  c++  java
  • C语言


    目前使用的机器都是使用字节BYTE来存储的。

    对于跨越多字节的对象,必须搞清楚两个规则:

    • 这个对象的地址是什么
    • 在存储器中如何按照这些字节的存放的书序

    对于一个整型对象 a=0x12345678,一共有四个字节。
    假设存放在地址0x00002000中,于是,在0x2000开始放0x78还是0x12就是一个大小端问题。
    但是,对于只是读写一个WORD32而言,计算器如何存储WORD32字节序,其实并不重要。

    大小端的存储示例:
    大端法

    0x2000    0x2001    0x2002    0x2003
    12        34        56        78

    小端法

    0x2000    0x2001    0x2002    0x2003
    78        56        34        12

    什么时候会遭遇大小端问题:

    1. 在不同类型的机器之间通过网络传送二进制数据时
    2. 当阅读表示整型数据的字节序列时,这里重点是整型数据,并不是字节数据
    3. 档使用强制转换对象类型时候

    对于二进制文件流:
    文件流与网络流其实是一样的传输方式。
    如果一个整型对象,使用fread的方式按照字节序读取进来,首先要知道二进制文件的字节流的结构意义。

    • 1)从程序写入到二进制文件中

    假设有整型对象a=0x12345678 b=0x1E2B3D4C
    使用fwrite写入到二进制文件中
    a、在小端机器上使用fwrite写入时,这两个整型对象在内存中的摆放方式为
    0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
    78 56 34 12 4C 3D 2B 1E

    0x200    0x201    0x202    0x203    0x204    0x205    0x206    0x207
    78        56        34        12    4C        3D        2B        1E 

    写入到文件中
    0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
    78   56   34   12   1E   2B   3D   4C

    b、在小端机器上使用fwrite写入时,这两个整型对象在内存中的摆放方式为
    0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
    12 34 56 78 1E 2B 3D 4C
    写入到文件中
    0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
    12 34 56 78 1E 2B 3D 4C

    • 2)从二进制文件读取到程序中

    譬如文件里有下面的二进制序列:
    0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
    12 34 56 78 91 23 45 67
    a、在小端机器上使用fread,读取到0x200地址上,
    0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
    12 34 56 78 91 23 45 67
    现在,代码中从0x200地址读出一个整型对象,由于该机器是小端,那么读出来就是0x78563412
    b、在大端机器上使用fread,读取到0x200地址上,结果同上
    0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
    12 34 56 78 91 23 45 67
    但是,如果现在代码从0x200地址中读出一个整型对象时,读出来的整型对象将是0x12345678


    对于文本文件:(并不区分大小端)
    文本文件在文件中的存储方式是ASCII码的字节流
    如果有char *s = "ABCD1234"
    无论是大端还是小端机器,在内存里面的表示都是
    0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
    41 42 43 44 31 32 33 34
    所以使用stdio的库函数,写入到文件中,都是一样,从0地址开始按照byte写,连续写入8个字节


    //对应int32大小的成员 的转换 范例
    unsigned int swapInt32(unsigned int value)
    {
    return ((value & 0x000000FF) << 24) |
    ((value & 0x0000FF00) << 8) |
    ((value & 0x00FF0000) >> 8) |
    ((value & 0xFF000000) >> 24) ;
    }

  • 相关阅读:
    一个非侵入的Go事务管理库——如何使用
    事件驱动的微服务-事件驱动设计
    事件驱动的微服务-总体设计
    如何快速高效率地学习Go语言
    清晰架构(Clean Architecture)的Go微服务
    清晰架构(Clean Architecture)的Go微服务: 编码风格
    清晰架构(Clean Architecture)的Go微服务: 事物管理
    清晰架构(Clean Architecture)的Go微服务: 依赖注入(Dependency Injection)
    msf stagers开发不完全指北(四): msf 中使用域前置技术隐藏流量
    elementui 表格中带有按钮的loading解决方案
  • 原文地址:https://www.cnblogs.com/McKean/p/6084320.html
Copyright © 2011-2022 走看看