欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 【C语言】数组指针与指针数组

【C语言】数组指针与指针数组

2025/2/25 3:22:34 来源:https://blog.csdn.net/XJ2536877903/article/details/144750782  浏览:    关键词:【C语言】数组指针与指针数组

前言

前面的文章讲了指针的一些基本内容,这里我们来讲一下数组指针与指针数组,数组指针是指针运用的一个明显体现,准确来说是通过指针访问内存地址的具体体现

一、一维数组的指针

首先,我们先来看一段代码

#include <stdio.h>
int main() {int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* pa = &arr[0];int* p = arr;printf("pa -> %p\n", pa);printf("p  -> %p\n", p);return 0;
}

在这里插入图片描述
在上述结果中我们发现,数组arr的首元素地址与arr这个数组的名字是一样的,所以数组名就是首元素的地址


同时在【C语言】自定义类型数据-数组这篇文章中我们说过,数组是一个连续的内存空间,所以,我们可以通过指针的运算来逐一访问数组的元素,请看下面的代码

#include <stdio.h>
int main() {int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* pa = &arr[0];for (int i = 0; i < 10; i++) {printf("%d ", *(pa + i));}return 0;
}

在这里插入图片描述


arr是首元素地址的特殊情况

一、&arr
我们上面说了,数组名arr就是数组arr首元素的地址,那么当我们&arr时,得到的会是什么呢?那让我们看一下下面的代码

#include <stdio.h>
int main() {int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* pa = &arr[0];printf("pa   -> %p\n", pa);printf("parr -> %p\n", &arr);printf("pa + 1   -> %p\n", pa + 1);printf("parr + 1 -> %p\n", &arr + 1);return 0;
}

在这里插入图片描述
结果如下:
pa -> 000000D1FA16F5D8
parr -> 000000D1FA16F5D8
pa + 1 -> 000000D1FA16F5DC
parr + 1 -> 000000D1FA16F600
我们可以发现,pa与pa + 1相差了4个字节,也就是一个整形,但是parr与parr + 1相差了40个字节,隔了一个数组的大小,也就是说,&arr得到的parr是整个数组的地址,当parr + 1时指针会走过一个数组,所以此时的arr不是首元素的地址,而是整个数组

二、sizeof(arr)
我们先看代码

#include <stdio.h>
int main() {int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* pa = &arr[0];printf("sizeof(pa) -> %zd\n", sizeof(pa));printf("sizeof(arr) -> %zd\n", sizeof(arr));return 0;
}

在这里插入图片描述
这里我们可以发现,sizeof(arr)得到的并不是地址的大小,而是arr数组的大小,也就说sizeof(arr)中的arr并不代表着首元素的地址,而是代表整个数组的


二、二维数组指针

我们上面很详细地介绍了一维数组的指针,接下来我们介绍一下二维数组的指针,对于二维数组我们可以如此定义:

类型 (*ptr)[M] = arr;

这里的类型也就是二维数组的元素的数据类型,而ptr则是指针的名称,M则是一行数组的元素数量,我们看下面的代码

#include <stdio.h>
int main() {int arr[2][5] = {1,2,3,4,5,6,7,8,9,10};int(*pa)[5] = arr;return 0;
}

这里我们定义了一个行为2列为5的二维数组指针变量,那么,这个指针变量究竟是什么呢?让我们继续看下面的代码

#include <stdio.h>
int main() {int arr[2][5] = { 1,2,3,4,5,6,7,8,9,10 };int(*pa)[5] = arr;printf("*pa        -> %p\n", *pa);printf("&arr[0]    -> %p\n", &arr[0]);printf("&arr[0][0] -> %p\n", &arr[0][0]);printf("\n");printf("*(pa + 1)  -> %p\n", *(pa + 1));printf("&arr[1]    -> %p\n", &arr[1]);printf("&arr[1][0] -> %p\n", &arr[1][0]);printf("\n");printf("**pa       -> %d\n", **pa);return 0;
}

在这里插入图片描述
其实我们根据结果可以发现二维数组的指针是一个二级指针,而且存放的是一个行数组的指针(arr[0]),也就是首元素地址,当我们进行(pa + 1)时,指针变成了第二行数组的指针(arr[1]),也是第二行数值的首元素地址,我们可以简单用图表示*
在这里插入图片描述
所以通过指针我们也可以对二维数组进行访问


三、指针数组

我们之前说过,数组是一种基本的数据结构,用于存储相同类型的多个值,当然相同类型的多个值也包括指针类型,所以我们可以定义一个数组来存储我们的指针,请看下面的代码

#include <stdio.h>int main() {int* ptrarr[3] = { 0 };int arr[3] = { 1,2,3 };ptrarr[0] = &arr[0];ptrarr[1] = &arr[1];ptrarr[2] = &arr[2];for (int i = 0; i < 3; i++) {printf("ptrarr[%d] -> %p\n", i + 1, ptrarr[i]);}return 0;
}

在这里插入图片描述
这里我们定义了一个整形类型指针数组用来储存我们的整形指针,定义指针类型的方法与定义普通类型的数组是一样的,所以我就不再多讲啦!


End

对于指针的所有内容,博主只能到这个地步啦,谢谢大家的阅读,希望我的文章对大家有帮助!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词