[英]Why do we use “type * var” instead of “type & var” when defining a pointer?
我對 C++ 比較陌生(大約一年的經驗,斷斷續續)。 我很好奇是什么導致決定將type * name
作為定義指針的語法。 在我看來,語法應該是type & name
因為&
符號在代碼中的其他任何地方都用於引用變量的內存地址。 因此,要使用int
指針的傳統示例:
int a = 1;
int * b = &a;
會成為
int a = 1;
int & b = &a
我確信這有一些我沒有看到的原因,我很想聽聽 C++ 老手的一些意見。
謝謝,-S
C++ 采用 C 語法。 正如“ The Development of the C Language ”(Dennis Ritchie 着)中所揭示的,C 使用*
作為類型聲明中的指針,因為它決定類型語法應該遵循使用。
對於[復合類型]的每個對象,已經有一種提及底層對象的方法:索引數組,調用函數,在指針上使用間接運算符[
*
]。 類比推理導致名稱的聲明語法與名稱通常出現的表達式語法的聲明語法相同。 因此,int i, *pi, **ppi;
聲明一個整數,一個指向整數的指針,一個指向整數指針的指針。 這些聲明的語法反映了當在表達式中使用時 i、*pi 和 **ppi 都產生 int 類型的觀察結果。
這是一個更復雜的例子:
int *(*foo)[4][];
這個聲明意味着一個表達式*(*foo)[4][0]
具有類型int
,並且從那個(並且[]
具有比一元*
更高的優先級)你可以解碼類型: foo 是一個指向大小數組的指針4 個指向整數的指針數組。
這種語法在 C++ 中被采用是為了與 C 兼容。另外,不要忘記 C++ 在聲明中使用了 &。
int & b = a;
上面這行表示引用另一個int
類型變量的引用變量。 引用和指針的大致區別在於,引用只是初始化,不能改變指向的位置,最后總是自動解引用。
int x = 5, y = 10;
int& r = x;
int sum = r + y; // you do not need to say '*r' automatically dereferenced.
r = y; // WRONG, 'r' can only have one thing pointing at during its life, only at its infancy ;)
我認為 Dennis Ritchie 在The Development of the C Language 中回答了這個問題:
對於這種組合類型的每個對象,已經有一種方法可以提及底層對象:索引數組、調用函數、在指針上使用間接運算符。 類比推理導致名稱的聲明語法與名稱通常出現的表達式語法的聲明語法相同。 因此,
int i, *pi, **ppi;
聲明一個整數,一個指向整數的指針,一個指向整數指針的指針。 這些聲明的語法反映了當在表達式中使用時 i、*pi 和 **ppi 都產生 int 類型的觀察結果。 相似地,
int f(), *f(), (*f)();
聲明一個返回整數的函數,一個返回整數指針的函數,一個返回整數的函數指針;
int *api[10], (*pai)[10];
聲明一個指向整數的指針數組,以及一個指向整數數組的指針。 在所有這些情況下,變量的聲明類似於它在表達式中的用法,該表達式的類型是在聲明開頭命名的類型。
所以我們使用type * var
來聲明一個指針,因為這允許聲明反映指針的使用(取消引用)。
在本文中,Ritchie 還講述了在“NB”(“B”編程語言的擴展版本)中,他使用int pointer[]
聲明指向int
的指針,而不是使用int array[10]
聲明數組的int
s。
如果您是一名視覺思想家,將星號想象成導致數據值的黑洞可能會有所幫助。 因此,它是一個指針。
&符號是黑洞的另一端,可以把它想象成一個解開的星號或一艘宇宙飛船,當飛行員克服從黑洞出來的過渡時,它在不穩定的航線中搖擺不定。
我記得被 C++ 重載 & 號的含義所迷惑,給我們提供參考。 他們不顧一切地試圖避免使用更多字符,國際觀眾使用 C 和已知的鍵盤限制問題證明了這一點,他們增加了一個主要的混亂來源。
在 C++ 中可能有幫助的一件事是將引用視為預先准備好的解引用指針。 在傳遞參數時沒有使用 &someVariable,而是在定義 someVariable 時使用了尾隨與符號。 再說一次,這可能只會讓你更加困惑!
我的一個最厭惡的,我就不高興了蘋果的Objective-C的樣品中看到的頒布,是布局風格int *someIntPointer
而不是int* someIntPointer
恕我直言,在變量中保留星號是一種老式的 C 方法,它強調如何定義變量的機制,而不是它的數據類型。
someIntPointer
的數據類型someIntPointer
是一個指向整數的指針,聲明應該反映這一點。 這確實導致要求您每行聲明一個變量,以避免出現細微的錯誤,例如:
int* a, b; // b is a straight int, was that our intention?
int *a, *b; // old-style C declaring two pointers
int* a;
int* b; // b is another pointer to an int
雖然人們認為在同一行上有意地聲明混合指針和值的能力是一個強大的功能,但我已經看到它會導致微妙的錯誤和混亂。
你的第二個例子不是有效的 C 代碼,只有 C++ 代碼。 區別在於一個是指針,而另一個是引用。
右側的“&”始終表示地址。 在定義中,它表明該變量是一個引用。
在右側,“*”始終表示地址處的值。 在定義中,它表明該變量是一個指針。
引用和指針相似,但又不一樣。 本文解決了這些差異。
與其將int* b
讀作“b 是一個指向 int 的指針”,不如將其讀作int *b
:“*b 是一個 int”。 然后,您將&
作為反*
:*b 是一個 int。 *b
的地址是&*b
,或者只是 b。
我認為答案很可能是“因為 K&R 就是這樣做的。”
K&R 決定了聲明指針的 C 語法是什么。
這不是 int & x; 而不是 int * x; 因為這就是語言的組成者定義語言的方式——K&R。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.