标记化结构初始化语法(C语言)

本文介绍C99标准中的标记化结构体初始化语法,这种语法允许开发者指定成员变量进行初始化,提高了代码的可读性和维护性。文章通过实例展示了如何使用此特性,并比较了其与传统初始化方法的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以前在看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. void read1(char *data)
  11. {
  12. printf("read1: %s/n",data);
  13. }
  14. void read2(char *data)
  15. {
  16. printf("read2: %s/n",data);
  17. }
  18. void read3(char *data)
  19. {
  20. printf("read3: %s/n",data);
  21. }
  22. int main()
  23. { //传统的初始化方法
  24. //struct operators my_op = {read1, read2, read3, 100}; //所谓的标记化结构初始化语法
  25. struct operators my_op = {.read2 = read2,
  26. .read1 = read1,
  27. .read3 = read3,
  28. .n = 100};
  29. my_op.read1("wangyang");
  30. my_op.read2("wangyang");
  31. my_op.read3("wangyang");
  32. return 0;
  33. }

重点就在于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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值