咱們用兩個簡單(?)的問題做爲引入,固然咱們整篇文章都會圍繞這兩個問題:html
下面四種類型聲明等價嗎?linux
int* i;
int *i;
int * i;
int*i;
下面四種類型聲明中,j
擁有哪個數據類型?是int
或者int
的指針?數據庫
int* i, j;
int *i, j;
int * i, j;
int*i, j;
固然看到這裏,若是你已經有很是自信的答案,你固然能夠無視這一篇文章後面的部分。express
第一個問題的答案是: 四種指針的類型聲明的等價的。編程
很好,既然咱們知道它們等價,或許已經足夠了。可是咱們數據庫教授老是在課上提醒你們,知道區別並不足夠,還須要問本身其中的哪個更好,什麼狀況下用哪種方式。less
C++之父在他的一篇文章:Bjarne Stroustrup's C++ Style and Technique FAQ中提到:ide
The choice betweenint* 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.
Atypical C programmer
writesint *p;
and explains it*p is what is the int
emphasizing 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.
Atypical C++ programmer
writesint* p;
and explains itp is a pointer to an int
emphasizing 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.
Linux kernel coding style中的習慣規則是:this
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的想法。spa
第二個問題的答案是: j
的類型是int
。指針
固然這問題是編譯器的行爲,或者語言自身的規定,很難去闡述行爲或規定背後的爲何。
咱們繼續看Bjarne Stroustrup's C++ Style and Technique FAQ,這部分緊接問題一中對應的引用:
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.
從他的這一部分文字中,很容易能夠看出咱們這文章中的第一個問題和第二個問題徹底是緊密結合。第二個問題中的四種寫法的確是等價的,可是無一能讓人輕鬆理解。從他的這一個觀點中:Declaring one name per declaration minimizes the problem
,咱們能夠對這篇文章下一個主觀的結論。
針對第二個問題,對我來講最好的方式是:
int* i; int j;
這種寫法更清晰,也是多個Stackoverflow提問中所提倡的。
最後一點聲明是,不管怎麼寫對編譯器來講其實都無所謂,它只是客觀地去檢查可否經過編譯而後生成對應的代碼。這些等價寫法對應的彙編語言甚至同樣,對應的程序的效能天然也是同樣。這些寫法迷惑的只是人類(編程的人和瀏覽代碼的人),咱們須要有一個清晰的方式,保證本身不出錯同時也讓代碼瀏覽者能快速理解。
引用和推薦閱讀:
http://www.stroustrup.com/bs_...
https://www.kernel.org/doc/Do...
https://softwareengineering.s...
https://stackoverflow.com/que...
https://stackoverflow.com/que...
https://stackoverflow.com/que...
https://stackoverflow.com/que...
https://stackoverflow.com/que...
(Stackoverflow通通是在問同一件問題)
該文章遵循創做共用版權協議 CC BY-NC 4.0,要求署名、非商業 、保持一致。在知足創做共用版權協議 CC BY-NC 4.0 的基礎上能夠轉載,但請以超連接形式註明出處。文章僅表明做者的知識和見解,若有不一樣觀點,能夠回覆並討論。