函式的引數可以是陣列嗎 指標和陣列有何聯絡及區別?

2021-10-18 02:10:30 字數 3244 閱讀 4085

1.指標和陣列定義、區別

1.1指標和陣列定義

指標和陣列都是c語言的精髓所在,對於很多c程式設計師來說,如果你問這樣乙個問題:陣列和指標有什麼區別?他們的答案很可能是:」陣列和指標不是同一樣東西嗎,他們之間有什麼區別啊?「;確實在極個別的情況下,陣列和指標確實可以」通用「。

但是在卻大多數情況下,陣列和指標是兩個完全不同的c語言特性。

首先,我們分別看一下,指標和陣列的定義,以及他們之間的不同;指標表示c語言中某種資料型別的資料儲存的記憶體位址,例如,指向各種整型的指標或者指向某個結構體的指標;陣列表示若干個相同c語言資料型別的元素在連續記憶體中儲存的一種形態。

1.2陣列和指標的區別

好了,上面即為陣列和指標的簡單定義。在說明陣列和指標之間的區別之前,我們先來看乙個例項;

我們定義兩個檔案:a.c和b.c,其中,

[cpp] view plain copya.c檔案:  int array[4] = ;  b.c檔案:  #include     extern int *array;  int main(void)         return 0;  }
我們編譯執行上面的示例程式,不出意外其無法執行。可能有的人很不理解其中原因,他們找不出問題的原因。其實根本原因就是他們認為陣列和指標是相同的!其將array定義為乙個4個int元素的陣列,但是在b.c中卻又將其宣告為int型指標。其實陣列和指標只是在特定的上下文環境下可以認為相同,一般情況下,他們是不同的資料型別,就像float和int型別不同一樣。

下面逐步分析陣列和指標之間的區別:

陣列和指標本質上都代表一塊記憶體,陣列比較」直接「,陣列名即代表這塊記憶體的位址,而指標比較」含蓄「,其本身不代表任何有意義的內容,只有給它賦值後,它才真正的表示一塊有意義的記憶體位址。這就引出了指標和陣列的乙個區別:定義的時機不同;陣列在編譯時就已經被確定下來,而指標直到執行時才能被真正的確定到底指向何方。陣列就好比生在帝王家一樣,一生來就有了屬於自己的封地、財富(記憶體),而指標需要經過編譯、鏈結、執行時等重重考驗才能獲得屬於自己的財富(記憶體)。但是,陣列的這些身份(記憶體)一旦確定下來就不能輕易的改變了,它們(記憶體)會伴隨陣列一生;而指標則有很多的選擇,在其一生他可以選擇不同的生活方式,比如乙個字元指標可以指向單個字元同時也可代表多個字元等。

由陣列和指標的上述區別引出了它們的之間的另乙個區別:訪問方式不同;由於陣列名直接代表其身份(陣列在記憶體中的位址),而指標需要間接才能知道自己的身份(通過讀取其儲存的位址),所以它們的對於自己」財富「的訪問方式自然就不同了,陣列為直接方式,而指標位間接訪問。通過下面幾幅圖來說明,陣列和指標對於自身元素的訪問方式的不同:

2.再論陣列

2.1陣列和指標何時相同

圖2-1展示了陣列和指標何時相同。

圖2-1,中說明了陣列除了在作為函式引數或者在表示式中作為右值,其他情況情況下其與指標均不相同。 

圖2-1指標和陣列何時相同

圖2-1,中說明了陣列除了在作為函式引數或者在表示式中作為右值,其他情況情況下其與指標均不相同。

c語言標準對於陣列和指標何時相同定義幾條規則:

規則1:表示式中的陣列名(與宣告不同)被編譯器當作乙個指向陣列第乙個元素的指標。

規則2:下標總是與指標的偏移量相同。

規則3:在函式引數的宣告中,陣列名被編譯器當作指向該陣列第乙個元素的指標。

簡而言之,陣列和指標的關係頗有點像詩和詞關係,它們都是文學性之一,有不少共同之處,但在具體的表現形式上又各有特色。下面具體介紹這幾條規則的具體含義。

2.1.1 規則1

組合規則1和規則2,就是對於陣列下標的引用總是可以寫成「乙個指向陣列的起始位址的指標加上偏移量」。例如,假如我們宣告如下:

就可以通過下面任何一種方式訪問a[i]:

p = a;p[i];

p = a;*(p+i);

p = a + i;*p;

記住:在表示式中,指標和陣列是可以互換的,因為它們在編譯器裡的最終形式都是指標,並且都是可以進行取下標操作。

2.1.2 規則2

陣列下標和指標總是相同的,為什麼要這麼說呢?大家可能聽說過,在編寫程式時,對於陣列訪問應該寫成指標的形式,因為這樣可以提高效率。對於現代的編譯器而言,這個說法一般是錯誤的!現代編譯器對於陣列的訪問都會自動優化為其對應的指標加偏移量的形式,所以也就沒有哪種形式效率更高的說法了。實際上,陣列的訪問之所以改寫為指標加偏移量的方式,是因為其為系統底層最基本的工作方式。

2.1.3 規則3

c語言中函式的引數基本都是「傳值」呼叫的,唯獨陣列為「引用」呼叫方式,即陣列作為函式引數時,會被編譯器自動的轉換為指向陣列第乙個元素的指標,這是編譯器自動完成的。之所以這麼做,其實是為了系統效能,因為陣列結構占用的記憶體通常比較大,如果「傳值」呼叫的話,記憶體拷貝會浪費大量的時間和空間,這樣做得不償失,所以陣列作為函式引數時,編譯器會自動將其轉換為指向第乙個元素的指標。

猜你喜歡:

c語言、嵌入式位操作精華技巧大彙總

c經典問題:函式不可返回指向棧記憶體的指標!

面試題:c語言驗證大小端的幾個方法

指標函式和函式指標 指標陣列和陣列指標

綜述 函式指標是乙個指向函式的指標,而指標函式是指乙個返回值為指標的函式 陣列指標是乙個指向二維陣列的指標變數,而指標陣列是多個指標變數以陣列的形式儲存在記憶體中 一 函式指標 1 函式指標定義 函式型別 指標變數名 形參列表 函式型別 說明函式的返回型別,由於 的優先順序高於 所以指標變數名外的括...

關於指標,函式和陣列

指標,陣列,函式分別在c語言學習中,都很重要的東西。也是大多數同學較為頭疼的,那麼函式,陣列和指標組合在一起,又會又哪些新的變數型別呢。在這之前,我先要和大家強調一點,其實指標就是指標,陣列就是陣列。陣列和指標之間,沒關係 只是他們在訪問內部變數時的形式可以相同。所有我們要特別區分幾個量 指標陣列 ...

陣列指標和陣列引用做引數的區別

陣列指標和陣列引用做引數的區別 是否能夠限定陣列大小 陣列降價 template void func1 t t template void func2 tt,tt int main 1 在c 中可以定義陣列的引用,用以解決c中無法解決的 陣列降價 問題,我們先來看看什麼是 陣列降價 先看如下 voi...