GNU C標記化結構初始化語法_第1頁
GNU C標記化結構初始化語法_第2頁
GNU C標記化結構初始化語法_第3頁
GNU C標記化結構初始化語法_第4頁
GNU C標記化結構初始化語法_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

GNUC標記化結構初始化語法---結構體成員前加小數(shù)點對結構體[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內核中對結構體的定義形式發(fā)生了變化,不再支持原來的定義形式。[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,//串口發(fā)送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入口讀函數(shù)23#endif24.tiocmget=uart_tiocmget,25.tiocmset=uart_tiocmset,26};

這個聲明采用了標記化結構初始化語法。這種寫法是值得采用的,因為它使驅動程序在結構的定義發(fā)生變化時更具有可移植性,并且使代碼更加緊湊且易讀。標記化的初始化方法允許對結構成員進行重新排列。在某些場合下,將頻繁被訪問的成員放在相同的硬件緩存行上,將大大提高性能。---LLD3標記化結構初始化語法是ISOC99的用法CPrimerPlus第五版相關章節(jié):已知一個結構,定義如下:[cpp]

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

book{char

title[MAXTITL];char

author[MAXAUTL];float

value;};C99支持結構的指定初始化項目,其語法與數(shù)組的指定初始化項目近似。只是,結構的指定初始化項目使用點運算符和成員名(而不是方括號和索引值)來標識具體的元素。例如,只初始化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"};正像數(shù)組一樣,跟在一個指定初始化項目之后的常規(guī)初始化項目為跟在指定成員后的成員提供了初始值。另外,對特定成員的最后一次賦值是它實際獲得的值。例如,考慮如下聲明:[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節(jié)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(){

//傳統(tǒng)的初始化方法//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()函數(shù)中對my_op結構體的初始化語句,使用點加變量名進行初始化。用過Python的人會馬上感覺這與關鍵字傳參是多么的相似。那它好處在哪里呢?我想好處有三。首先,標記傳參不用理會參數(shù)傳遞的順序,正如我上面的例子里表示的那樣,我是先初始化了read2,然后再初始化了read1,程序員不用記憶參數(shù)的順序;再者,我們可以選擇性傳參,在傳統(tǒng)C語言順序傳參中,如果你只想對第三個變量進行初始化,那么你不得不給第一個,第二個參數(shù)進行初始化,而有時候一個變量并沒有和合適的默認值,而使用標記初始化法,你可以相當自由地對你有把握的參數(shù)進行初始化;還有,擴展性更好,如果你要在該結構體中增加一個字段,傳統(tǒng)方式下,為了考慮代碼修改量,你最好將新添加的字段放在這個結構體的最后面,否則你將要面對大量而且無趣的修改,你可能覺得放在哪里沒什么關系,但是我們都習慣了,姓名下面是性別,性別下面是年齡,接著是興趣愛好,最后是事跡描述,如果年齡放在了最后面,難道不別扭么?上面的例程為什么在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需要初始化語句的元素以固定的順序出現(xiàn),和被初始化的數(shù)組或結構體中的元素順序一樣。在ISOC99中,你可以按任何順序給出這些元素,指明它們對應的數(shù)組的下表或結構體的成員名,并且GNUC也把這作為C89模式下的一個擴展。這個擴展沒有在GNUC++中實現(xiàn)。為了指定一個數(shù)組下標,在元素值的前面寫上"[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};下標值必須是常量表達式,即使被初始化的數(shù)組是自動的。一個可替代的語法是在元素前面寫上".[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};如果其中的值有副作用,這個副作用將只發(fā)生一次,而不是范圍內的每次初始化一次。注意:數(shù)組的長度是指定的最大值加一。在結構體的初始化語法中,在元素值的前面用".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類型將會把它作為整數(shù)i存入共同體,既然它是一個整數(shù)。(參考5.24節(jié)共同體類型轉換)你可以把這種命名元素的技術和連續(xù)元素的普通C初始化結合起來。每個沒有指示符的初始化元素應用于數(shù)組或結構體中的下一個連續(xù)的元素。比如:[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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論