C语言标记化结构初始化语法
2016-04-11 15:08
381 查看
C语言标记化结构初始化语法 (designated initializer),而且还是一个ISO标准。
[cpp] view plain copy
#include <stdio.h>
#include <stdlib.h>
struct operators
{
void (*read1)(char *);
void (*read2)(char *);
void (*read3)(char *);
int n;
};
void read1(char *data)
{
printf("read1: %s/n",data);
}
void read2(char *data)
{
printf("read2: %s/n",data);
}
void read3(char *data)
{
printf("read3: %s/n",data);
}
int main()
{ //传统的初始化方法
//struct operators my_op = {read1, read2, read3, 100}; //所谓的标记化结构初始化语法
struct operators my_op = {.read2 = read2,
.read1 = read1,
.read3 = read3,
.n = 100};
my_op.read1("wangyang");
my_op.read2("wangyang");
my_op.read3("wangyang");
return 0;
}
重点就在于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,};
[cpp] view plain copy
#include <stdio.h>
#include <stdlib.h>
struct operators
{
void (*read1)(char *);
void (*read2)(char *);
void (*read3)(char *);
int n;
};
void read1(char *data)
{
printf("read1: %s/n",data);
}
void read2(char *data)
{
printf("read2: %s/n",data);
}
void read3(char *data)
{
printf("read3: %s/n",data);
}
int main()
{ //传统的初始化方法
//struct operators my_op = {read1, read2, read3, 100}; //所谓的标记化结构初始化语法
struct operators my_op = {.read2 = read2,
.read1 = read1,
.read3 = read3,
.n = 100};
my_op.read1("wangyang");
my_op.read2("wangyang");
my_op.read3("wangyang");
return 0;
}
重点就在于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,};
相关文章推荐
- C语言写的俄罗斯方块
- C++实验3-个人所得税计算器
- C++中回车换行(\n\r)和换行(\r)的区别
- C++ std::pair
- [C++日常小题] 三角螺旋数组
- C++ 栈的应用
- C和C++中void*的区别
- JNI/NDK开发指南(七)——C/C++访问Java实例变量和静态变量
- JNI/NDK开发指南(六)——C/C++访问Java实例方法和静态方法
- C++的静态库与动态库
- C++作业3
- C++继承详解之二——派生类成员函数详解(函数隐藏、构造函数与兼容覆盖规则)
- 使用VS2008创建MFC ActiveX工程项目
- C语言实现队循FIFO缓冲区-《30天自制操作系统》
- C++中继承的性质
- C++用类链表模仿栈操作
- c++的头文件与源文件
- Windows下Eclipse运行C++问题Launch failed,Binary not found
- C++第3次作业
- C++继承问题(白兰花例)