• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

C语言进阶:指针的进阶(2)

c语言 搞代码 4年前 (2022-01-06) 41次浏览 已收录 0个评论
文章目录[隐藏]

这篇文章主要介绍了C语言指针详解及用法示例,介绍了其相关概念,然后分享了几种用法,具有一定参考价值。需要的朋友可以了解下

数组指针

由前面的例子,不难得出,数组指针是指向数组的指针,是指针而非数组。

数组指针的定义

 char ch = 'w'; char* pch = &ch;//字符地址存放在字符指针中 int a = 10; int* pint = &a;//整型地址存放在整型指针中 float f = 0.0; float* pf = &f;//浮点型地址存放在浮点型指针中 

什么变量的地址存放在什么指针中。指针指向变量的类型,决定了指针的类型。顾名思义,数组指针指向的是数组。

递推可得,数组的地址存放在数组指针中。且数组指针的类型为数组的类型再加个* 。

下面那种定义方法是对的呢?

 int arr[10] = { 0 }; //1. int* pa = arr; //2. &arr;//整个数组的地址 int* parr = &arr; //3. int* parr[10] = &arr; //4. int(*parr)[10] = &arr; 

取出的是首元素的地址,而非整个数组的地址
整型指针应存放整型变量的地址,数组的地址无法存入整型指针中。
[]的优先级比*高,故parr先与[]结合成数组名,所以parr是个指针数组。

数组指针的类型由数组类型决定,先找出数组的类型int[10](去掉名就是类型)。且不能让[]先与parr结合,所以用()先将parr和*结合,即成int(*parr)[10]。

C语言规定[]必须再最后面,所以不可写成int[10](*parr)。

 int* parr[10];//指针数组 int(*parr)[10];//数组指针 

我们前面强调过,去掉名字就是类型。所以int[10]是整型数组的类型,int*[10]是指针数组的类型,int(*)[10]是数组指针的类型。

&数组名和数组名

之前介绍过不止一遍,所以这次只说重点。

指针类型决定了指针±整数的步长。

 //首元素地址+1 printf("%p\n", arr);//0073FCA4 printf("%p\n", arr + 1);//0073FCA8 //整个数组地址+1 printf("%p\n", &arr);//0073FCA4 printf("%p\n", &arr + 1);//0073FCCC 

1.首元素地址就是整型指针+1,自然只能向后访问4shou个字节

2.整个数组地址+1,即int(*)[10]型指针+1,向后访问了 i n t × 10 int×10 int×10即40个字节。

sizeof(arr)也代表整个数组,现在去理解为什么sizeof里数组名代表的是整个数组呢?数组这种结构保存了数组的大小,sizeof求所占空间的长度,那自然要严谨一些了。

数组指针的使用

遍历数组,使用数组或是指针作形参接收就行了。且所谓的用数组接收仅是理解层面,本质上都是指针。

 void Print1(int arr[], int sz) { for (int i = 0; i <sz; i++) { //printf("%d ", arr[i]); printf("%d ", *(arr + i)); } } void Print2(int* arr, int sz) { for (int i = 0; i <sz; i++) { printf("%d ", arr[i]); //printf("%d ", *(arr + i)); } } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); Print1(arr, sz); Print2(arr, sz); return 0; } 

反面用例

数组作实参,用数组或指针接收即可。数组指针使用对了很好用,但如果随便用可能会很别扭。下面先介绍强行使用数组指针的用法。

 //错误示范 void Print3(int(*pa)[10], int sz) { for (int i = 0; i <sz; i++) { //printf("%d ", pa[i]); printf("%d ", *(pa + i)); } } 

将整个数组地址传过去,则用数组指针接收,然后呢,直接对pa解引用吗?

结果显然是错误的,从结果中也可以看出打印的是十进制下的地址,+1跳过40个字节。

这里笔者在学习的时候产生了个疑问,传过去数组的地址,为什么解一层引用后还是地址呢?

&arr解引用*后相当于找到首元素的地址,可以理解为&和*相互抵消只剩下arr不就是首元素的地址嘛~

 void Print4(int(*pa)[10], int sz) { for (int i = 0; i <sz; i++) { printf("%d ", *(*(pa)+j)); } } 

倘若我们把一维数组看作是二维数组第一行。由于二维数组在内存中是连续存放的,我们只打印二维数组的第一行,便可以避免上面的错误。

style=“zoom:80%;” />

*(pa)相当于数组指针所指向数组的数组名。数组指针指向整个数组,将其看作二维数组并解引用得到一行的首元素,从而遍历访问。

正面用例

从上面的例子也可以看出,用数组指针访问二维数组时,效果便不错。

 //二维数组传参,用二维数组接收 void Print1(int arr[3][5], int r, int c) { for (int i = 0; i <r; i++) { for (int j = 0; j <c; j++) { //printf("%d ", arr[i][j]); printf("%d ", *(*(arr + i) + j)); } printf("\n"); } } 

上面的例子,是正常二维数组传参,二维数组接收的情况。下面我们用数组指针接收。

 //二维数组传参,用数组指针接收 void Print2(int(*pa)[5], int r, int c) { for (int i = 0; i <r; i++) { for (int j = 0; j <c; j++) { //1. printf("%d ", pa[i][j]); //2. printf("%d ", *(*(pa + i) + j)); } printf("\n"); } } int main()来源gaodai#ma#com搞*!代#%^码网 { int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 }; Print2(arr, 3, 5);//二维数组首元素是首行 retur

以上就是C语言进阶:指针的进阶(2)的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:C语言进阶:指针的进阶(2)

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址