zoukankan      html  css  js  c++  java
  • 标记化结构初始化语法(C语言)

      以前在看Linux代码时,就对它的结构体初始化写法感到奇怪,所有的初始化代码都写清了变量名,并且变量名前面还有一个诡异的点。最近学习Linux设备驱动,又遇到了,就查了一下,发现自己的知识果然纰漏不少,此种初始化写法并不是什么特殊的代码风格,而是所谓的C语言标记化结构初始化语法(designated initializer),而且还是一个ISO标准。

    1. #include <stdio.h>   
    2. #include <stdlib.h>   
    3. struct operators   
    4. {   
    5.      void (*read1)(char *);   
    6.      void (*read2)(char *);   
    7.      void (*read3)(char *);   
    8.      int n;   
    9. };   
    10.    
    11. void read1(char *data)   
    12. {   
    13.      printf("read1: %s/n",data);   
    14. }   
    15. void read2(char *data)   
    16. {   
    17.      printf("read2: %s/n",data);   
    18. }   
    19. void read3(char *data)   
    20. {   
    21.      printf("read3: %s/n",data);   
    22. }   
    23.    
    24. int main()   
    25. {    //传统的初始化方法   
    26.      //struct operators my_op = {read1, read2, read3, 100};    //所谓的标记化结构初始化语法   
    27.      struct operators my_op = {.read2 = read2,   
    28.                                .read1 = read1,   
    29.                                .read3 = read3,   
    30.                                .n = 100};   
    31.      my_op.read1("wangyang");   
    32.      my_op.read2("wangyang");   
    33.      my_op.read3("wangyang");   
    34.      return 0;   
    35. }  

    重点就在于main()函数中对my_op结构体的初始化语句,使用点加变量名进行初始化。用过python的人会马上感觉到这与关键字传参是多么的相似。

    那它的好处在哪里呢?我想好处有三:

        首先,标记传参不用理会参数传递的顺序,正如我上面的例子表示的那样,我是先初始化了read2,然后再初始化了read1,程序员不用记忆参数的顺序;

        其次,我们可以选择性传参,在传统C语言顺序传参中,如果你只想对第三个变量进行初始化,那么你不得不给第一个, 第二个参数进行初始化,而有时候一个变量并没有很合适的默认值,而使用标记初始化法,你可以相当自由地对你有把握的参数进行初始化;

        第三,扩展性更好,如果你要在该结构体中增加一个字段,传统方式下,为了考虑代码修改量,你最好将新添加的字段放在这个结构体的最后面,否则你将要面对大量且无趣的修改,你可能觉得放在哪里没什么关系,但是我们都习惯了,姓名下面是性别,性别下面是年龄,接着是兴趣爱好,最后是事迹描述,如果年龄放在了最后面,难道不别扭么?!

    有人提到,该种语法还有利于提高性能,木有感觉出来,我在这里就不谈这点了。

    其实,该种初始化语法并不是什么新技术,新定义,它就是ISO C99的一个标准用法,也就是说99年就有了,再说Linus也不会去赶什么时髦的,据说C Primer Plus第五版中提到了这点,不过,我没有看过该书,遗憾,我是直接投入了面向对象的怀抱。

    GCC有扩展标记化结构初始化语法,写法是下面这样的:

    struct operators my_op = {read2 : read2, read1 : read1, read3 : read3,};

    转自: http://www.hustyx.com/cplusplus/agtodXN0eWl4aWFuZ3IPCxIHQXJjaGl2ZRihigcM

  • 相关阅读:
    Microsoft Enterprise Library 5.0 系列(二) Cryptography Application Block (初级)
    Microsoft Enterprise Library 5.0 系列(五) Data Access Application Block
    Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception
    Microsoft Enterprise Library 5.0 系列(九) Policy Injection Application Block
    Microsoft Enterprise Library 5.0 系列(三) Validation Application Block (高级)
    软件研发打油诗祝大家节日快乐
    从挖井的故事中想到开发管理中最容易忽视的几个简单道理
    ITIL管理思想的执行工具发布
    管理类软件设计“渔”之演化
    20070926日下午工作流与ITILQQ群 事件管理 讨论聊天记录
  • 原文地址:https://www.cnblogs.com/myitm/p/2494811.html
Copyright © 2011-2022 走看看