Paragma & Bytes

// 非标准数据类型字节对齐原则
    // 数组  : 按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。 
    // 联合  : 按其包含的长度最大的数据类型对齐。 
    // 结构体: 结构体中每个数据类型都要对齐。

// 两种更改C编译器缺省字节对齐方式的方法 : 
    // #paragma pack(n); /* 设置 n 字节对齐 */
    // #paragma pack();  /* 设置字节对齐 */

    //__attribute__ ((aligned (n)));
    //__attribute__((packed));得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐.

    //使用实例:
    struct stu                                      struct stu
    {                               <---等同--->    {
        char sex;                   <---等同--->        char sex;
        int length;                 <---等同--->        int length;
        char name[10];              <---等同--->        char name[10];
    }__attribute__ ((aligned (1))); <---等同--->    }__attribute__ ((packed));

--------------------------------------------------------------------------------

#paragma pack(4);//设置4字节对齐

int main()
{
    unsigned char puc[4];

    struct tagPIM
    {
        unsigned char ucPim1;
        unsigned char ucData1 : 1;
        unsigned char ucData2 : 2;
        unsigned char ucData3 : 3;
    } *pstPimData;

    pstPimData = (struct tagPIM*)puc;

    memset(puc, 0, 4);

    pstPimData->ucPim1 = 1;
    pstPimData->ucData1 = 2;
    pstPimData->ucData2 = 3;
    pstPimData->ucData3 = 4;

    printf("%02X %02X %02X %02X \n", puc[0], puc[1], puc[2], puc[3]);

    return 0;
}

#paragma pack();//恢复默认字节对齐

/*
 * 打印结果 : “01 26 00 00”;
 */
 
/* 解释 : 
 * 对齐函数无论为何种都无意义,因为结构体中最大成员才1个字节,所以该成员会按自身对齐方式进行对齐。
 * 结构体强转等操作不解释,直接讲解关键处 : 
 *  结构体第1个成员 : ucPim1 占一个字节,ucPim1占据(struct tagPIM*)puc这快内存的第一个字节。puc[0] = 1;
 *  结构体后3个成员 : 占据了第二个字节的7个bit。
 *      ucData1 : 占1bit, 2的二进制为10,可将10中的一位存放在第二个字节的第1位。
 *      ucData2 : 占2bit, 3的二进制为11,正好可将其存放在第二个字节的第2、3位。
 *      ucData3 : 占3bit, 4的二进制为100,正好可将其存放在第二个字节的第4、5、6位。
 *  则第二个字节为 : 00100110,其16进制数为26。即puc[1] = 26;
 *  第三、四个字节根本就没用,所以为初始值0。
 */
原文地址:https://www.cnblogs.com/xuejianhui/p/2780483.html