C 陣列指標 指標陣列及陣列傳參

2021-09-10 09:00:22 字數 4862 閱讀 5638

一維陣列傳參

二維陣列傳參

一級指標傳參

二級指標傳參

小引

在指標的學習階段,有不少同學都十分畏懼這個物什,甚至「談指標色變」。其實對指標的不理解,其實本質上是對記憶體的不理解,本篇部落格就從零開始、系統的來講解指標這個話題。

首先我們應該明確以下的一些基礎常識:

指標是乙個變數,用來存放位址,位址唯一標識一塊記憶體位址。

指標的大小是固定的4 或 8個位元組。(3264位平台)

指標是有型別的,指標的型別決定了指標加減整數運算的步長,以及指標解引用時的許可權。

顧名思義,就是指向字元變數的指標,指標內存放的內容是乙個字元。它的一般寫法如下:

int main()

如果此時對ptr進行strlen,就會記憶體訪問越界,屬於未定義行為,結果不可預期。因為指標指向的是乙個字元而不是字串。

指向單個字元的使用方式簡單明瞭,但是相對於下面的這種常見的指向字串的使用方式,就相形見絀了。

int main()

這樣也可以間接的表現為指標指向了字串

**中char *ptr_1 = "this is a c string";語句看似是將字串放入了指標內,但其本質是將這個字串的首位址存放到了指標內。

如果此時對ptr_1進行strlen,就會正確的列印出字串的個數,因為此時指標的指向不再是單個字元,而是字串。

其實編譯器無法識別指標的指向是字元陣列 還是字串,所以它的指向需要使用者來定義保證。

請看**:

int main()

它的本質是指標,指標的指向是乙個陣列。它的定義如下:

int (*arr)[20];
因為的優先順序高於*,而()的優先順序高於。所以加上圓括號()改變優先順序順序。(不加圓括號的情況下面會提及)

先進行括號( )內的操作,這裡變數名arr*結合就明確了他是乙個指標變數,括號操作符完成再與其他元素進行結合,它指向了乙個大小為10個整型元素的陣列。

【二維陣列也是乙個陣列指標】

請看如下**:

int main()

;printf

("%p\n"

, arr)

;printf

("%p\n"

,&arr)

;return0;

}

執行結果為:

二者輸出內容相同,這就說明陣列名& 陣列名是等價的嗎?其實不然,請看如下**:

int main()

;printf

("arr = %p\n"

, arr)

;printf

("&arr = %p\n"

,&arr)

;printf

("arr+1 = %p\n"

, arr+1)

;printf

("&arr+1 = %p\n"

,&arr+1)

;return0;

}

執行結果為:

這裡對陣列名 + 1& 陣列名 + 1操作發現二者出現了區別,說明它們有著本質上的差別。

arr指向陣列首元素&arr是陣列指標,指向陣列,二者指向的位址是相同的但型別不同。

arr + 1是指向陣列首元素之後乙個元素的指標。

&arr + 1是指向下乙個陣列,跨過了整個陣列,步距為陣列元素的大小之和。

與陣列指標相混淆的有另乙個名詞:指標陣列

int *p1[10];
它的本質是陣列,陣列中的所有元素都是指標

【二級指標也是乙個指標陣列】

int *arr1[10]

;//整型指標的陣列

char *arr2[4]

;//一級字元指標的陣列

char **arr3[5]

;//二級字元指標的陣列

具體舉例:

const char *arr=

;

對於陣列:

int arr[10] = ;
使用以下函式進行傳參:

//	情況 1

void

test

(int arr[

])

//	情況 2

void

test

(int arr[10]

)

//	情況 3

void

test

(int *arr)

所以以上三種方法都是正確的,內涵也是相同的,讀者使用時可以根據具體情況選擇不同的表現形式,提高**可讀性。對於陣列:

int *arr2[20] = ;
使用以下函式進行傳參:

//	情況一

void

test2

(int *arr[20]

)

//	情況二

void

test2

(int **arr)

所以指標陣列可以當做二級指標來傳參。

對於陣列:

int arr[3][5] = ;
使用以下函式進行傳參:

//	情況 1

void

test

(int arr[3]

[5])

//	情況 2

void

test

(int arr[

])

//	情況 3 

void

test

(int arr[5])

【小結】:

二維陣列傳參,函式形參只能省略第乙個的數字,第二個[ ]中的數字不可省略。

對乙個二維陣列,可以不知道有多少行,但是必須知道一行多少元素。

//	情況一

void

test

(int

(*arr)[5

])

//	情況二

void

test

(int* arr[5]

)

//	情況三

void

test

(int *arr)

//	情況四

void

test

(int **arr)

【小結】:二維陣列可以作為 陣列指標 傳參。

常見的傳參方式如下:

void

print

(int *p, int sz)

}int main()

; int *p = arr;

int sz =

sizeof

(arr)

/sizeof

(arr[0]

);print

(p,sz)

;//一級指標p,傳給函式print

return0;

}

q:那麼當乙個函式的引數部分為一級指標的時候(例如int *),函式能接收什麼引數?

int*型別的一級整型指標

陣列元素型別為int的一維陣列

常見的傳參方式如下:

void

test

(int** ptr)

int main()

q:當函式的引數是二級指標時(例如int **),可以接收什麼引數?

二級指標

指標陣列

指標陣列 陣列指標 陣列傳參

指標陣列 實際上是乙個陣列,陣列中存放的元素是指標 例如 int arr 10 char arr1 5 陣列指標 實際上是乙個指標,指向乙個陣列的指標 例如 int p 10 這就表示乙個p指標,指向乙個大小為10陣列 在陣列傳參的過程中,由於c語言的對於速度的要求的特點,是不會傳整個陣列的,最終陣...

指標陣列陣列傳參 指標引用傳參

指標和陣列作為引數傳入函式時,傳入的是位址,即指向變數的位址和陣列的首位址,可以在函式中改變指標或陣列的值,但本質上它們還是值的傳遞 區別於變數的值傳遞的是 變數值傳遞不會改變實參原來的值。我們無法對指標和陣列的位址進行操作 如 位址賦值,分配記憶體等 要進行位址操作需要使用指標引用或指標的指標。示...

陣列和指標傳參

在我們寫函式時,有沒有被引數型別難到呢?如果有,那就耐心看完本篇部落格吧 一維陣列傳參 二維陣列傳參 總結 陣列傳參時,降級為其內部元素型別的指標,二維陣列傳參,函式的引數只可以省略第乙個 的數字,因為對二維陣列,可以不知道有多少行元素,但必須知道一行有多少元素。引申為,多維陣列傳參,只有第乙個 的...