C语言小知识(基于Linux)——个人笔记,不定时更新

一、switch case语法,在case中定义变量时,需要在case的有效范围内使用花括号包起来,否则会编译报错;

switch (name){

  case "zhangSan":{

    int age = 13;

    break;

  }

  case "liSi":{

    int age = 14;

    break;

  }

  default:{

    break;  

  }

}

 

二、规定结构体以n字节对齐

  在C语言结构体中,字节对齐方式默认为最大类型字节对齐;比如:

  struct Class{

    char age;

    int id;

  }class;

  这个结构体有两个成员,分别为1字节的age与4字节的id(32位编译时);实际占用了5个字节的空间,但是此时sizeof(class) == 8;因为最大的成员 id 占了4个字节,所以会以4字节对齐;age就会补充3个字节的保留位来字节对齐。

  但是在数据流的处理中,为节约资源,一般每个字节甚至每个bit都需物尽其用;所以上述结构只需要5字节有效空间;

  此时就可以使用#pragma pack(n)来进行n字节对齐;

#pragma pack(1)

  struct Class{

    char age;

    int id;

  }class;

#pragma pack()

  现在sizeof(class)就会等于5了;age只占1字节;在结构体之后加上#pragma pack()是为了限制1字节对齐的范围;#pragma pack()之后的数据结构又会以默认最大成员类型来进行字节对齐;

 

三、结构中按bit定义变量

  可以在定义变量时,变量名之后,分号;之前 加上 : n 来规定此变量占用的位数;

#pragma pack(1)

  struct ZhangSan{

    unsigned char gender_flag : 1;

    unsigned char age : 7;

    unsigned short  height : 6;

    unsigned short  weight : 6;

    unsigned short  id : 4;

  }zhangSan;

#pragma pack()

  此时gender_flag 成员与age 成员就共用一个字节的空间,height 与 weight 与 id 共用两个字节的空间;sizeof(zhangSan) == 3;

 

四、数据大小端   1.位序

    有如下结构:   

      struct ZhangSan{

        unsigned char gender_flag : 1;

        unsigned char age : 7;

      }zhangSan;

    其中 gender_flag 与 age 共用了一个字节(8bit)的空间,一个占1bit,一个占7bit;但是bit占的位置却是与平台相关的;就有可能出现如下两种排列情况

                           

C语言小知识(基于Linux)——个人笔记,不定时更新

    为了解决这种差异化,一般规定传输时的位序都为大端;即在基本类型里声明多个位域时,每个位域看做一个整体,先声明的排在前面,后声明的排在后面;在声明结构体时就可以依据本机的位序来声明位域,从而在接收数据流时能顺利的取出每一个位域。

  Linux系统中一般可以通过判断是否定义了宏 __LITTLE_ENDIAN_BITFIELD__BIG_ENDIAN_BITFIELD 来区分当前的位序定义;

  若这两个宏同时都没有定义,还可以添加 对字节序的判断来得出本机的位序定义,如下:

 

    #if  !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD)

      #if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__)

        #define __LITTLE_ENDIAN_BITFIELD

      #elif (__BYTE_ORDER__==__ORDER_BIG_ENDIAN__)

        #define __BIG_ENDIAN_BITFIELD

      #endif

    #endif

 

    struct ZhangSan{

        #if defined(__LITTLE_ENDIAN_BITFIELD)

        unsigned char gender_flag : 1;

        unsigned char age : 7;

        #elif defined(__BIG_ENDIAN_BITFIELD)

        unsigned char age : 7;
        unsigned char gender_flag : 1;

        #endif

    }zhangSan;

  

  加了如上修饰之后,即可保证接收到的大端数据流中的位域都能成功的映射到本机所定义的位域;

    2.字节序

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjjxf.html