标记化结构初始化语法 在结构体成员前加上小数点 如 “.open .write .close ”C99编译器 .
今天在看串口驱动(四)的时候 有这样一个结构体初始化 我很不理解 如下:
static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
14 [0] = {
15 .port = {
16 .lock = SPIN_LOCK_UNLOCKED,
17 .iotype = UPIO_MEM,
18 .irq = IRQ_S3CUART_RX0,
19 .uartclk = 0,
20 .fifosize = 16,
21 .ops = &s3c24xx_serial_ops,
22 .flags = UPF_BOOT_AUTOCONF,
23 .line = 0,//端口索引:0
24 }
25 },
26 [1] = {
27 .port = {
28 .lock = SPIN_LOCK_UNLOCKED,
29 .iotype = UPIO_MEM,
30 .irq = IRQ_S3CUART_RX1,
31 .uartclk = 0,
32 .fifosize = 16,
33 .ops = &s3c24xx_serial_ops,
34 .flags = UPF_BOOT_AUTOCONF,
35 .line = 1, //端口索引:1
36 }
37 },
38 #if NR_PORTS > 2
39
40 [2] = {
41 .port = {
42 .lock = SPIN_LOCK_UNLOCKED,
43 .iotype = UPIO_MEM,
44 .irq = IRQ_S3CUART_RX2,
45 .uartclk = 0,
46 .fifosize = 16,
47 .ops = &s3c24xx_serial_ops,
48 .flags = UPF_BOOT_AUTOCONF,
49 .line = 2, //端口索引:2
50 }
51 }
52 #endif
53 };
为什么会在成员函数前加上小数点呢? 我在网上游荡了好一阵找到了“Felix 的博客”,内容如下:
标记化结构初始化语法
在Linux2.6内核中对结构体的定义形式发生了变化,不再支持原来的定义形式。
1 static struct tty_operations uart_ops =
2 {
3 .open = uart_open,//串口打开
4 .close = uart_close,//串口关闭
5 .write = uart_write,//串口发送
6 .put_char = uart_put_char,//...
7 .flush_chars = uart_flush_chars,
8 .write_room = uart_write_room,
9 .chars_in_buffer= uart_chars_in_buffer,
10 .flush_buffer = uart_flush_buffer,
11 .ioctl = uart_ioctl,
12 .throttle = uart_throttle,
13 .unthrottle = uart_unthrottle,
14 .send_xchar = uart_send_xchar,
15 .set_termios = uart_set_termios,
16 .stop = uart_stop,
17 .start = uart_start,
18 .hangup = uart_hangup,
19 .break_ctl = uart_break_ctl,
20 .wait_until_sent= uart_wait_until_sent,
21 #ifdef CONFIG_PROC_FS
22 .read_proc = uart_read_proc, //proc入口读函数
23 #endif
24 .tiocmget = uart_tiocmget,
25 .tiocmset = uart_tiocmset,
26 };
这个声明采用了标记化结构初始化语法。这种写法是值得采用的,因为它使驱动程序在结构的定义发生变化时更具有可移植性,并且使代码更加紧凑且易读。标记化的初始化方法允许对结构成员进行重新排列。在某些场合下,将频繁被访问的成员放在相同的硬件缓存行上,将大大提高性能。
----LLD3
查到这里 我发现一个关键字 “这个声明采用了标记化结构初始化语法” 我就搜索“标记化结构初始化语法” 内容如下:
这是ISO C99的用法
C Primer Plus第五版中相关章节:
已知一个结构,定义如下
struct book
{
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
C99支持结构的指定初始化项目,其语法与数组的指定初始化项目近似。只是,结构的指定初始化项目使用点运算符和成员名(而不是方括号和索引值)来标识具体的元素。例如,只初始化book结构的成员value,可以这样做:
struct book surprise = { .value = 10.99 };
可以按照任意的顺序使用指定初始化项目:
struct book gift = {
.value = 25.99,
.author = "James Broadfool",
.title = "Rue for the Toad"
};
正像数组一样,跟在一个指定初始化项目之后的常规初始化项目为跟在指定成员后的成员提供了初始值。另外,对特定成员的最后一次赋值是它实际获得的值。例如,考虑下列声明:
struct book gift = {
.value = 18.90,
.author = "Philionna pestle",
0.25
};
这将把值0.25赋给成员value,因为它在结构声明中紧跟在author成员之后。新的值0.25代替了早先的赋值18.90。
有关designated initializer的进一步信息可以参考c99标准的6.7.8节Ininialization。
在忆向 的博客中写到:
C语言标记化结构初始化语法
以前在看Linux代码时,就对它的结构体初始化写法感到奇怪,所有的初始化代码都写清了变量名,并且变量名前面还有一个诡异的点。最近学习Linux设备驱动,又遇到了,就查了一下,发现自己的知识果然纰漏不少,此种初始化写法并不是什么特殊的代码风格,而是所谓的C语言标记化结构初始化语法(designated initializer),而且还是一个ISO标准。在此我就小小科普一下。
代码举例如下:
重点就在于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,};
上面的例程为什么在vc++6.0中编译怎么通不过呢???
在 bluedrum 的空间中有篇 名为《C版本差异--- 结构处理差别》的第3点中讲到:
3、标记化结构初始化语法
在标准C中(C89(结构标准初始化是用{}来实始化,在C99的版本,采用了采用可读性更强的标记化实始化,这在LINUX内核和驱动很为常见。
其中VC++ 6.0只支持C89初始化,GCC支持自己标记化或自己扩展初始化。这种初始化采用 .name = value.这样不需要按顺序排序,方便调整实义,在大结构最大程度防止错位的和调整定义带来不便
/* C89 初始化 */ struct name_str str2 = /* gcc 扩展初始化 */ |
个人想编译 以上代码 想下个C99编译器 在百度搜索 C99编译器 解决时间:2009-07-10 21:54 回答是
“VC++ 2005支持的是C89
而不是C99
这点可以在一次对VS2005的负责人的采访中看出来
他解释了为什么VS2005支持C89 而不支持C99
目前完全支持C99标准的编译器还不存在
支持部分C99标准的编译器也不多
做的最好的是GCC”
查到这里 终于明白这是个怎么回事了
截稿了
原文:标记化结构初始化语法 在结构体成员前加上小数点 如 “.open .write .close ”C99编译器
标记化结构初始化语法 在结构体成员前加上小数点 如 “.open .write .close ”C99编译器 .的更多相关文章
- C语言标记化结构初始化语法
C语言标记化结构初始化语法 (designated initializer),而且还是一个ISO标准. #include <stdio.h> #include <stdlib.h&g ...
- 标准C的标记化结构初始化语法
1 struct file_operations { 2 struct module *owner; 3 loff_t (*llseek) (struct file * ...
- C基础--结构体成员初始化方式
之前在linux内核代码中看到结构体成员成员初始化使用类似于.owner = THIS_MODULE, 不太见过,于是搜了个博客,分享下: 转自:http://www.cnblogs.com/Anke ...
- C++结构体成员列表初始化
C++关于struct和class的区别,可以看上一篇文章:c ++ class和struct[转] 结构体成员列表初始化,来个例子: #include <iostream> #inclu ...
- C语言语法教程-结构体
2018-09-30 结构体中成员变量地址是连续的,结构体用于描述记录. Create a struct //---------------------------- //struct1.c //创建 ...
- Delphi XE5教程6:单元的结构和语法
内容源自Delphi XE5 UPDATE 2官方帮助<Delphi Reference>,本人水平有限,欢迎各位高人修正相关错误! 也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者 ...
- 使用XML的五种场合,XML基本规则,XML的术语,结构与语法
在很多研讨会和培训班上我遇到过许多人,他们还不明白为什么要使用XML也不知道如何 在他们的应用中使用XML.一些来自诸如Gartner公司的报告建议说,商业公司不能再做 局外人了,不能对XML置之不理 ...
- FFmpeg源代码简单分析:结构体成员管理系统-AVClass
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- Delphi XE5教程5:程序的结构和语法
内容源自Delphi XE5 UPDATE 2官方帮助<Delphi Reference>,本人水平有限,欢迎各位高人修正相关错误! 也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者 ...
随机推荐
- 谷歌开发的draco格式文件将obj文件压缩成drc文件后将大大减小文件大小(threejs加载有mtl文件的drc文件)
问题描述:当前threejs是92版本 但是当前版本还没有能够直接加载带贴图文件的drc格式的loader: 解决办法:先加载mtl文件将obj文件分解(按照mtl文件内材质贴图信息进行分解)再将分解 ...
- Linux定时任务Crontab使用 提示no crontab for root
使用命令查询crontab 任务时,一直提示:no crontab for root .查看了一些资料,说是crontab在初始时,设置了一次编辑方式,所以试了一下crontab -e的方式编辑,即在 ...
- memcached 一致性hash原理
memcache 是一个分布式的缓存系统,但是本身没有提供集群功能,在大型应用的情况下容易成为瓶颈.但是客户端这个时候可以自由扩展,分两阶段实现.第一阶段:key 要先根据一定的算法映射到一台memc ...
- div同时使用两个class
<p class="con hide">...</p> 1:使用空格分割 2:这个段落将同时应用这两个 class 制定的规则 3:如果二者有重叠,后者覆盖 ...
- Spring Boot REST(二)源码分析
Spring Boot REST(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) SpringBoot RE ...
- AUC和ROC
https://www.cnblogs.com/gatherstars/p/6084696.html
- js实现环形菜单效果
点击中间的圆点,会弹出环形菜单,效果图: 代码: <!DOCTYPE html> <html> <head> <meta charset="UTF- ...
- RNA-Seq数据去接头(Adapter)
1.adapter是一段短的序列已知的核酸链,用于链接序列未知的目标测序片段. 2.barcode,也称为index,是一段很短的寡居核酸链,用于在多个样品混合测序时,标记不同的样品. 3.inser ...
- 记录一次JVM调优【GC日志的分析】
首先查看服务器版本默认信息: 修改tomcat/bin/catalina.sh,在最顶端加入JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -Xloggc ...
- (转)用webbrowser做的网站登陆程序,如何获取cookie并且保存在程序中 (IE8有效) ,用途嘛,你懂的。
今天帮朋友做了个工具,用webbrowser做的,用户使用用户名密码登陆网站后,需要在后台下载和分析一些页面. 分析页面使用的是htmlparser .net版 里面唯一需要解决的问题是,登陆后的co ...