目前共有4篇帖子。
【轉載】再談定義指針變量時星號應該靠左還是靠右
1樓 巨大八爪鱼 2015-8-13 12:14
雖然
(1) int* a;
(2) int *a;
都能編譯通過,不過我想這是編譯器的糾錯優化,給許多編碼潦草的人一個很大的容錯度。
但是,這並不代表原本的含義就是可以隨意跟隨。
我的觀點是正確的應該是(2)。
我看過一些帖子,有人認為(1)是正確的,理由是:int*代表了一個類型,這種說法面臨的最大質疑是,倘若真如此,那麼如下寫法應該表示定義了三個指針變量
int* a,b,c;
但實際上我們知道不是。
另外,若int*代表了一個類型,那我們很容易想到,int*&是否又代表回了int類型呢?但實際上這樣的寫法編譯器是不認的。
再有,若int*代表了一個類型,那轉定義的時候為什麼不能寫成
typedef (int*) PINT;
呢?但卻可以寫成
typedef int (*PINT);
這實際上更強烈的暗示,我們並不是將int*定義成了PINT,而是將*PINT定義成了int。
還有
typedef char ARRAY[10];
是合法的,但
typedef char[10] ARRAY;
是非法的。這也提示,我們是定義了一個數組大小為10的ARRAY,而這ARRAY中的一個,是定義為字符類型的。而不是將ARRAY定義為了大小為10的字符數組類型。
當然,在java里,這兩種寫法都是ok的,這是不是後來為了更好理解的原因,想強制糾正成(1)的理解,這是另外的話題。
那支持(1)的規則到底是什麼呢?我認為很混亂了。首先多引入了許多代表指針、雙重指針、多重指針的類型;其次,又規定跟隨&是不合法的;又規定只能適用於定義變量,而不適用於轉定義類型,不適用於定義數組等等。
我認為,一個好的規則,是要盡量的簡單,如果用已有的規則已經能解釋清楚了,就沒必要再引入新的規則。
這在哲學上叫做奧卡姆剃刀原理,即:如無必要,勿增實體。因此,(1)的規則,是不好的規則,至少在編譯器所能支持的語法規範里是如此。
現在我來說說我理解的(2)的規則:
在(2)這種寫法里,類型還是int,並沒有增加。*a代表a取內容,這也是既有的規則。因此,它說的是,變量a的值所在的地址里,存儲的是類型為int的值。因此,a被通俗地稱為指向int型的指針。
在這裡,沒有引入額外的概念(即int*)就讓人明白a到底是什麼東西了。
同樣,在typedef int (*PINT);
里,我們定義的還是基本類型int,沒有引入額外的類型。數組的定義也是如此。
那我們再來看看,用規則(2)是怎麼解釋,為什麼形如
int &*a;
的寫法是錯誤的。此時,我們定義了一個變量a,它的值所在的地址里的值,再取地址……等等,這裡我們就碰到問題了,無法繼續理解下去。
譬如a=0x1234,在內存地址為0x1234的地方,假設值為0x5678,0x5678取地址?但,0x5678隻是一個數值,不是變量,怎麼取地址呢,所以是錯誤的聲明。
但是按照(1)的規則,我們完全應該可以這樣寫
int*& a;
這無非是定義了一個變量a,它的類型是int*&,至於int*&是什麼東西,管我什麼事。再說編譯器也沒有提示我它不認識int*&啊。
同樣的,在轉定義函數指針的時候,也可以按照(2)的規則,很簡單的理解定義的內容,比如
typedef int (*func)(void);
這表示函數返回值所在的內存地址里,表徵的是int類型的值。我們無法寫成
typedef (int*) func(void);
綜上所述,個人認為,基於當前C編譯器支持的語法而言,引用奧卡姆剃刀原理的話,只有(2)規則才是正確的理解。
我個人在看一些複雜定義的時候,都是通過(2)這樣的規則去理解的,從來沒有出現過錯誤。所以我也一直沿用(2)的寫法。
最後,我想說的是,從誰更加容易被理解的角度,實際上(2)的規則並沒有(1)來的好,我個人更希望是這樣的規則
int* a,b,c; 定義了3個指針變量
char[10] array; 定義數組
typedef (int*) PINT; 是轉定義類型
這顯得更直觀,但無奈目前編譯器不是這麼想的。
以上為一家之言,若有理解不對的地方,請大家指正。

原文:http://bbs.csdn.net/topics/390442206
2樓 巨大八爪鱼 2015-8-13 12:14
上述很多事實都已經證明了int*不是一個類型。
所以定義指針變量時最好寫成int *p
3樓 巨大八爪鱼 2015-8-13 12:15
int main(int argc, char *argv[])
默認的main函數格式也是星號靠右。
4樓 巨大八爪鱼 2015-10-21 09:31
int *p可以這樣理解:把*p定義為int類型。

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
 
 
©2010-2025 Arslanbar [手機版] [桌面版]
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。