引入
我們用兩個(gè)簡(jiǎn)單(?)的問(wèn)題作為引入,當(dāng)然我們整篇文章都會(huì)圍繞這兩個(gè)問(wèn)題:
- 下面四種類(lèi)型聲明等價(jià)嗎?
int* i;int *i;int * i;int*i;
- 下面四種類(lèi)型聲明中,
j擁有哪一個(gè)數(shù)據(jù)類(lèi)型?是int或者int的指針?int* i, j;int *i, j;int * i, j;int*i, j;
當(dāng)然看到這里,如果你已經(jīng)有非常自信的答案,你當(dāng)然可以無(wú)視這一篇文章后面的部分。
第一個(gè)問(wèn)題
第一個(gè)問(wèn)題的答案是: 四種指針的類(lèi)型聲明的等價(jià)的。
很好,既然我們知道它們等價(jià),或許已經(jīng)足夠了。但是我們數(shù)據(jù)庫(kù)教授總是在課上提醒大家,知道區(qū)別并不足夠,還需要問(wèn)自己其中的哪一個(gè)更好,什么情況下用哪一種方式。
哪一種寫(xiě)法更好呢?
C++之父在他的一篇文章:Bjarne Stroustrup's C++ Style and Technique FAQ中提到:
The choice between
int* p;andint *p;is not about right and wrong, but about style and emphasis. C emphasized expressions; declarations were often considered little more than a necessary evil. C++, on the other hand, has a heavy emphasis on types.A
typical C programmerwritesint *p;and explains it*p is what is the intemphasizing syntax, and may point to the C (and C++) declaration grammar to argue for the correctness of the style. Indeed, the * binds to the name p in the grammar.A
typical C++ programmerwritesint* p;and explains itp is a pointer to an intemphasizing type. Indeed the type of p is int*. I clearly prefer that emphasis and see it as important for using the more advanced parts of C++ well.
</br>
Linux kernel coding style中的習(xí)慣規(guī)則是:
When declaring pointer data or a function that returns a pointer type, the
preferred use of*is adjacent to the data name or function name and not
adjacent to the type name. Examples:
char *linux_banner;
unsigned long long memparse(char *ptr, char **retptr);
char *match_strdup(substring_t *s);
某種程度上它也擬合了C++之父Bjarne Stroustrup的想法。
第二個(gè)問(wèn)題
第二個(gè)問(wèn)題的答案是: j的類(lèi)型是int。
當(dāng)然這問(wèn)題是編譯器的行為,或者語(yǔ)言自身的規(guī)定,很難去闡述行為或規(guī)定背后的為什么。
我們繼續(xù)看Bjarne Stroustrup's C++ Style and Technique FAQ,這部分緊接問(wèn)題一中對(duì)應(yīng)的引用:
The critical confusion comes (only) when people try to declare several pointers with a single declaration:
int* p, p1; // probable error: p1 is not an int*
Placing the * closer to the name does not make this kind of error significantly less likely.
int *p, p1; // probable error?
Declaring one name per declaration minimizes the problem - in particular when we initialize the variables. People are far less likely to write:
int* p = &i;
int p1 = p; // error: int initialized by int*
And if they do, the compiler will complain.
從他的這一部分文字中,很容易可以看出我們這文章中的第一個(gè)問(wèn)題和第二個(gè)問(wèn)題完全是緊密結(jié)合。第二個(gè)問(wèn)題中的四種寫(xiě)法的確是等價(jià)的,但是無(wú)一能讓人輕松理解。從他的這一個(gè)觀(guān)點(diǎn)中:Declaring one name per declaration minimizes the problem,我們可以對(duì)這篇文章下一個(gè)主觀(guān)的結(jié)論。
結(jié)論
針對(duì)第二個(gè)問(wèn)題,對(duì)我來(lái)說(shuō)最好的方式是:
int* i;
int j;
這種寫(xiě)法更清晰,也是多個(gè)Stackoverflow提問(wèn)中所提倡的。
最后一點(diǎn)聲明是,無(wú)論怎么寫(xiě)對(duì)編譯器來(lái)說(shuō)其實(shí)都無(wú)所謂,它只是客觀(guān)地去檢查能否通過(guò)編譯然后生成對(duì)應(yīng)的代碼。這些等價(jià)寫(xiě)法對(duì)應(yīng)的匯編語(yǔ)言甚至一樣,對(duì)應(yīng)的程序的效能自然也是一樣。這些寫(xiě)法迷惑的只是人類(lèi)(編程的人和瀏覽代碼的人),我們需要有一個(gè)清晰的方式,保證自己不出錯(cuò)同時(shí)也讓代碼瀏覽者能快速理解。
</br>
</br>
引用和推薦閱讀:
http://www.stroustrup.com/bs_faq2.html#whitespace
https://www.kernel.org/doc/Documentation/process/coding-style.rst
https://softwareengineering.stackexchange.com/questions/7305/int-i-or-int-i-or-int-i
https://stackoverflow.com/questions/6990726/correct-way-of-declaring-pointer-variables-in-c-c
https://stackoverflow.com/questions/13894228/where-to-put-the-star-in-c-and-c-pointer-notation
https://stackoverflow.com/questions/2704167/type-declaration-pointer-asterisk-position
https://stackoverflow.com/questions/180401/placement-of-the-asterisk-in-pointer-declarations
(Stackoverflow統(tǒng)統(tǒng)是在問(wèn)同一件問(wèn)題)
該文章遵循創(chuàng)作共用版權(quán)協(xié)議 CC BY-NC 4.0,要求署名、非商業(yè) 、保持一致。在滿(mǎn)足創(chuàng)作共用版權(quán)協(xié)議 CC BY-NC 4.0 的基礎(chǔ)上可以轉(zhuǎn)載,但請(qǐng)以超鏈接形式注明出處。文章僅代表作者的知識(shí)和看法,如有不同觀(guān)點(diǎn),可以回復(fù)并討論。