亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

什么是陣列衰減?

什么是陣列衰減?

MMTTMM 2019-05-21 15:46:01
什么是陣列的衰變?與數組指針有關系嗎?什么是陣列衰減?
查看完整描述

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.


查看完整回答
反對 回復 2019-05-21
?
HUX布斯

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

這種喪失的能力被稱為“衰變”。


有關更多詳細信息,請查看有關數組衰減的文章。


查看完整回答
反對 回復 2019-05-21
?
汪汪一只貓

TA貢獻1898條經驗 獲得超8個贊

這是標準所說的(C99 6.3.2.1/3 - 其他操作數 - 左值,數組和函數指示符):

除非它是sizeof運算符或一元&運算符的操作數,或者是用于初始化數組的字符串文字,否則將類型為''array of type''的表達式轉換為類型為''指針的表達式type''指向數組對象的初始元素,而不是左值。

這意味著幾乎在表達式中使用數組名稱的任何時候,它都會自動轉換為指向數組中第1項的指針。

請注意,函數名稱以類似的方式起作用,但函數指針的使用要少得多,而且使用方式更加專業,因為它不會引起與將數組名稱自動轉換為指針一樣多的混淆。

C ++標準(4.2數組到指針轉換)將轉換要求放寬到(強調我的):

左值或類型“數組NT的”或“結合的T未知的數組”的右值可以被轉換成類型的右值“指針T.”

所以轉換不會發生像它幾乎總是用C做(這讓對數組類型函數重載或模板匹配)。

這也是為什么在C中你應該避免在函數原型/定義中使用數組參數(在我看來 - 我不確定是否有任何普遍的協議)。它們引起混淆并且無論如何都是虛構的 - 使用指針參數并且混淆可能不會完全消失,但至少參數聲明不是說謊。


查看完整回答
反對 回復 2019-05-21
?
收到一只叮咚

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的簡單指針。


查看完整回答
反對 回復 2019-05-21
?
白豬掌柜的

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運算符的操作數,或者是&運算符('運算符的地址),或者是用于初始化字符數組的字符串文字。


查看完整回答
反對 回復 2019-05-21
?
慕尼黑的夜晚無繁華

TA貢獻1864條經驗 獲得超6個贊

當陣列腐爛并被指向時;-)

實際上,只是如果你想在某個地方傳遞一個數組,而是傳遞指針(因為誰將為你傳遞整個數組),人們會說可憐的數組衰減到指針。


查看完整回答
反對 回復 2019-05-21
  • 6 回答
  • 0 關注
  • 776 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號