3、数组指针
1.数组指针的定义
数组指针是指针还是数组 ?
答案是∶指针
我们已经熟悉︰
整形指针 : int p* ; 能够指向整形数据的指针。
浮点型指针 : float pf* ; 能够指向浮点型数据的指针。
那数组指针应该是︰能够指向数组的指针。数组指针和指针数组要区分开来。
整型指针 —> 指向整型的指针
字符指针 —> 指向字符的指针
数组指针—> 指向数组的指针----->eg : int (*p)[10]=NAll ;
首先,我们要知道[]的优先级是比 * 要高的,对于形式1,p1会先与[ ]结合,在与 * 结合,所以形式1是指针数组,()的优先级又比[]高,所以p2会先于 * 结合,在与[ ]结合,所以形式2是数组指针。
到这里,相信你对数组指针有了一定了解,哪么怎么建立数组指针呢
?
✳
例如:给定char arr[5],请写出用来表达char arr[5]的数组指针**
先分析char* arr[5],很明显,这是一个指针数组,数组名是arr,有五个元素,数组的类型是char*,我们已知数组指针 - 指向数组的指针 - 存放数组的地址,所以应该对数组取地址,即&arr,如何应该定义一个有五个元素的指针存放数组的地址,即(p)[5],指针类型为char,所以数组指针是char* (*p)[5] = &arr
不成熟的说指针的指针相当于二级指针,肯定有两个 “ * ”
所以我们现在会写数组指针了。
来试一试!
例如:
- 写出char* arr[10]的数组指针
char*( *pa)[10] = &arr
- 写出int* par[2]的数组指针
int*( *pa)[2] = &par
2. & 数组名 和 数组名
我们看到打印的结果都是一样的,那么数组名arr和数组的地址 & arr是一样的吗?
从地址值来看,两者是一样的,但是两者的含义和使用是不同的:
int* p1; p1+1 表示跳过一个int类型的长度,也就是4个字节
char* p2; p2+1表示跳过一个char类型的长度,也就是1个字节
int(p3)[10]; p3+1表示跳过一个具有10个整型长度的数组,也就是410=40个字节
3.数组指针的使用
① 对一维数组的使用
我们先看这个例子:
通过数组指针解引用找到数组,再用方括号[ ],去找到数组中的每个元素。
这种并非数组指针的常用方式,因为用起来很“别扭”。
这种方式不如首元素地址 + i 流畅:
数组指针的使用,一般常见于二维数组及其以上
当我们在谈首元素的时候,一维数组的首元素就是第一个元素,二维数组的首元素要先将二维数组看作一维数组(该数组中每一个元素都是一个一维数组),那二维数组的首元素就是第一个一维数组。那么二维数组的首元素地址就是第一个一维数组的地址!(不是第一个一维数组中第一个元素的地址,虽然值相同,但含义和使用不同)
② 对二维数组的使用
结果展示:
图解:
注意:对一个存放数组地址的指针进行解引用操作,找到的是这个数组,也就是这个数组的数组名,数组名这时候又表示数组首元素地址!
*( p + i ):相当于拿到了一行 相当于这一行的数组名 ( *p + i )[ j ] <===> *(*(p + i ) + j )
为了更好的理解这一点,我们来看这个例子:
恍然大悟
**总结:**我们对一个数组指针变量进行解引用操作,比如int(*p)[10],得到的是一个数组,或者说是这个数组的数组名,而数组名又可以表示该数组首元素的地址。如果要找到该数组中的每一个元素,就需要对这个数组元素的地址进行解引用操作。
简单点来说就是,对一个数组指针类型进行解引用操作,得到的还是地址,对这个地址在进行相应的解引用操作,才能得到数组中的具体的元素。
巩固练习
下面这些代码的含义是什么?
解析:
int( parr3 [10])[ 5 ]; 拿掉数组名后,剩下 int()[5]就是这个数组的类型
问题1:parr2 = &parr1;//能否将数组parr1的地址放到parr2中呢?
答:不能,因为类型不匹配,parr2指向的类型应该是 int[10] parr1 是 int* [10];
4、数组参数、指针参数
1.一维数组传参
答案:以上五种传参方式均ok
**注意:**一维数组传参可以传数组形式,也可以传指针形式,传数组形式的时候数组元素的个数可以不写,也可以写,传指针的时候要注意指针的类型,也就是指针指向什么类型的元素,
比如说指针指向int类型元素,那么指针的类型就是 int*
2.二维数组传参
总结 : 二维数组传参,函数形参的设计只能省略第一个[ ]的数字。
因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
这样才方便运算。
二维数组传参也能写成指针的形式,指针的类型应该是数组指针。
3.一级指针传参
思考1:这里的指针传参可以用数组去接收吗?
经过实验我们可以看到这样做是没问题的,指针传参可以用数组去接收!
思考2:当一个函数的参数部分为一级指针的时候,函数能接收什么参数 ?
例如:int * p
再例如:char* p
注意:
int* p1;
int* p2;
靠近int 或者靠近变量p实际的意义和效果没区别,是一样的。 一般我们习惯用int p2这种写法,这样可以明确表示指针变量p2的类型。*