侧边栏壁纸
    • 累计撰写 296 篇文章
    • 累计收到 520 条评论
    嵌入式软件-基于C语言小端转大端
    我的学记|刘航宇的博客

    嵌入式软件-基于C语言小端转大端

    刘航宇
    2023-07-19 / 0 评论 / 116 阅读 / 正在检测是否收录...

    意义

    大端小端转化对嵌入式系统有意义,因为不同的处理器或者通信协议可能采用不同的字节序来存储或者传输数据。字节序是指一个多字节数据在内存中的存放顺序,它有两种主要的形式:

    大端:最高有效位(MSB)存放在最低的内存地址,最低有效位(LSB)存放在最高的内存地址。
    小端:最低有效位(LSB)存放在最低的内存地址,最高有效位(MSB)存放在最高的内存地址。
    例如,一个32位的整数0x12345678,在大端系统中,它的内存布局是:
    pC703EF.png
    而在小端系统中,它的内存布局是:
    pC70G4J.png
    如果一个嵌入式系统需要和不同字节序的设备或者网络进行交互,就需要进行字节序的转换,否则会导致数据错误或者通信失败。例如,TCP/IP协议族中的所有层都采用大端字节序来表示数据包头中的16位或32位的值,如IP地址、包长、校验和等。如果一个嵌入式系统使用小端字节序的处理器,并且想要建立一个TCP连接,就需要将IP地址等信息从小端转换为大端再发送出去,否则对方无法正确解析。

    题目

    输入一个数字n,假设它是以小端模式保存在机器的,请将其转换为大端方式保存时的值。

    示例

    输入:1
    返回值:16777216

    解答

    1.char指针,按字节替换

    /*
     * @param n int整型 
     * @return int整型
     */
    int convert(int n ) {
        // write code here
        int tmp = 0x00000000; //开辟新的int空间用于接收转化结果
        unsigned char *p = &tmp, *q = &n;
        p[0] = q[3];
        p[1] = q[2];
        p[2] = q[1];
        p[3] = q[0];
        return tmp;
    }

    2.利用union联合体共用内存空间特性,使用char数组来改变

    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
     typedef union {
        int i;
        unsigned char c[4]
     } inc_u;
    int convert(int n ) {
        // write code here
        inc_u x;  //这里也可以用新开辟空间进行置换
        x.i = n;
        //利用按位异或运算可叠加、可还原性
        x.c[0] ^= x.c[3], x.c[3] ^= x.c[0], x.c[0] ^= x.c[3]; //首尾两字节对调
        x.c[1] ^= x.c[2], x.c[2] ^= x.c[1], x.c[1] ^= x.c[2]; //中间两字节对调
        return  x.i;
        /*
        按位<<到正确位置,并用|拼装
        return (x.c[0]<<24)|(x.c[1]<<16)|(x.c[2]<<8)|x.c[3];
        */
    }

    3. 使用按位与运算保留以获取每个字节,然后按位左移到正确位置并拼接

    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
    int convert(int n ) {
        // write code here
        return  (((n & 0xff000000)>>24) | 
                 ((n & 0x00ff0000)>>8 ) |
                 ((n & 0x0000ff00)<<8 ) |
                 ((n & 0x000000ff)<<24); //按位与时,遇0清零,遇1保留
        );
    }

    4. 使用预定义好的宏函数


    所以我们这里使用 32 bit 小转大的 htonl() 宏函数来解决这个问题。

    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
    int convert(int n ) {
        // write code here
        return  htonl(n);
        );
    }
    1
    嵌入式软件-无需排序找数字
    « 上一篇 2023-07-21
    反向散射理论与ADG902电路实现
    下一篇 » 2023-07-13

    评论 (0)

    取消