以前在看linux**時,就對它的結構體初始化寫法感到奇怪,所有的初始化**都寫清了變數名,並且變數名前面還有乙個詭異的點。最近學習linux裝置驅動,又遇到了,就查了一下,發現自己的知識果然紕漏不少,此種初始化寫法並不是什麼特殊的**風格,而是所謂的c語言標記化結構初始化語法(designated initializer),而且還是乙個iso標準。
[cpp]view plain
copy
#include
#include
struct operators
;
void read1(char *data)
void read2(char *data)
void read3(char *data)
int main()
; //所謂的標記化結構初始化語法
struct operators my_op = ;
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 = ;
**:
c的標記化結構初始化語法
在標準c中 c89 結構標準初始化是用 來實始化,在c99的版本,採用了採用可讀性更強的標記化實始化,這在linux核心和驅動很為常見。這是iso c99的用法。c primer plus第五版中相關章節 已知乙個結構,定義如下 struct book c99支援結構的指定初始化專案,其語法與陣列的...
標準C的標記化結構初始化語法
以前在看 linux 時,就對它的結構體初始化寫法感到奇怪,所有的初始化 都寫清了變數名,並且變數名前面還有乙個詭異的點。最近學習linux裝置驅動,又遇到了,就查了一下,發現自己的知識果然紕漏不少,此種初始化寫法並不是什麼特殊的 風格,而是所謂的 c語言標記化結構初始化語法 designated ...
C 標記化結構初始化語法 點運算子
已知乙個結構體 struct point c99支援結構的指定初始化專案,結構的指定初始化專案使用點運算子和成員名 而不是方括號和索引值 來標識具體的元素。如 struct point position 這個宣告採用了標記化結構初始化語法。這種寫法是值得採用的,因為它使驅動程式在結構的定義發生變化時...