數(shù)組指針
整型指針:指向整型的指針
字符指針:指向字符的指針
數(shù)組指針:指向數(shù)組的指針
基本概念
下面哪個是數(shù)組指針呢?
指針數(shù)組和數(shù)組指針的概念很容易混淆,一定要分清楚哦!
int *p1[10];
int (*p2)[10];
p1是指針數(shù)組,每個元素的類型是int*
p2是數(shù)組指針,每個元素的類型是int(*)[10]
int (*p2)[10];
//p2先和*結(jié)合,表示p2是一個指針變量
//指向一個大小為10個整型的數(shù)組
//所以p2是數(shù)組指針
注:[ ]的優(yōu)先級高于*,所以必須加上()來保證p2先和*結(jié)合
1.1、代碼示例
int* parr[6];
int* (*pp)[6] = &parr;
pp是一個數(shù)組指針,類型是int*(*)[6],存放的是int*類型的數(shù)組,該數(shù)組有6個元素
一般情況下,去掉變量名,剩下的即為變量類型
如:int* (*pp)[6]去掉變量名pp,變量類型為int*(*)[6]
char arr[5];
char (*pa)[5] = &arr;
pa也是一個數(shù)組指針,變量類型為char(*)[5],指向char類型的數(shù)組,該數(shù)組元素個數(shù)為5
1.2、錯誤示范
你肯定會有一個疑問,變量類型為int(*)[5]的數(shù)組指針,能否指向數(shù)組元素為3或者6的數(shù)組呢?
程序能夠正常編譯,但是會報出如下警告
warning C4048: “int (*)[5]”和“int (*)[3]”數(shù)組的下標(biāo)不同
在正常編寫代碼的時候,我們還是得保證數(shù)組指針和原數(shù)組的元素個數(shù)一致!
arr和&arr的區(qū)別
在進(jìn)一步了解數(shù)組指針之前,我們需要了解arr和&arr的區(qū)別
當(dāng)我們用%p打印arr和&arr時,會發(fā)現(xiàn)它們的結(jié)果是相同的
但這能說明arr和&arr等價了嗎?
并不能!
再來看看下面這串代碼
arr+1跳過4個字節(jié),一個元素int的大小
&arr+1跳過40個字節(jié),整個數(shù)組的大小
其實&arr和arr雖然指向的地址值相同,但是意義不同!
&arr表示的是數(shù)組的地址,是int(*)[10]類型
arr表示數(shù)組首元素的地址,是int*類型
數(shù)組的地址+1,跳過整個數(shù)組的大小
所以&arr+1和&arr的差值為40
對應(yīng)的int(*p)[5]和int* p1也有不同
p接收的是&arr,整個數(shù)組的地址
p1接收arr,數(shù)組首元素的地址
數(shù)組指針的使用
3.1打印一維數(shù)組
下面這串代碼是用整型指針打印數(shù)組元素的情況
除了整型指針外,我們可以利用數(shù)組指針打印元素
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int (*p)[10] = &arr;
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", *((*p) + i));
//*p-->arr
}
printf(" ");
return 0;
}
*p等價于arr,arr+i等價于&arr[i],對arr+i解引用就是arr[i]
但是這種方式實際上是把簡單問題復(fù)雜化了:我們本來就可以用int*指針來打印數(shù)組元素,為何要利用數(shù)組指針來多此一舉呢?
所以在一維數(shù)組里面,我們一般不會這么寫
3.2、打印二維數(shù)組
假設(shè)我現(xiàn)在需要一個print函數(shù)來打印二維數(shù)組
在之前,我們一般會想到用這張方式傳入二維數(shù)組
void print(int a[3][5], int r, int c);
當(dāng)我們想用數(shù)組指針的時候,情況就有些變化了
數(shù)組名是數(shù)組首元素的地址
二維數(shù)組的首元素是第一行
二維數(shù)組的數(shù)組名表示第一行的地址
//main函數(shù)中
print(arr,3,5);
這里prinf里面的arr就需要用數(shù)組指針來接收
該二維數(shù)組是3行5列,每一行都有5個元素,是一個int[5]的數(shù)組
對應(yīng)的數(shù)組指針為int(*)[5]類型
void print(int(*p)[5], int r, int c)
這里的p指針指向的是二維數(shù)組第一行的地址
*p:對p直接解引用
相當(dāng)于拿道了第一行元素的地址(把第一行看作數(shù)組,也就是數(shù)組的地址)
相當(dāng)于是二維數(shù)組第一行首元素的地址
對(p+i)解引用,就能拿到第i行第一個元素的地址
*(p+i)+j第i行第j個元素的地址
*(*(p+i)+j)第i行第j個元素
這一部分和上篇博客指針數(shù)組的內(nèi)容相似
最終的函數(shù)實現(xiàn)如下
void print(int(*p)[5], int r, int c)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j < c; j++)
{
printf("%d ", *(*(p + i) + j));
}
printf(" ");
}
}
int main()
{
int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
print(arr,3,5);
return 0;
}
4練習(xí):判斷
這一站最重要的就是區(qū)別指針數(shù)組和數(shù)組指針
4.1 int arr[5]
int arr[5];
arr是一個整型數(shù)組,有5個元素,每個元素是int類型的
4.2 int*parr[10]
int*parr1[10];
parr1是一個數(shù)組,數(shù)組有10個int*類型的元素
所以parr1是指針數(shù)組
4.3 int (*parr2)[10]
int(*parr2)[10];
parr2和*結(jié)合,表示parr2是一個指針
去掉parr2即為它的變量類型int(*)[10]
所以parr2是一個數(shù)組指針
4.4 int(*parr3[10])[5]
int(*parr3[10])[5];
[]的優(yōu)先級高于*
parr3先和[]結(jié)合,說明parr3是一個數(shù)組
該數(shù)組有10個元素,每一個元素都是一個數(shù)組指針,類型是int(*)[5]
該數(shù)組指針指向的數(shù)組有5個int類型的元素
結(jié)語
第三站數(shù)組指針到這里就結(jié)束啦!
-
代碼
+關(guān)注
關(guān)注
30文章
4788瀏覽量
68625 -
數(shù)組指針
+關(guān)注
關(guān)注
0文章
5瀏覽量
5234
原文標(biāo)題:【C語言】指針進(jìn)階第三站,數(shù)組指針!
文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論