案例描述
本案例主要讲解的主要知识有两个:一是函数指针,该知识将在选择求和函数时使用;二是指针与二维数组的联系。本案例中的存储基于二为数组,数据的获取利用数组指针,下面分别讲解这两个知识点:
必备知识
1,指针与二维数组
在之前的案例中,我们学习了如何用指针引用一维数组,二维数组与多维数组同样有地址,也可以使用指针引用,只是因为其逻辑结构较一维数组复杂,所以操作也比较复杂。这里我们来介绍指针和二维数组的关系。
假设要定义一个二行三列的二维数组,示例如下:
int a[2][3] = {
{
1,2,3}{
4,5,6}};
其中 a 是二维数组的数组名,该数组中包含两行数据。二维数组的数组指针同样指向数组中的第一个元素的地址,只是二维数组中的元素不是单独的数据,而是由多个数据组成的一维数组。
假设数组中的数据类型为int,每行有n个元素,则数组指针每加一,指针实际移动的步长为n*sizeof(int)
另外:a[0],a[1]相当于二维数组中一维数组的数组名,指向二维数组对应行的第一个元素,a[0] = &a[0][0] ; a[1] = &a[1][0];
二维数组中相关指针与数据的表示形式
- 表示形式 含义
- a 二维数组名,指向一维数组a[0],也是a[0][0]的地址
- a[i],*(a + i) 一维数组名,表示二维数组第i行元素首地址,值为&a[i][0]
- *(a + 1)+j 二维数组元素地址,二维数组中最小数据单元地址,等价于&a[i][j]
- ((a+1)+j) 二维数组元素,表示第i行,第j列数据的值,等价于a[i][j]
2,作为函数参数的二维函数
一维数组的数组名就是一个指针,若要将一维数组传入函数,只需传入数组名,或指向该数组首地址的指针即可。假设要将一维数组a[5]传入func()函数中,函数声明如下:
func(int a[]);
函数调用时的形式如下
func(a);
若在程序中定义一个指向该一维数组的指针
int *p = a;
则也可以将该指针传入函数,其形式如下
func(p);
若使用一维数组指针传值得方式类比二维数组,很容易将其传入的参数声明为“int **arr”,但这样写是不对的,因为int **arr是一个二级指针,它声明的是一个指向整型指针的指针,而非指向整形数组的指针。
若将二维数组传入函数,形式相对略微复杂,一维数组可以不关心数组中数据的个数,但二维数组即有行,又有列,是在定义时行值可以缺省,列值不能缺省,所以将二维数组的指针传递到函数中时必须满足数组的列值,定义一个数组指针的形式如下:
数据类型(*数组指针名)[列号]
假设现在要将数组a[4][5]传入函数func(),则其现实如下:
int (*p)[5] = a;
func(p);
在这里要注意指针数组与数组指针的区别。指针数组表示数组元素都为指针的一个数组,其定义形式的区别在于*和[]与变量名结合的优先顺序,切记在定义数组指针时()不可丢失,因为[]的优先级高于**,所以如果没有小括号,该变量就会被编译为指针数组。
函数指针<