指针这一块内容比较抽象,所以下面的讲解主要以举例为主
实例代码:
#include<bits/stdc++.h> //gcc编译器的万能头
using namespace std;
int main() {
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; //定义一个二维数组并初始化
int (*p)[4]; //定义行指针
p=a;
cout << *(*p+2)<<endl; //是数组中第一行第三列元素,即3
cout << *(*(p+1)+1)<<endl; //是数组中第二行第二列元素,即6
cout << *(*(p+2)+2)<<endl; //是数组中第三行第三列元素,即11
cout << *(*p+2)+1<<endl; //是数组中第一行第三列元素加1,即4
return 0;
}
//下面作为一个参考
/* 1 2 3 4
5 6 7 8
9 10 11 12 */
运行结果:(先思考一下为什么这么输出,下面再具体区分)
3
6
11
4
下面来分析一下行指针:
代码解读:
int (*p)[4];
p=a;
int (*p)[4]
是一个指针,它指向一个包含4个整型元素的数组,p=a,相当于把二维数组的第一行地址赋给p这个指针,这样可以通过p来访问二维数组的每一行。
//假设一个数组
int a[n][m];
int (*p)[m];
p=a;
//举一个例子说明行指针的移动
——>1 2 3 4 //行指针,顾名思义,映射到矩阵上那就是,上下移动的指针。
——>5 6 7 8
——>9 10 11 12
含义 对应
p 指向二维数组a的第一行的指针 行指针
*p 对行指针p解引用,得到二维数组a第一行地址 二维数组a第一行地址
*(p+1) 首先行指针向下走一个单位,然后解引用,得到二维数组a的第二行地址 二维数组a的第二行地址
*(*p+1) 先得到二维数组a第一行地址,再向右移动一个单位,即a[0][1] a[0][1]的值
在解引用得到a[0][1]的值
*(*p+1)+1 先得到二维数组a第一行地址,再向右移动一个单位,即a[0][1] a[0][1]的值+1
在解引用得到a[0][1]的值,得到a[0][1]的值后+1
//其他的用以上情况稍微推一下即可
另外注意一下*p+1和*(*p+1)的区别,就是注意下运算符优先级问题,
还有就是:
别越界
别越界
别越界
重要的事情说三遍。
作者的建议:针对初学者而言,指针是一个比较抽象的概念,(作者初学时也没怎么弄懂),但编程毕竟是一门实践型学科,还是要多打代码,多练习,才能理解,比如这个行指针概念,去亲身试验一下,多找几个样例,慢慢就理解了。
最后说一下使用指针的好处:在C/C++中,通过指向数组的指针可以更灵活地操作数组元素,特别是在处理多维数组时。通过这种方式,可以方便地访问数组中的特定行或列,以及进行数组元素的遍历和操作。