美文网首页
C语言少用but实用知识 & C语言难点

C语言少用but实用知识 & C语言难点

作者: Neucrack | 来源:发表于2016-12-26 23:05 被阅读105次

    结构体初始化

    typedef struct
    {
        uint8_t sck;
        uint8_t miso;
        uint8_t mosi;
        uint8_t cs;
        uint8_t cpol;
        uint8_t cpha;
    }spi_simulate_config_typedef;
    spi_simulate_config_typedef spi = {
            .cpol = 0,
            .cpha = 0
    }
    spi_simulate_config_typedef spi2 = {
            cpol:   0,
            cpha:  0
    }
    
    

    结构体最后一个成员的用法

    typedef struct{
      int a;
      float b;
      int *c;
    } a_t;
    
    typedef struct{
      int a;
      float b;
      int c[];
    } a_t;
    
    typedef struct{
      int a;
      float b;
      int c[0];
    } a_t;
    

    三者等效,可以使用如下方式来分配空间

    a_t*p = malloc(sizeof(a_t) + sizeof(int)*8);
    

    数组的初始化方式

    
    #include "stdio.h"
    enum{ENUM1=0,ENUM2,ENUM3};
    
    int main() {
        char array0[3]={1,2,3};
        char array1[3]={
            [0] = 1,
            [1] = 2,
            [2] = 3    
        };
        char array2[3]={
            [ENUM1] = 1,
            [ENUM2] = 2,
            [ENUM3] = 3
        };
    
        for(int i=0;i<3;++i)
            printf("%d\n",array0[i]);
        for(int i=0;i<3;++i)
            printf("%d\n",array1[i]);
        for(int i=0;i<3;++i)
            printf("%d\n",array2[i]);
        return 0;
    }
    

    另外,你可能会遇到一种奇怪的写法,建议使用:

        char array2[4]={
    #define NUMBER0  (10)
            ENUM1,
            ENUM2,
            ENUM3
        };
    

    可控储存的结构体,占位符的使用

    typedef struct
    {
        enum
        {
            TEST_FRAME_VER_0 = 0,
            TEST_FRAME_VER_MAX,
        } version : 8;
        uint8_t gateway : 1;
        uint8_t fragment : 1;
        enum
        {
            TEST_FRAME_TYPE_DISCOVER = 0,
            TEST_FRAME_TYPE_LINK = 1,
            TEST_FRAME_TYPE_DATA = 2,
            TEST_FRAME_TYPE_MAX,
        } type : 2;
        enum
        {
            TEST_FRAME_SUBTYPE_DISCOVER_REQ = 0,
            TEST_FRAME_SUBTYPE_DISCOVER_RESP = 1,
            TEST_FRAME_SUBTYPE_DISCOVER_MAX
        } subtype : 4;
        uint8_t resv : 8;
        uint8_t dest_length_type : 4;
        uint8_t src_length_type : 4;
        void * raw;
    } __attribute__((aligned(1),packed)) test_frame_t;
    
    uint8_t frame[4];
    test_frame_t test_frame;
    memcpy(frame,test_frame,4);
    

    C99中数组定义

    C99开始可以使用变量来定义数组长度
    eg:

    int num=10;
    int array[num];
    

    keil MDK5也可以使用这个哦,不过在编译选项里面加一个--gnu参数就可以了

    keil gnu parameter

    强制转换问题

    我们常常使用各种指针指过去指过来、强制转换过去转换过来、飞过去飞过来~~~然后就飞不见了!!!!!
    案例1:强制转换导致越界访问,这种情况下如果编译器检查不严格很难发现,如果检查严格,会出现非法访问地址错误

    #include "stdio.h"
    #include "stdint.h"
    
    int main()
    {
        uint8_t  a = 10;
        void* p = (void*)&a;
        uint16_t b = (uint16_t)(*((uint8_t*)p));
        uint16_t c = *((uint16_t*)&p);
        printf("a=%d,b=%d,c=%d\n",a,b,c);
    }
    

    正确的是b的写法,c是错误的


    输出结果

    一种函数的神奇写法

    int plus (a,b)
    int a;
    int b;
    {
      return a+b;
    }
    

    在一些老版程序中会出现,现在不建议这样用了,但是有可能会遇到别人这样写!!

    相关文章

      网友评论

          本文标题:C语言少用but实用知识 & C语言难点

          本文链接:https://www.haomeiwen.com/subject/qzjgmttx.html