爲什麼指針變量可以賦值,但數組變量不能? 換句話說,爲什麼語句4是非法的,在代碼片段之下?數組和指針C++
1.int a[10];
2.int *p;
3.p=a; //legal operation
4.a=p; // Illegal operation
爲什麼指針變量可以賦值,但數組變量不能? 換句話說,爲什麼語句4是非法的,在代碼片段之下?數組和指針C++
1.int a[10];
2.int *p;
3.p=a; //legal operation
4.a=p; // Illegal operation
有一個原因爲什麼你的聲明3.被稱爲衰變。轉換是一種方式,因爲指針和數組是不一樣的。
當數組衰減到指針時,它會丟失有關它的大小的信息。它不能被恢復,所以相反的轉換不能隱式執行。即到int[WHAT]
它應該轉回嗎?從我的頭頂
兩個主要區別:
如果檢查a
不包含關於它的大小信息,指針不。請檢查sizeof(a)
,sizeof(p)
和sizeof(*p)
。
a
保證某些元素存在(C++禁止零大小的數組)。
但它是有道理的在某些情況下治療p
爲綁定陣列decltype(p)
類型。特別是元素的放置很容易計算給定元素在內存中的位置。它與指針算術相同。這就是爲什麼符號是相同的,例如工作p[6]
和a[6]
。所以接受數組的函數可以接受任意大小的數組。
但它是不一樣的。
添加另一個維度時,差異會變得明顯。使用(固定大小)數組,您可以像上面一樣計算元素的位置,它在內存中是連續的,並且您知道每個「行」的大小。
但是對於int**
你有兩個層次,你不知道邊界。即您無法通過算術計算元素的位置int**
您必須先解析第1級,然後使用計算。每個「行」可以有不同的長度。
這就是爲什麼你的錯誤看起來像:
main.cpp:11:8: error: cannot convert 'int**' to 'int ()[5]' for argument '1' to 'void f(int ()[5])'
注意,第一維得到covnerted一個指針,但你只能在一維數組解除綁定(按照慣例這是其一)!
參見http://coliru.stacked-crooked.com/a/5063a9d19739278a:
void f(int a[3][5]){}
int main() {
int ** p = new int*;
int b[4][5]; // works because 1st dimension can decay to pointer (unbound array)
int c[3][6]; // doesn't work because 2st dimension cannot decay to pointer
f(p); f(b); f(c);
return 0;
}
大約有陣列是如何工作的一些古怪的事情,但主要的事情是:
根據數組是如何定義的細節,通過將數組轉換爲指向其第一個元素的指針(從而將第一個元素轉換爲第二個元素)這種轉換隱含地發生),但從第二轉換爲第一轉換沒有多大意義。
您可以將數組視爲一個指針,在內存中保留多個位置。 a
是指向數組a的指針。當您使用p=a
時,您正在將指向數組a的指針指向指針p。但不能使用a=p
因爲多於一個的對象,並且p指向的單個位置
int * p
技術上這是一個整數的任一個ADRESS或數組的ADRESS,其我們忽略的尺寸(也許更多比10)
int a[10];
這是一個給定大小
的對象因此你不能ASIGN的ADRESS一個完整的對象。
使用p=a
您正在將數組的基地址分配給指針,因此它是合法的,或者您可以編寫p=&a[0];
但a = p沒有任何意義,它不是一個單獨的位置。
基本上他們[數組和指針]只是不同的實體。指針可以指向數組的第一個元素,在某些情況下數組會衰減到一個指針(可以參考C++語言標準4.4.2),但反之亦然。
另請參閱this答案。
因爲數組是恆定指針。 –
a不是一個變量。 –
@射線:'a' *是一個'int [10]'類型的變量。 – Hurkyl