天天看點

C語言—指針數組與數組指針

前言:

看到标題的小夥伴可能會有點疑惑,什麼是指針數組,數組指針??傻傻分不清楚,不怕,聽我慢慢道來。

正文:

要想弄清楚這兩個概念,我們不妨舉幾個例子:

1、數組:

int arr[5] = {1,2,3,4,5};

這就是最簡單的數組,數組中每個元素都是int類型,下面的圖檔幫助大家很容易了解。

C語言—指針數組與數組指針

數組可以将相同類型的資料整合到一起,你可以通過下标的方式或者指針的方式來通路,在這裡不多贅述。

2、指針數組:

int *parr1[10]

形如以上形式的,叫做指針數組,其中:paar1先與[10]結合為parr1[10],為一個有10個元素的數組,其次再與int*結合,及每個元素的類型是int*。以下圖檔更友善大家了解:

C語言—指針數組與數組指針

 注意:指針數組,本質上parr1是數組,因為優先級的關系,parr1先與[]結合,但是接下來要介紹的數組指針正好相反。

3、數組指針

int(*parr2)[10]

在第2點已經說過,數組指針因為()的緣故,優先級很高,是以parr2先與*結合為指針,并且是指向數組的指針,後面的[10]表示指向的數組裡面有10個元素,每個元素為int型。下面的圖更友善大家了解:

C語言—指針數組與數組指針

注意:此時的parr2是一個指針,如果把指針名parr2去掉,剩餘的部分就是指針類型,:int(*)[10]

 這就是數組指針,其實并沒有想象的那麼神秘!

4、數組指針的應用

這裡為大家分享一下數組指針的幾個小應用。

  • 數組指針一般 = 右側是整個數組的位址;
  • 當數組指針指向一維數組的時候(當然基本上沒人這麼用),形式如下:
int(*pa)[5] = &arr

注意:

  1. 這裡pa是數組指針,指向數組中有5個元素,數組元素是int型。
  2. &+數組名就是整個數組的位址,其數值上雖然與首元素位址相同,但是意義完全不一樣。
  3. pa指針指向的是整個數組的位址,那麼*pa(将指針解引用)取出的是整個數組的位址(也是數組首元素的位址)
  4. **pa取出的是第一個元素,與*pa[0]的效果等價。
  • 當數組指針指向二維數組中時,這個用法很常見,有些書上面稱這種指針為行指針,顧名思義就是操縱一行的指針,形如:
void print_arr2(int(*arr)[5], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
	//數組名arr,表示首元素的位址
	//但是二維數組的首元素是二維數組的第一行
	//是以這裡傳遞的arr,其實相當于第一行的位址,是一維數組的位址
	//可以數組指針來接收
	print_arr2(arr, 3, 5);
	return 0;
}
           

運作結果: 

C語言—指針數組與數組指針

注意:

  1. 上述代碼我們定義了一個3行5列的二維數組,需要注意的是,二維數組可以不寫明行,但是必須寫明列,這裡我們用數組指針來接收,也必須注明是5列,這是為了告訴記憶體第二行在哪裡開始存放
  2. 我們将arr數組名傳參過去,在一維數組中arr數組名代表首元素的位址,但在二維數組中,arr數組名代碼的是第一行的位址,是以這也是行指針的由來。
  3. 形參中的int(*arr)[5]中存放的是:二維數組第一行的位址,也就是說arr代表的是第一行的位址。
  4. *arr就是二維數組第一個元素的位址,本代碼也就是1的位址;**arr才找到第一個元素,即1。
  5. (arr+1)是第二行的位址,*(arr+1)是第二行首元素的位址,*(*(arr+1))是第二行首元素,即6。

結語:

想必大家看過我的blog應該對數組指針與指針數組有了初步的了解

這也是我本人第一次寫blog,還請各位大佬手下留情!

最後,放一道思考題:

請問以下代碼代表什麼意思:

int(*parr3[10])[5]

答案就是:

  • paar3是一個數組,數組中有10個元素,每個元素的類型是:int(*)[5];
  • paar3是存放數組指針的數組。

繼續閱讀