为了网上传输数据,所以数据最好被拆为单位为1byte大小的数组串(unsigned char 类型恰好是这个大小),然后再进行传输,这样才能不会出现自己无法控制的情况(断网谁都控制不了了当然)。 此外,需要约定好字节序 -- 比如本日志使用的是大端(big endian),以及编码。这样拆解和重组才不会错乱。

代码的拆和拼装如下:

#include <stdio.h>
#include <string.h>

typedef unsigned short Unit16;
typedef unsigned long Unit32;
typedef unsigned char BYTE;

/**
 * 将一串4字节Uint32类型数组大端模式放入1BYTE大小的数组
 *
 * 注意说明上要求:
 * 数据流遵循大端( big endian,即高字节在前,低字在后)排序方式的网络字节顺序
 * 如果是小端的话,排列的方法是相反的
 *
 * dest 目标字符串
 * src 待处理数组
 * len 待处理数组长度
 *
 * return 
 *     :1 成功
 */
int _u32_2_byte(BYTE dest[],Unit32 src[],int len)
{
    int i,j;
    Unit32 tmp; //若为16位,此处为 Unit16
    int destSize = 4; // 4个字节
    for(i = 0; i < len ; i++)
    {
        tmp = src[i];
        for(j=3;j>=0;j--)// 3 = 字节数-1 比如4个字节,就是 3,2,1,0
        {
            dest[i*4+j] = tmp & 0xff; 
            tmp /= 256;
        }
    }
    return 1;
}

/**
 * 
 *  这个sample code 首先往里面拼装了1个Unit16类型的字符,也就是两个
 *  然后拼装了有10个元素的Unit32类型的数组
 *  注意拼第二个的时候开始位置的offset
 *
 **/
int main(int argc,char *argv[])
{
    BYTE bytes[42];
    Unit16 sample_value;
    Unit32 sample_values[10];
    int i;
    int j;
    int offset = 0;

    /**
     * 单个的转化
     *
     */  
    sample_value =  0X9001; //假如数字为 这个 , 注意,这是16进制数

    // Uint16 -> BYTE 这个是单独的
    // 发送使用这个手法
    bytes[0] = sample_value / 256;
    bytes[1] = sample_value & 0xFF;
    /**
     * int offset = 0; //开始的偏移  
     * 或者可以写成这样:
     * for(i = 1 ; i >=0 ; i--) // Unit16两个字节 所以 i = 2 - 1 (放在0~1下标下)
     * {
     *    bytes[i+offset] = sample_value & 0xFF; //取低8位
     *    sample_value /= 256 ; //1个字节8位数 = dec 256, 也可以是 sample_value /= 0xFF; 
     *  //或者 sample_value = sample_value >> 8; --一个意思
     * }
     **/
    printf("bytes: %x,%x\n",bytes[0],bytes[1]);


    // BYTE -> Uint16
    // 同样单独的, 接收使用这个手法
    sample_value = bytes[0] * 256 + bytes[1];
    /**
     * 或者写成这样
     * sample_value = 0;
     * for (i = 0 ; i < 1 ; i ++) // 2个字节,就是[0...1] , N个字节就是 [0...N-1]
     * {
     *  sample_value = sample_value << 8; 
     *  sample_value = sample_value | bytes[i+offset];
     * }
     *
     **/
    printf("value:%x\n",sample_value);


    /**
     *
     * 多个的转化
     */

    //注意offset
    offset = 2;

    /**
     *  
     *  设置初始数据
     */
    for(i = 0 ; i < 10 ; i ++) sample_values[i] = 0x90011991+i*0x2013;


    //展示修改一串数组的用法
        //注意:刚才已经放了2个进去了,所以是从第三个开始保存 <<-- offset 
    //注意bytes预留足够的空间
    _u32_2_byte(bytes+offset,sample_values,10); 

    //显示byte
    for(i = 2 ; i < 42 ; i ++)
    {
        printf("%02x ",bytes[i]);
        if(((i+3) % 4)==0) putchar('\n');
    }

    //数组拼装
    
    //清空数据
    for(i=0;i<10;i++) sample_values[i] = 0; 
    
    //  
    offset = 2;
    int toffset = 0; // temp offset
    for(i=0;i<10;i++) //sample_values 有10个元素
    {
        toffset = i * 4 + offset;
        for (j = toffset ; j < toffset + 4;  j++) // WHY 4 ?  32位4个字节
        {
            sample_values[i] <<= 8; 
            sample_values[i] = sample_values[i] | bytes[j];
        }
    }
    //显示数据
    for(i=0;i<10;i++)
        printf("0x%x\n",sample_values[i]);


    return 0;
}

Categories: Code

Yu

Ideals are like the stars: we never reach them, but like the mariners of the sea, we chart our course by them.

5 Comments

花七七 · March 26, 2013 at 23:48

Google Chrome 27.0.1450.0 Google Chrome 27.0.1450.0 Windows 8 x64 Edition Windows 8 x64 Edition

= =我高中。。。

    yu · March 27, 2013 at 07:26

    Google Chrome 25.0.1364.172 Google Chrome 25.0.1364.172 GNU/Linux x64 GNU/Linux x64

    有些小屁孩初中就玩C了,你也可以试试

Leniy · March 26, 2013 at 17:24

Google Chrome 25.0.1364.172 Google Chrome 25.0.1364.172 Windows 7 Windows 7

选修啊选修。

屏幕打字、二极管发光还有电动小马达什么的,在单片机系列课程和自己的几个项目中用过。

趁着大学的机会,多学学啊,不选修课旁听也好。这方面的很有意思

Leniy · March 26, 2013 at 14:22

Google Chrome 25.0.1364.172 Google Chrome 25.0.1364.172 Windows 7 Windows 7

看到big endian于是想到了选修嵌入式系统编写驱动时的纠结。

    yu · March 26, 2013 at 17:21

    Google Chrome 25.0.1364.172 Google Chrome 25.0.1364.172 Windows 7 x64 Edition Windows 7 x64 Edition

    把每个byte,每个bit都掌握在手里,这感觉多爽呢

    话说,我还木有学过嵌入式的驱动呢,当时就控制个屏幕打字,二极管发光,还有电动小马达转转….标准的应用程序员啊.. 囧

Leave a Reply to 花七七 Cancel reply

Your email address will not be published. Required fields are marked *