陣列做函式引數的退化問題,請問是怎麼回事呢?

時間 2021-06-03 19:56:13

1樓:

1. 首先明白編譯器將陣列退化為指標的場景,以下三種情況是不會退化為指標的:

char s = 「hello」;

此時對 s 進行取位址操作,還是使用的陣列首元素,而不是首元素的位址

即 &s <==> &s[0]

1.2 作為常量字串進行初始化賦值的時候

char s = 「hello」;

此時的 "hello" 表示的是陣列,而不是指標

1.3 最後一點就是你用到的 sizeof( )

除此之外的3種情況都會被編譯器當作陣列首元素的位址處理。

2. 第二點要明白sizeof() 的含義, sizeof() 計算的是變數分配的記憶體大小,以位元組為單位

比如 int a =10; sizeof(a) = 4 , 說明是 int 是4個位元組,

比如 char s[10] = "hello" -> sizeof(s) =10 是因為陣列分配了10個位元組的空間,即使這些空間沒有被全部使用(只對前5個字元進行了初始化),返回的也是已分配的空間大小10。如果要得到字串長度,要使用 strlen()

當陣列作為函式引數傳進來之後,會退化成指標的方式,你的sizeof(a) 實際上計算的是這個指標所佔的記憶體大小,8個位元組表示是64位的,而 sizeof(a[0]) ==> sizeof(int)

2樓:只增笑耳Jason

如果你的a是caller通過 new 建立的,sizeof不起作用。另外sizeof(a)那是在求乙個指標的大小不是那個陣列

3樓:Alinshans

如果你想得到乙個實實在在的陣列,請使用引用,那麼你就會得到乙個真實的陣列 (const) T(&)[N] 而不是 (const) T* ,像這樣用:

template

void prints(T& arr)

int main()

;prints(dump);

}輸出12.

借鑑此可以寫乙個編譯期獲取原生陣列大小的模板:

template

constexpr std::size_t getSize(T(&)[N]) noexcept

然後可以這樣用:

int dump = ;

int arr[getSize(dump)]; // works.

參考 《Effective Modern C++》.

4樓:Morris

陣列作為引數傳入函式,陣列名被編譯器視作指標處理,對其使用sizeof得到指標大小,你的結果是8,說明你的作業系統是64位。a這已經是在訪問陣列內元素了,sizeof結果自然是元素的大小

haskell的 函式組合 是怎麼實現的,scala裡如何做到?

夏梓耀 compose A g A T1 A R Haskell的話,還是個函式 b c a b a c f.g x f gx 那麼在Scala裡也可以這麼搞 假設可以用implicit scala implicit class JoinFunctionsCompactly B,C g B C de...

請問C 函式的區域性變數和引數哪個先被刪除?

徐聖 C param 讀讀它你就明白了 區域性變數先滾蛋,引數其實是在呼叫者的棧上呢,最後銷毀。怎麼定址到引數呢,棧幀基址往高位址加就行了。其實GCC最後一步銷毀引數一般都省略不做,因為下次使用到這塊記憶體時會覆蓋掉了。 旺旺 根據C 2003標準文件第5.2.2節第4項的規定 引數的構造與析構發生...

c語言函式是如何獲取傳入的陣列(指標)的指標所指向內容的長度的,有辦法嗎?

陳昱 如果是new出來的話,有可能找到,想想delete array時,系統是如何知道需要delete的長度的呢?一種說法是array指標的位址前面的位址,有儲存該陣列大小的資訊,於是可以獲取到了,具體不確定 c語言的情況下,老老實實的把長度帶上。就好比你給搬家公司的人說我要搬家,然後人家說我派一輛...