鄭州北大青鳥:Linux內(nèi)核代碼 結構體初始化
今天我們鄭州北大青鳥電腦培訓給大家分享的知識點是: Linux內(nèi)核代碼結構體的初始化。這些都是我們在以后的工作學習中的必備知識積累。
在閱讀GNU/Linux內(nèi)核代碼時,我們會遇到一種特殊的結構初始化方式。該方式是某些C教材中沒有介紹過的。這種方式稱為指定初始化(designated initializer)。
下面我們看一個例子,Linux-2.6.x/drivers/usb/storage/usb.c中有這樣一個結構體初始化項目:
static struct usb_driver usb_storage_driver = {
.owner = THIS_MODULE,
.name = "usb-storage",
.probe = storage_probe,
.disconnect = storage_disconnect,
.id_table = storage_usb_ids, };
乍一看,這與我們之前學過的結構體初始化差距甚遠。其實這就是前面所說的指定初始化在Linux設備驅(qū)動程序中的一個應用,它源自ISO C99標準。以下我摘錄了C Primer Plus第五版中相關章節(jié)的內(nèi)容,從而就可以很好的理解2.6版內(nèi)核采用這種方式的優(yōu)勢就在于由此初始化不必嚴格按照定義時的順序。這帶來了極大的靈活性,其更大的益處還有待大家在開發(fā)中結合自身的應用慢慢體會。
已知一個結構,定義如下 struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value; };
C99支持結構的指定初始化項目,其語法與數(shù)組的指定初始化項目近似。只是,結構的指定初始化項目使用點運算符和成員名(而不是方括號和索引值)來標識具體的元素。例如,只初始化book結構的成員value,可以這樣做:
struct book surprise = { .value = 10.99 };
可以按照任意的順序使用指定初始化項目:
struct book gift = { .value = 25.99, .author = "James Broadfool", .title = "Rue for the Toad"};
正像數(shù)組一樣,跟在一個指定初始化項目之后的常規(guī)初始化項目為跟在指定成員后的成員提供了初始值。另外,對特定成員的最后一次賦值是它實際獲得的值。例如,考慮下列聲明:
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節(jié)Ininialization。
特定的初始化
標準C89需要初始化語句的元素以固定的順序出現(xiàn),和被初始化的數(shù)組或結構體中的元素順序一樣。在ISO C99中,你可以按任何順序給出這些元素,指明它們對應的數(shù)組的下標或結構體的成員名,并且GNU C也把這作為C89模式下的一個擴展。這個擴展沒有在GNU C++中實現(xiàn)。為了指定一個數(shù)組下標,在元素值的前面寫上“[index] =”。比如: int a[6] = { [4] = 29, [2] = 15 };
相當于: int a[6] = { 0, 0, 15, 0, 29, 0 };
下標值必須是常量表達式,即使被初始化的數(shù)組是自動的。一個可替代這的語法是在元素值前面寫上“.[index]”,沒有“=”,但從GCC 2.5開始就不再被使用,但GCC仍然接受。 為了把一系列的元素初始化為相同的值,寫為“[first ... last] = value”。這是一個GNU擴展。比如: int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
如果其中的值有副作用,這個副作用將只發(fā)生一次,而不是范圍內(nèi)的每次初始化一次。注意,數(shù)組的長度是指定的最大值加一。在結構體的初始化語句中,在元素值的前面用“.fieldname = ”指定要初始化的成員名。例如,給定下面的結構體, struct point { int x, y; };
和下面的初始化, struct point p = { .y = yvalue, .x = xvalue };
等價于: struct point p = { xvalue, yvalue };
另一有相同含義的語法是“.fieldname:”,不過從GCC 2.5開始廢除了,就像這里所示: struct point p = { y: yvalue, x: xvalue };
“[index]”或“.fieldname”就是指示符。在初始化共同體時,你也可以使用一個指示符(或不再使用的冒號語法),來指定共同體的哪個元素應該使用。比如: union foo { int i; double d; }; union foo f = { .d = 4 };
將會使用第二個元素把4轉(zhuǎn)換成一個double類型來在共同體存放。相反,把4轉(zhuǎn)換成union foo類型將會把它作為整數(shù)i存入共同體,既然它是一個整數(shù)。(參考5.24節(jié)向共同體類型轉(zhuǎn)換。)你可以把這種命名元素的技術和連續(xù)元素的普通C初始化結合起來。每個沒有指示符的初始化元素應用于數(shù)組或結構體中的下一個連續(xù)的元素。比如, int a[6] = { [1] = v1, v2, [4] = v4 };
等價于 int a[6] = { 0, v1, v2, 0, v4, 0 };
當下標是字符或者屬于enum類型時,標識數(shù)組初始化語句的元素特別有用。例如: int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\h'] = 1, ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };
你也可以在“=”前面寫上一系列的“.fieldname”和“[index]”指示符來指定一個要初始化的嵌套的子對象;這個列表是相對于和最近的花括號對一致的子對象。比如,用上面的struct point聲明: struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };
如果同一個成員被初始化多次,它將從最后一次初始化中取值。如果任何這樣的覆蓋初始化有副作用,副作用發(fā)生與否是非指定的。目前,gcc會舍棄它們并產(chǎn)生一個警告。
以上就是詳細的介紹了結構體初始化的具體操作,大家回去在實際聯(lián)系下,加深理解記憶。想要了解更多有關數(shù)據(jù)庫知識的請查看:http://i3061.cn/html/jsjl/sjk/ 本文源自:http://i3061.cn 轉(zhuǎn)載請注明出處!
本文由站河南北大青鳥校區(qū)整編而成,如需了解更多IT資訊類的文章、新聞、課程和學習技巧、就業(yè)案例、招生詳情等問題,可以對在線咨詢老師進行一對一問答!
推薦資訊
- 鄭州北大青鳥翔天信鴿5月第三周就... 2020-05-25
- 雅虎旗下45.3萬用戶信息被曝光,... 2012-10-13
- 初中畢業(yè)的學生學什么技術最好?... 2013-11-22
- 鄭州北大青鳥翔天信鴿T85班項目啟... 2019-08-14
- 景安官網(wǎng)被黑,網(wǎng)絡安全是通病... 2013-02-01
熱點資訊
- 學習SQL數(shù)據(jù)庫有哪些方法?... 2018-09-07
- 河南IT培訓:SQLSERVER2000T-SQL的... 2018-09-07
- 使用access數(shù)據(jù)庫有哪些好處呢?... 2018-09-07
- 網(wǎng)站數(shù)據(jù)庫老是被入侵該怎么辦?... 2018-09-07
- 半小時讓你快速MySQL 入門... 2018-09-07