6 回答

TA貢獻1784條經驗 獲得超7個贊
據說數組“衰變”成指針。聲明為int numbers [5]無法重新指向的C ++數組,即你不能說numbers = 0x5a5aff23。更重要的是,衰變一詞意味著類型和維度的損失; 通過丟失維度信息(計數5)而numbers衰減int*,類型不再存在int [5]??纯催@里沒有發生腐爛的情況。
如果你按值傳遞一個數組,你真正要做的就是復制一個指針 - 一個指向數組的第一個元素的指針被復制到參數(其類型也應該是數組元素類型的指針)。這是因為陣列的衰變性質; 一旦衰減,sizeof就不再給出完整數組的大小,因為它本質上變成了一個指針。這就是為什么通過引用或指針傳遞(以及其他原因)的原因。
傳入數組1的三種方法:
void by_value(const T* array) // const T array[] means the same
void by_pointer(const T (*array)[U])
void by_reference(const T (&array)[U])
最后兩個將提供正確的sizeof信息,而第一個將不會,因為數組參數已經衰減分配給參數。
1在編譯時應該知道常量U.

TA貢獻1876條經驗 獲得超6個贊
數組與C / C ++中的指針基本相同,但并不完全相同。轉換數組后:
const int a[] = { 2, 3, 5, 7, 11 };
到一個指針(沒有強制轉換,因此在某些情況下可能會意外發生):
const int* p = a;
你失去了sizeof操作員計算數組中元素的能力:
assert( sizeof(p) != sizeof(a) ); // sizes are not equal
這種喪失的能力被稱為“衰變”。
有關更多詳細信息,請查看有關數組衰減的文章。

TA貢獻1898條經驗 獲得超8個贊
這是標準所說的(C99 6.3.2.1/3 - 其他操作數 - 左值,數組和函數指示符):
除非它是sizeof運算符或一元&運算符的操作數,或者是用于初始化數組的字符串文字,否則將類型為''array of type''的表達式轉換為類型為''指針的表達式type''指向數組對象的初始元素,而不是左值。
這意味著幾乎在表達式中使用數組名稱的任何時候,它都會自動轉換為指向數組中第1項的指針。
請注意,函數名稱以類似的方式起作用,但函數指針的使用要少得多,而且使用方式更加專業,因為它不會引起與將數組名稱自動轉換為指針一樣多的混淆。
C ++標準(4.2數組到指針轉換)將轉換要求放寬到(強調我的):
左值或類型“數組NT的”或“結合的T未知的數組”的右值可以被轉換成類型的右值“指針T.”
所以轉換不會有發生像它幾乎總是用C做(這讓對數組類型函數重載或模板匹配)。
這也是為什么在C中你應該避免在函數原型/定義中使用數組參數(在我看來 - 我不確定是否有任何普遍的協議)。它們引起混淆并且無論如何都是虛構的 - 使用指針參數并且混淆可能不會完全消失,但至少參數聲明不是說謊。

TA貢獻1821條經驗 獲得超5個贊
“Decay”是指表達式從數組類型到指針類型的隱式轉換。在大多數情況下,當編譯器看到數組表達式時,它將表達式的類型從“N元素數組T”轉換為“指向T”,并將表達式的值設置為數組第一個元素的地址。此規則的例外情況是,數組是sizeof或&運算符的操作數,或者數組是在聲明中用作初始值設定項的字符串文字。
假設以下代碼:
char a[80];
strcpy(a, "This is a test");
表達式a的類型為“80元素的char數組”,表達式“This is a test”的類型為“16元素的char數組”(在C中;在C ++中,字符串文字是const char的數組)。但是,在調用中strcpy(),表達式都不是sizeof或的操作數&,因此它們的類型被隱式轉換為“指向char的指針”,并且它們的值被設置為每個中的第一個元素的地址。什么strcpy()接收不是數組,但是指針,作為其原型看出:
char *strcpy(char *dest, const char *src);
這與數組指針不同。例如:
char a[80];
char *ptr_to_first_element = a;
char (*ptr_to_array)[80] = &a;
雙方ptr_to_first_element并ptr_to_array具有相同的價值 ; a的基地址。但是,它們是不同的類型,并且處理方式不同,如下所示:
a[i] == ptr_to_first_element[i] == (*ptr_to_array)[i] != *ptr_to_array[i] != ptr_to_array[i]
請記住,表達a[i]被解釋為*(a+i)(如果該數組類型轉換為指針類型僅作品),所以無論a[i]和ptr_to_first_element[i]工作相同。表達式(*ptr_to_array)[i]被解釋為*(*a+i)。表達*ptr_to_array[i]和ptr_to_array[i]可能導致的編譯器警告或者根據上下文的錯誤; 如果你期望他們評價,他們肯定會做錯事a[i]。
sizeof a == sizeof *ptr_to_array == 80
同樣,當數組是操作數時sizeof,它不會轉換為指針類型。
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element 是一個指向char的簡單指針。

TA貢獻1893條經驗 獲得超10個贊
C中的數組沒有任何價值。
只要對象的值是預期的但對象是數組,則使用其第一個元素的地址來代替類型pointer to (type of array elements)。
在函數中,所有參數都按值傳遞(數組也不例外)。當你在一個函數中傳遞一個數組時,它“衰變成一個指針”(原文如此); 當你將一個數組與其他數據進行比較時,它再次“衰變成一個指針”(原文如此); ...
void foo(int arr[]);
函數foo期望數組的值。但是,在C中,數組沒有價值!因此,foo獲取數組的第一個元素的地址。
int arr[5];
int *ip = &(arr[1]);
if (arr == ip) { /* something; */ }
在上面的比較中,arr沒有值,所以它成為一個指針。它成為指向int的指針。該指針可以與變量進行比較ip。
在數組索引語法中,您習慣于再次看到arr''衰變為指針'
arr[42];
/* same as *(arr + 42); */
/* same as *(&(arr[0]) + 42); */
數組不會衰減為指針的唯一情況是它是sizeof運算符的操作數,或者是&運算符('運算符的地址),或者是用于初始化字符數組的字符串文字。

TA貢獻1864條經驗 獲得超6個贊
當陣列腐爛并被指向時;-)
實際上,只是如果你想在某個地方傳遞一個數組,而是傳遞指針(因為誰將為你傳遞整個數組),人們會說可憐的數組衰減到指針。
- 6 回答
- 0 關注
- 776 瀏覽
添加回答
舉報