GNU C标记化结构初始化语法_第1页
GNU C标记化结构初始化语法_第2页
GNU C标记化结构初始化语法_第3页
GNU C标记化结构初始化语法_第4页
GNU C标记化结构初始化语法_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

GNUC标记化结构初始化语法---结构体成员前加小数点对结构体[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

a{int

b;int

c;}有几种初始化方式:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

aa1={.b=1,.c=2};或者[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

aa1={b:1,c:2}或者[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

aa1={1,2};内核喜欢用第一种,使用第一种和第二种时,成员初始化顺序可变。标记化结构初始化语法在Linux2.6内核中对结构体的定义形式发生了变化,不再支持原来的定义形式。[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?1

static

struct

tty_operationsuart_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#ifdefCONFIG_PROC_FS22.read_proc=uart_read_proc,

//proc入口读函数23#endif24.tiocmget=uart_tiocmget,25.tiocmset=uart_tiocmset,26};

这个声明采用了标记化结构初始化语法。这种写法是值得采用的,因为它使驱动程序在结构的定义发生变化时更具有可移植性,并且使代码更加紧凑且易读。标记化的初始化方法允许对结构成员进行重新排列。在某些场合下,将频繁被访问的成员放在相同的硬件缓存行上,将大大提高性能。---LLD3标记化结构初始化语法是ISOC99的用法CPrimerPlus第五版相关章节:已知一个结构,定义如下:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

book{char

title[MAXTITL];char

author[MAXAUTL];float

value;};C99支持结构的指定初始化项目,其语法与数组的指定初始化项目近似。只是,结构的指定初始化项目使用点运算符和成员名(而不是方括号和索引值)来标识具体的元素。例如,只初始化book结构的成员vlaue,可以这样做:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

booksurprise={.value=10.99};可以按照任意的顺序使用指定初始化项目:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

bookgift={.value=25.99,.author=

"JamesBroadfool",.title=

"RuefortheToad"};正像数组一样,跟在一个指定初始化项目之后的常规初始化项目为跟在指定成员后的成员提供了初始值。另外,对特定成员的最后一次赋值是它实际获得的值。例如,考虑如下声明:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

bookgift={.value=18.90,.author=

"Philionnapestle",0.25};

这将把值0.25赋给成员vlaue,因为它在结构声明中紧跟在author成员之后。新的值0.25代替了早先的赋值18.90。有关designatedinitializer的进一步信息可以参考C99标准的6.7.8节Initialization。代码举例:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?#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(){

//传统的初始化方法//structoperatorsmy_op={read1,read2,read3,100};//所谓的标记化结构初始化语法struct

operatorsmy_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语言顺序传参中,如果你只想对第三个变量进行初始化,那么你不得不给第一个,第二个参数进行初始化,而有时候一个变量并没有和合适的默认值,而使用标记初始化法,你可以相当自由地对你有把握的参数进行初始化;还有,扩展性更好,如果你要在该结构体中增加一个字段,传统方式下,为了考虑代码修改量,你最好将新添加的字段放在这个结构体的最后面,否则你将要面对大量而且无趣的修改,你可能觉得放在哪里没什么关系,但是我们都习惯了,姓名下面是性别,性别下面是年龄,接着是兴趣爱好,最后是事迹描述,如果年龄放在了最后面,难道不别扭么?上面的例程为什么在VC++6.0中编译不同通过呢???在bluedrum的空间中有篇名为《C版本差异---结构处理差别》的第3点中讲到:在标准C中(C89),结构标准初始化是用{}来初始化,在C99的版本,采用了可读性更强的标记化初始化,这在Linux内核和驱动中很为常见。其中VC++6.0只支持C89初始化,GCC支持自己标记化或自己扩展初始化。[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

name_str{int

data;char

name[120];int

num;};/*标记式初始化,注意顺序不同,并可缺省*/struct

name_strstr={.num=100;.name=

"hxy";};/*C89初始化*/struct

name_strstr2={100,"AndrewHuang",-2};/*gcc扩展初始化*/struct

name_strstr3={name:"bluedrum";data:-1}}个人想编译以上代码,想下个C99编译器,在百度搜索C99编译器,解决时间:2009-07-1021:54回答是“VC++2005支持的是C89而不是C99这点可以在一次对VS2005的负责人的采访中看出来,他解释了为什么VS2005支持C89而不支持C99目前完全支持C99标准的编译器还不存在支持部分C99标准的编译器也不多做的最好的是GCC”

特定的初始化标准C89需要初始化语句的元素以固定的顺序出现,和被初始化的数组或结构体中的元素顺序一样。在ISOC99中,你可以按任何顺序给出这些元素,指明它们对应的数组的下表或结构体的成员名,并且GNUC也把这作为C89模式下的一个扩展。这个扩展没有在GNUC++中实现。为了指定一个数组下标,在元素值的前面写上"[index]="。比如:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?int

a[6]={[4]=29,[2]=15};相当于:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?int

a[6]={0,0,15,0,29,0};下标值必须是常量表达式,即使被初始化的数组是自动的。一个可替代的语法是在元素前面写上".[index]",没有"=",但从GCC2.5开始就不再被使用,但GCC仍然接受。为了把一系列的元素初始化化为相同的值,写为"[first......last]=value"。这是一个GNU扩展。比如:[html]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?intwidths[]={[0...9]=1,[10...99]=2,[100]=3};如果其中的值有副作用,这个副作用将只发生一次,而不是范围内的每次初始化一次。注意:数组的长度是指定的最大值加一。在结构体的初始化语法中,在元素值的前面用".fieldname="指定要初始化的成员名。例如,给定下面的结构体:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

point{

int

x,y;};和下面的初始化:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

pointp={.y=yvalue,.x=xvalue};等价于:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

pointp={xvalue,yvalue};另一有相同含义的语法是“.fieldname:”,不过从GCC2.5开始废除了,就像这里所示:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct

pointp={y:yvalue,x:xvalue};

"[index]"或".fieldname"就是指示符。在初始化共同体时,你也可以使用一个指示符(或不再使用的冒号语法),来指定共同体的哪个元素应该使用。比如:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?union

foo{

int

i;

double

d;};union

foof={.d=4};将会使用第二个元素把4转换成一个double类型来在共同体存放。相反,把4转换成unionfoo类型将会把它作为整数i存入共同体,既然它是一个整数。(参考5.24节共同体类型转换)你可以把这种命名元素的技术和连续元素的普通C初始化结合起来。每个没有指示符的初始化元素应用于数组或结构体中的下一个连续的元素。比如:[cpp]

\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?int

a[6]={[1]=v1,v2,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论