C++编程入门 互动版

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器

指针与数组名

看了上一节的例子,我们知道了,数组元素不仅可以通过下标来获取,还可以通过指针获取,而且用指针获取数组元素效率更高,所以推荐使用指针获取元素。但也有同学会有疑问:为啥数组名s等价于数组第一个元素的内存地址&s[0]? C++语言规定数组名是一个指针常量,它表示数组首元素的地址,因为是常量所以其值不能改变。

指针与数组元素

int a[5];
int *p=a;

上面的代码定义了int型数组a,int型指针p指向数组a的首元素a[0]。对于数组a的元素访问方法由四种:

1.下标表示。a[i],其中i=0,1,2,3,4。这个很熟悉,不解释。

2.下标表示。p[i],其中i=0,1,2,3,4。这个是新的,p=a嘛,都是数组首元素的地址,所以可以这样用。

3.指针表示。*(p+i),其中i=0,1,2,3,4。这里解释下,上一节也说过,指针加一个数值i是指加i个int型占内存的字节数。

4.指针表示。*(a+i),其中i=0,1,2,3,4。p=a嘛,所以也可以这样用。

int a[3][2];
int *p=a;

这里定义了二维数组a,它有3行2列共6个元素。实际上,这6个元素在内存中是顺序排列的。但理解上,也可以这样想,数组a由3个一维数组a[0],a[1],a[2]构成,每个一维数组又由2个元素组成,例如a[0]又由a[0][0]和a[0][1]构成。那么就有下面的关系了,这个地方需要好好消化:

a表示二维数组的首地址,也是数组第0行的首地址,a+1表示数组第1行的首地址,a+2表示数组第2行的首地址

a[0]表示数组第0行的首地址,a[1]表示数组第1行的首地址,a[2]表示数组第2行的首地址

a,a[0],*a,&a[0][0]四个都是第0行第0列的元素的内存地址。

a+1,a[1],*(a+1),&a[1][0]四个都是第1行第0列的元素的内存地址。

a[1]+1,*(a+1)+1,&a[1][1]四个都是第1行第1列的元素的内存地址。

指向数组的指针和指针数组

上一知识点学习的是指向数组元素的指针,这里先看指向数组的指针:一个二维指针,常常用来指向二维数组中的某一行。另外还有指针数组:一个数组,每个元素都是指针类型。例如:

int a[3][5],(*p1)[5],*p2,*p3[5];
p1=a+1;
p2=a;

重点看第一行的声明。a是一个二维数组。p1是一个指向具有5个int型元素的一维数组的指针,也就是说p1是一个指针,只不过它指向的元素是一个数组,该数组是一维的,由5个整型元素构成。p2就是一个普通的int型指针,它指向int变量。p3是一个一维数组,不过特殊在该数组的每个元素都是int型指针。

第二行执行后p1指向数组a的第1行,p1+2指向数组a的第2行

注意第三行是错误的,因为a表示数组a第0行的地址,第0行是一维数组。而p2只能接收int变量的地址,所以不能把数组的地址赋值给p2。

在右侧代码框中编写程序:定义一个3行5列的整型二维数组,由用户输入数组各个元素的数值,分别用下标和指针的方法输出该二维数组的各个元素的值。