A B C
将2个盘子从B移到C的过程 A B C
将2个盘子从B移到C的过程 A B C
将2个盘子从B移到C的过程
由上面的分析可知:将n个盘子从A座移到C座可以分解为以下3个步骤: (1) 将A上n-1个盘借助C座先移到B座上 (2) 把A座上剩下的一个盘移到C座上
(3) 将n-1个盘从B座借助于A座移到C座上 可以将第(1)步和第(3)步表示为:
将“one”座上n-1个盘移到“two”座(借助“three”座)。
在第(1)步和第(3)步中,one 、two、three和A、B、C的对应关系不同。 对第(1)步,对应关系是one对应A,two对应B,three对应C。 对第(3)步,对应关系是one对应B,two对应C,three对应A。 把上面3个步骤分成两类操作:
(1) 将n-1个盘从一个座移到另一个座上(n>1)。这就是大和尚让小和尚做的工作,它是一个递归的过程,即和尚将任务层层下放,直到第64个和尚为止。
(2) 将1个盘子从一个座上移到另一座上。这是大和尚自己做的工作。 编写程序。
用hanoi函数实现第1类操作(即模拟小和尚的任务) 用move函数实现第2类操作(模拟大和尚自己移盘) 函数调用hanoi(n,one,two.three)表示将n个盘子从“one”座移到“three”座的过程(借助“two”座)
函数调用move(x,y)表示将1个盘子从x 座移到y 座的过程。x和y是代表A、B、C座之一,根据每次不同情况分别取A、B、C代入 #include
{ void hanoi(int n,char one,
char two,char three); int m;
printf(“the number of diskes:\ scanf(\
printf(\ hanoi(m,'A','B','C'); }
void hanoi(int n,char one,char two,
char three)
{ void move(char x,char y); if(n==1)
move(one,three); else
{ hanoi(n-1,one,three,two); move(one,three);
hanoi(n-1,two,one,three); } }
void move(char x,char y) {
printf(\ }
7.7数组作为函数参数 7.7.1数组元素作函数实参 7.7.2数组名作函数参数 7.7.3多维数组名作函数参数 7.7.1数组元素作函数实参
例7.9 输入10个数,要求输出其中值最大的元素和该数是第几个数。 7.7.1数组元素作函数实参 解题思路:
定义数组a,用来存放10个数
设计函数max,用来求两个数中的大者
在主函数中定义变量m,初值为a[0],每次调用max函数后的返回值存放在m中
用“打擂台”算法,依次将数组元素a[1]到a[9]与m比较,最后得到的m值就是10个数中的最大者
#include
{ int max(int x,int y); int a[10],m,n,i;
printf(“10 integer numbers:\\n\ for(i=0;i<10;i++) scanf(\ printf(\
for(i=1,m=a[0],n=0;i<10;i++) { if (max(m,a[i])>m) { m=max(m,a[i]); n=i; } }
printf(“largest number is %d\\n\ printf(“%dth number.\\n“,n+1); }
int max(int x,int y)
{ return(x>y?x:y); } 7.7.2数组名作函数参数
除了可以用数组元素作为函数参数外,还可以用数组名作函数参数(包括实参和形参) 用数组元素作实参时,向形参变量传递的是数组元素的值 用数组名作函数实参时,向形参 传递的是数组首元素的地址 7.7.2数组名作函数参数
例7.10 有一个一维数组score,内放10个学生成绩,求平均成绩。 解题思路:
用函数average求平均成绩,用数组名作为函数实参,形参也用数组名 在average函数中引用各数组元素,求平均成绩并返回main函数 #include
{ float average(float array[10]); float score[10],aver; int i; printf(\ for(i=0;i<10;i++)
scanf(\ printf(\
aver=average(score); printf(\ return 0; }
定义实参数组
float average(float array[10]) { int i;
float aver,sum=array[0]; for(i=1;i<10;i++)
sum=sum+array[i]; aver=sum/10; return(aver); }
定义形参数组 相当于score[0] 相当于score[i]
例7.11 有两个班级,分别有35名和30名学生,调用一个average函数,分别求这两个班的学生的平均成绩。 解题思路:
需要解决怎样用同一个函数求两个不同长度的数组的平均值的问题
定义average函数时不指定数组的长度,在形参表中增加一个整型变量i 从主函数把数组实际长度从实参传递给形参i 这个i用来在average函数中控制循环的次数 为简化,设两个班的学生数分别为5和10 #include
{ float average(float array[ ],int n);
float score1[5]={98.5,97,91.5,60,55}; float score2[10]={67.5,89.5,99,69.5,
77,89.5,76.5,54,60,99.5}; printf(“%6.2f\\n”,average(score1,5)); printf(“%6.2f\\n”,average(score2,10)); return 0; }
float average(float array[ ],int n) { int i;
float aver,sum=array[0]; for(i=1;i sum=sum+array[i]; aver=sum/n; return(aver); } 调用形式为average(score1,5)时 相当于score1[0] 相当于score1[i] 相当于5 float average(float array[ ],int n) { int i; float aver,sum=array[0]; for(i=1;i sum=sum+array[i]; aver=sum/n; return(aver); } 调用形式为average(score2,10)时 相当于score2[0] 相当于score2[i] 相当于10 例7.12用选择法对数组中10个整数按由小到大排序。 解题思路: 所谓选择法就是先将10个数中最小的数与a[0]对换;再将a[1]到a[9]中最小的数与a[1]对换??每比较一轮,找出一个未经排序的数中最小的一个 共比较9轮 a[0] a[1] a[2] a[3] a[4] 3 6 1 9 4 1 6 3 9 4 1 3 6 9 4 1 3 4 9 6 1 3 4 6 9 小到大排序 #include { void sort(int array[],int n); int a[10],i; printf(\ for(i=0;i<10;i++) scanf(\ sort(a,10); printf(\ for(i=0;i<10;i++) printf(\ printf(\ return 0; } void sort(int array[],int n) { int i,j,k,t; for(i=0;i for(j=i+1;j if(array[j] array[k]=array[i]; array[i]=t; } } 在sort[i]~sort[9]中,最小数与sort[i]对换 7.7.3多维数组名作函数参数 例7.13 有一个3×4的矩阵,求所有元素中的最大值。 解题思路:先使变量max的初值等于矩阵中第一个元素的值,然后将矩阵中各个元素的值与max相比,每次比较后都把“大者”存放在max中,全部元素比较完后,max 的值就是所有元素的最大值。 #include { int max_value(int array[][4]); int a[3][4]={{1,3,5,7},{2,4,6,8}, {15,17,34,12}}; printf(“Max value is %d\\n”, max_value(a)); return 0; } 可以省略 不能省略 要与形参数组第二维大小相同 int max_value(int array[][4]) { int i,j,max; max = array[0][0];