如何理解 C++ 中 int *i 的聲明方式?

如果*是和變數一起的,那說不通啊,變數的定義是必須以字母和下劃線開始的;如果*是和int在一起的,那為什麼不寫成int* i呢?

問題很小白,但我真的想明白這個到底是為什麼,編譯器又是怎麼解釋它的呢?


這顯然是語言設計的問題。

因為當初設計C語言的時候,那幫人腦抽,認為應當讓 "*a" 的表現和int一樣,以達到「最小驚訝」原則。所以就讓 "int * a, b" 表現得像 "int *a" 和 "int b" 一樣。

事實證明,大部分人的腦子都跟他們長得不一樣。


int *i;
int* i;
int * i;

這三句話的意思都是 創建一個名為i的int指針

空格肯定要空的 但空的空格是寫在前面還是寫在後面 這點取決於程序員的個人習慣

空格具體寫在哪裡 都沒有關係 會被編譯器忽略

如果您寫

int*i;

也是可以的:)

以上。


試試這個,int *a表示*a是int型,所以a就是指針了


事實上,c標準並不認為指針是個「類型」

c解析變數聲明是倒推的方法,int *a是說*a是int,所以推出a是int指針

再如複雜點的 int (*a[5])()

首先(*a[5])()這個表達式是int,於是*a[5]是個函數,於是a[5]是個函數指針,a就是個函數指針數組了,若改成這樣的語法是不是更明確,把類型寫在左邊:

int()*[5] a

c語言定義變數的語法邏輯上是自洽的,只是採用倒推的方式,看起來不那麼直觀,所以*還是和i挨著好,如:

int *i,j

這是說*i和j是int,而若*挨著int,看上去就是i和j都是int*,容易誤解


int *i沒問題。

很好想,*的作用就是獲取以i的值為起始地址的一串數據。那麼究竟要從i往後讀幾個位元組,就要靠前面的int來定義。

連起來,int *i意思就是指針i指向的變/常量為int型。也就是說,int定義的是*i這個整體(也就是i所指的變數),理所當然是右結合。(當然,事實上你想怎麼結合都行,因為編譯器處理出來都是一樣的~)

另:有答主說這是語言缺陷,我不敢苟同。畢竟這個邏輯還是很清晰的。


可以寫成 int *i ;

也可以寫成int* i ;

還可以寫成 int * i,對於編譯器沒有區別。

但是實際上為了便於閱讀和風格統一,我都是寫成 int* i ,畢竟i作為變數名前面加個*有不倫不類的感覺。


這個問題一點都不小白,這是自古以來我等程序員必爭之地,雖然比大括弧換行還是不換行等 猿家 重地,也是死傷無數的。

.......補充......

代碼不應該讓人看不懂,而且絕對應該遵循不要有二異性。個人一般書寫如下...int *a; 或者int* a;重點是不會同時定義倆個變數或元素在同一行如:int* a,b;看起來有歧義。 事實上沒有,int *a,b;一樣。


int *i;

這種寫法的意思是:*i(i 解引用後)是一個 int,所以 i 是一個指向 int 的指針。

int a[3];

這種寫法的意思是:a[...] 是一個 int,所以 a 是一個 int 數組。

int *a[3];

這種寫法的意思是:*a[...] 是一個 int,所以 a 是一個數組,其中的元素是指向 int 的指針。

注意由於 [] 的優先順序高於 *,所以 *a[...] 的意思是 *(a[...]) 而不是 (*a)[...]。


設想一下你需要在一行代碼裡面申明 int 和 int* 的情況;

int m, n, *p;

這樣是合法的申明


int* i

int * i

int *i

效果是一樣的,都是創建一個"名為"i的指向int的指針


首先*不會被編譯器考慮進變數名的一部分

*放在哪都可以的

你也可以

int * i;


看來還是圖樣圖森破啊

int* i和int *i怎麼寫都行,看你心情,兩種寫法對詞法分析器來說沒任何區別,都認為是類型標識符,運算符*和標識符,語法分析都看不到這種區別,不知這麼說你能不能聽懂,如果不明白的話,把編譯原理看上3遍自然就懂了


雖然*放在哪邊都可以,

但需要注意的是,連著聲明兩個指針,需要這樣:

int *i,*j;

而不是

int * i,j;


int別和*粘在一起。

int* point1, point2;

這裡只有point1是指針,point2是整形變數。

所以推薦:要麼這樣,

int *point1,*point2;

要麼分開

int *point1;

int *point2;

都可以。

//===========分割線==========

變數的首字母只能是下劃線和字母。

不可以加奇怪的符號。

*並不是變數名的一部分。

在定義變數的時候,*的意思是:告訴編譯器, *右邊的變數類型很特殊,它是指針。

編譯器允許你在不發生語義歧義的情況下,任性地加上空格。

你也許見過這種

int *a;

int* a;

int * a;

如果你想定義一個指針,這個指針是指向另外一個int指針,那就需要2個*了。

int **pp;


寫成int* i在一些時候理解上會出問題,所以我一般是寫成int *i。

看一個例子,假設寫int* a, b;

這裡是不是意味著你覺得int*是一個整體,一種特殊的類型,那a、b是不是都是指針類型?

事實上,寫代碼試試看,編譯器不這麼覺得,它覺得a是指針沒錯,可b就是整型數。

所以理解上,寫成int *a, *b;

*a是一個整體,是一個整型數,則a就是指針了。


我的偏好,當定義指針類型對象的時候,比如你的例子,我寫成int* a,理由,為了統一,好記,int*是類型名,a是變數名. 指針是複合類型,不同類型複合出的指針類型類型不同。


個人偏好把int*看做一個整體,把i作為變數,實際上這也符合從右向左看的原則。

至於int *i的寫法,我認為可以理解為*i代表一個整形。反正我不喜歡這樣。


typedef int* intp;


int *i


*的位置是給人看的,跟誰近對於編譯器來說都一樣。只不過跟類型近偏向於強調指針是什麼類型的,跟變數近偏向於強調這個變數裡面的內容是地址。《C++ Primer》裡面我記得介紹過,可以參考下。


可以理解為*i 是一個整形,也可以理解為 I 是一個 int* 的類型


*應該理解成一個一元運算符吧。。。


個人理解,int* 是一個類型,叫指向int型的指針,i 是變數名,所以我習慣寫成 int* i


推薦閱讀:

精通 Python 是一種怎樣的體驗?
微軟辦公軟體國際認證(MOS)有用嗎?
如何使用《演算法導論》?
計算機科學與技術有哪些專業書籍,如何系統的學習。怎麼結合幕課學習。?
台式電腦是組裝好還是原裝好?

TAG:編程語言 | 計算機 | C |