C語言 引數傳遞使陣列名退化為指標

2021-10-09 10:04:57 字數 1445 閱讀 4089

做題的時候發現了一道題,想了很久也沒有想出來與給出演算法相符合的思路

最後寫了個可以勉強得出結果,但是好像不怎麼對的方法

因為題目給出的變數都已經使用過,所以只能使用陣列名作為增量向後遍歷

但是這時就出現了問題,陣列名竟然不指向首位址元素了,事後想想也知道如果一直指向首元素那麼顯然不能通過這種自增陣列名的方式遍歷陣列

在main函式定義陣列並使用陣列名自增時,編譯器會報錯,那為什麼在while迴圈中可以自增?是因為while有神奇的魔力嗎?顯然不是,是因為在引數傳遞的時候,陣列名在傳遞過程中發生了「退化」,從陣列名這個特殊的型別退化成了指標,而指標自然時可以通過自增後移的

陣列名代表的是乙個記憶體塊及這個記憶體塊中的元素型別 。只是在大多數情況下陣列名會「退化」

算術運算與陣列取下標操作符時退化為指標

如:

char a = "hello";

char *p = a + 1;

陣列取下標操作符[ ],在c標準中對它的定義是等價於*(p + offset)運算

也是就說,你寫a[3]其實等價於*(a+3),可以看到括號內是乙個算術運算,於是a「退化」為乙個指標,隨後參與進行計算和解引用。

根據加法的交換律,我們也可以寫成*(3+a),也是就3[a]。

我們學在給函式傳遞陣列的時候,經常會聽到「按值傳遞機制和按引用傳遞機制 」這樣的說法(網上也有很多),即傳遞陣列是「按引用傳遞的」,這也是為什麼傳遞陣列在函式內讀寫陣列,退出函式後陣列會發生變化的原因。

實際上c語言引數傳遞只有一種:值傳遞

幾種定義陣列引數方式:

void test(int a[5])

void test(int [5])

void test(int*)

許多人認為,第一種寫法是最好的,清晰(這個是對的,對於**閱讀者而言)而且可以告訴編輯器這個陣列的大小。

但是,這三種宣告在編譯器看來只有一種:void test(int*)

test函式得到的是乙個值為a「退化」後指向陣列首元素(記憶體塊首位址)的指標 ,在test內部是不知到a是乙個陣列的,它僅僅認為它是乙個整數指標。

但是我們依然可以使用陣列取下標操作符進行運算,因為即使a是乙個陣列名,它被用作陣列取下標操作符的運算元時也會「退化」為指標

C C 中陣列名退化為指標的情況

指標是c c 語言的特色,而陣列名與指標有太多的相似,甚至很多時候,陣列名可以作為指標使用。於是乎,很多程式設計者就被搞糊塗了。而許多的大學老師,他們在c語言的教學過程中也錯誤得給學生講解 陣列名就是指標 很幸運,我的大學老師就是其中之一。時至今日,我日復一日地進行著c c 專案的 開發,而身邊還一...

陣列名作為函式引數時,退化為指標

陣列名作為函式引數時,退化為指標 func char str 100 函式中陣列名作為函式形參時,在函式體內,陣列名失去了本身的內涵,僅僅只是乙個指標 在失去其內涵的同時,它還失去了其常量特性,可以作自增 自減等操作,可以被修改。陣列作為引數傳給函式時傳的是指標而不是陣列,傳遞的是陣列的首位址 在c...

引數傳遞時陣列引用保護陣列退化為指標

如下定義就得到乙個陣列的引用 型別名 變數明 n 在進行引數的傳遞時,陣列引用可以幫助我們防止陣列退化為指標,而這是我們在程式設計中很難注意到的問題。下面來看乙個例項 include void each int int ref 10 each int array 問題1 sizeof 的值?each...