contact me:當我們寫下如下**:blog ->
email -> cugtyt#qq.com, cugtyt#gmail.com
github -> cugtyt@github
知乎專欄 -> programming & tools
void fun(int arr);
// 等同於void fun(int *arr);
int a[10];
fun(a);
我們知道a原來是個陣列,但是當我們呼叫fun傳入的時候,arr不再是陣列的形式,而是退化為指標,假設讀者有這個理解基礎。
那麼問題來了,這個轉變過程我們要注意什麼?
首先考慮如果是個陣列我們可以求陣列長度:
// 為了避免歧義,假設int是4個位元組,指標也是4個位元組
sizeof(a); // 40
sizeof(a) / sizeof(a[0]); // 10
但是指標就不一樣了:
sizeof(arr); // 4
我們丟失了陣列長度的資訊,因此從本質上來說,我們用退化的指標來表示陣列是有點問題的,真實的陣列指標應該怎麼寫呢?
void fun(int (*arr)[10]);
int a[10];
fun(&a);
#include
void fun1(int *arr)
void fun2(int (*arr)[10])
int main()
output:
0x7fffeadf1b30
0x7fffeadf1b34
0x7fffeadf1b30
0x7fffeadf1b58
可以看到fun1,就是原來的方式,指標增加1,沿著陣列元素後移,我們無法得知陣列有多長,而fun2是傳入陣列指標,指標增加1,位址增加28,注意這裡是16進製制,轉為10進製就是40,正好就是陣列的長度,也就是說這個指標包含了陣列長度的資訊。
好像我在表達原來的寫法是錯的,這樣才對,但是並不是。因為雖然保留了陣列資訊,但是函式的宣告必須把陣列長度表示出來,這意味著我們必須事先知道長度,而且不能改變,這就限制了函式的能力。所以c的處理方式是退化陣列為指標,然後加上陣列長度!
c++加入了std::array
的容器,但是正如我們上面討論的,由於我們要把長度寫死,因此在函式傳遞的時候就很不方便了,這個容器帶來的好處除了可以用標準庫的函式外,似乎在這方面並沒有什麼值得稱讚的地方。當然用指標,我們得人工保證傳入的東西是正確的。
希望讀者通過這個簡短的分析理解為什麼會有陣列退化為指標。
C語言 引數傳遞使陣列名退化為指標
做題的時候發現了一道題,想了很久也沒有想出來與給出演算法相符合的思路 最後寫了個可以勉強得出結果,但是好像不怎麼對的方法 因為題目給出的變數都已經使用過,所以只能使用陣列名作為增量向後遍歷 但是這時就出現了問題,陣列名竟然不指向首位址元素了,事後想想也知道如果一直指向首元素那麼顯然不能通過這種自增陣...
C語言 陣列做函式引數退化為指標的技術推演
陣列做函式引數退化為指標的技術推演 include include include 一維陣列做函式引數退化為指標的技術推演 void printfa char strarr 3 計算機中,陣列都是線性儲存,二維陣列元素也是乙個個的排列的 例如 1,2,3,4,5,6,7,8,9 像這組資料 我們可以...
引數傳遞時陣列引用保護陣列退化為指標
如下定義就得到乙個陣列的引用 型別名 變數明 n 在進行引數的傳遞時,陣列引用可以幫助我們防止陣列退化為指標,而這是我們在程式設計中很難注意到的問題。下面來看乙個例項 include void each int int ref 10 each int array 問題1 sizeof 的值?each...