前言:
此篇是针对 用指向数组的指针作函数参数 方面的练习。
解题思路:
这个题目是很简单的。本例用指向数组的指针作函数参数。用函数 average 求总平均成绩,用函数 search 找出并输出第 i 个学生的成绩。
正文:
#include<stdio.h>
int main() {
void average(float * p,int n);
void search (float(*p)[4],int n);
float score[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};
average(*score,12); //求12个分数的平均分 *score 为列指针
search(score,2); //求序号为2的学生的成绩
return 0;
}
void average(float * p,int n){ //定义求平均成绩的函数
float * p_end;
float sum = 0,aver;
p_end=p+n-1; //n的值为12时,p_end的值是p+11,指向最后一个元素
for(;p<=p_end;p++)
sum=sum+(*p);
aver=sum/n;
printf("average=%5.2f\n",aver);
}
void search (float(*p)[4],int n){ //p是指向具有4个元素的一维数组的指针
int i;
printf("The score of No.%d are:\n",n);
for(i=0;i<4;i++)
printf("%5.2f ",*(*(p+n)+i));
printf("\n");
}
注意:
①
二维数组分为 行指针 与 列指针 。
eg:
a,a+1,a+2…都为 行指针,指向行的地址。
a[0],a[0]+1,a[0]+2…都为 列指针,指向列的地址。
②
实参与形参如果是指针类型,应当注意它们的 类型必须一致 。
eg:
在 main 函数中调用 search 函数时,实参是 score ,形参 p 指向包含4个整型元素的一维数组,二者类型是一致的,程序中调用 search 函数的形式是正确的,即:
search(score,2); //用 score(即score[0]的起始地址)作为实参
如果写成下面这样就不对了:
search(*score,2); //用 *score(即score[0][0]的地址)作为参数
虽然 score 和 * score 都是地址,但后者的类型与形参 p 的类型不匹配。
程序分析:
在 main 函数中,先调用 average 函数以求总平均值。在函数 average 中形参 p 被声明为 float * 类型(指向 float 型变量)的指针变量。它的基类型为 float 型,实参用 * score,即 score[0] ,也就是 &score[0][0] ,即 score[0][0] 的地址。把 score[0][0] 的地址传给 p,使 p 指向 score[0][0] 。然后在 average 函数中使 p 先后指向二维数组的各个元素,p 每加 1 就改为指向 score 数组的下一个元素,见图8.26。形参 n 代表需要求平均值的元素的个数,实参12表示要求12个元素值的平均值。p_end是最后一个元素的地址。sum 是累计总分,aver 是平均值。在函数中输出 aver 的值,函数无需返回值。
函数 search 的形参 p 的类型是 float( * )[4] ,它不是指向整型变量的指针变量,而是指向包含4个元素的一维数组的指针变量。函数调用开始时,将实参 score 的值(代表该数组 0 行起始地址)传给 p,使 p 也指向 score[0] 。p+n 时 score[n] 的起始地址,* (p+n)+i 是 score[n][i] 的地址,*( *(p+n)+i)是 score[n][i] 的值。现在实参传给形参 n 的值是 2 ,即想找序号为2的学生的成绩(3个学生的序号分别为0,1,2)。
调用 search 函数时,实参时 score(二维数组名,代表该数组 0 行起始地址)传给 p ,使 p 也指向 score[0]。p+n 是 score[n] 的起始地址,*(p+n)+i 是 score[n][i] 的地址, * ( *(p+n)+i)是 score[n][i] 的值。现在 n=2 ,i 由 0 变到 3,for 循环输出 score[2][0] 到 score[2][3] 的值。
总结:
运行结果: