一、学习内容
本次课我们重点学习了怎样向函数传递数组,鉴于大家对函数和数组的理解和运用还存在一些问题,下面通过一些实例加以说明,希望同学们能够认真阅读和理解。
例1:火柴棍拼数字
要用火柴棍拼出0-9之间的数字,输入任意一个数字,输出需要多少根火柴棍。用火柴棍拼数字0-9的拼法如图所示:
对于这道题,我们学过分支结构后,就可以编程实现。代码如下:
#include <stdio.h> int main() { int digit,count; printf("请输入0-9之间的数字 "); scanf("%d",&digit); switch(digit) { case 0: case 6: case 9: count= 6;break; case 1: count= 2;break; case 2: case 3: case 5: count= 5;break; case 4: count= 4;break; case 7: count= 3;break; case 8: count= 7;break; } printf("拼出数字%d需要%d根火柴 ",digit,count); return 0; }
现在我们对例1进行扩展
例2:火柴棍等式:有16根火柴,可以拼出多少个形如“A+B=C”的等式,A、B、C是用火柴棍拼出的整数,且为一位数,输出该等式形式。
在学过循环结构之后,我们可以采用穷举法来完成。代码如下:
#include <stdio.h> int main() { int a,b,c,count1,count2,count3; for(a=0;a<=9;a++) { for(b=0;b<=9;b++) { c = a + b; if(c > 9) break; switch(a) { case 0: case 6: case 9: count1= 6;break; case 1: count1= 2;break; case 2: case 3: case 5: count1= 5;break; case 4: count1= 4;break; case 7: count1= 3;break; case 8: count1= 7;break; } switch(b) { case 0: case 6: case 9: count2= 6;break; case 1: count2= 2;break; case 2: case 3: case 5: count2= 5;break; case 4: count2= 4;break; case 7: count2= 3;break; case 8: count2= 7;break; } switch(c) { case 0: case 6: case 9: count3= 6;break; case 1: count3= 2;break; case 2: case 3: case 5: count3= 5;break; case 4: count3= 4;break; case 7: count3= 3;break; case 8: count3= 7;break; } if(count1+count2+count3 == 12) printf("%d+%d=%d ",a,b,c); } } return 0; }
在完成上面的程序过程中,我们发现三个switch结构的语句完全是一样的,都是实现计算拼出一个数字需要多少根火柴的功能,那么我们就可以考虑,把这部分重复的代码提取出来,单独设计成一个函数。
例3:利用函数实现火柴棍等式。代码如下:
#include <stdio.h> int num(int n); int main() { int a,b,c,sum; for(a=0;a<=9;a++) { for(b=0;b<=9;b++) { c = a + b; if(c > 9) break; sum = num(a)+num(b)+num(c); if(sum == 12) printf("%d+%d=%d ",a,b,c); } } return 0; } int num(int n) { int count=0; switch(n) { case 0: case 6: case 9: count= 6;break; case 1: count= 2;break; case 2: case 3: case 5: count= 5;break; case 4: count= 4;break; case 7: count= 3;break; case 8: count= 7;break; } return count; }
明显,例3的代码比例2的代码要简洁。
对于一个程序,如果实现的功能比较单一,那么直接在main函数完成就可以,如果实现的功能比较复杂,那么从程序的模块化设计出发,应将每一个功能设计为一个函数,如本次实验要求大家完成的成绩管理问题;另外,如果程序中存在代码的重复使用,那么也应该考虑是否将重复代码实现的功能设计为一个单独的函数,如火柴棍等式问题。
在使用函数的过程中,需要注意以下问题:
(1)函数中定义的变量(包括形参),它只在本函数范围内起作用,我们称之为局部变量。在其他函数中是不能使用本函数定义的变量的。
(2)简单变量做函数参数和数组做函数参数存在着本质的不同。
简单变量做参数,实现的是值的单向传递,即只能把实参的值传给形参,由于实参和形参占用不同的内存单元,形参的改变不会影响实参。
数组做函数参数,是将实参数组的地址传给形参数组,实参和形参占用的是相同的内存空间。
当我们学习了数组之后,有些程序可以通过使用数组进行优化。例如火柴棍问题,可以将火柴棍数存储在一个数组中
int match[10]={6,2,5,5,4,5,6,3,7,6};
则数字a的火柴棍数就是match[a]。代码如下:
#include <stdio.h> int main() { int a,b,c,sum; int match[10]={6,2,5,5,4,5,6,3,7,6}; for(a=0;a<=9;a++) { for(b=0;b<=9;b++) { c = a + b; if(c > 9) break; sum = match[a]+match[b]+match[c]; if(sum == 12) printf("%d+%d=%d ",a,b,c); } } return 0; }
在使用数组的过程中,特别需要强调的是数组越界问题。由于C语言不会对数组越界做检查,这就需要我们自己在写程序的过程中格外小心。
例如: int a[10];
数组定义大小是10,那么数组元素是从a[0]到a[9]。
数组的数据处理通常是通过循环结构来完成的,需要注意此时循环变量的初值是0,循环条件是i<10,那么在循环体中如果出现类似a[i-1]和a[i+1]的操作时就要考虑一下是否出现数组越界的情况了。
最后,说说实验总结的问题。实验总结应该是对自己在完成实验题目的过程中遇到的问题进行总结,现在我们在语法方面的错误已经比较少了,那么,重点应该分析的是问题的解题思路,程序有哪些考虑不全面的地方,出现了哪些bug,怎么解决的,以及程序是否可以优化等问题。希望大家可以认真对此进行总结。
再啰嗦一句,程序如果不会,不建议问百度,还是和同学一起讨论更有收获。
啰嗦了这么多,不知道大家认真看了没有,认真看了的同学,就在总结里回复我一声吧。
二、实验内容
1.定义函数实现:输入若干名学生的成绩(输入人数或用负数结束均可),求其平均分,最高分和最低分,并指出最高分和最低分的学生(给出下标即可),输入一个成绩,说明是第几个学生的成绩,最后按照成绩从高到低排序后输出。(至少七个函数。输入函数、平均值函数、最大值下标函数、最小值下标函数,查找函数,排序函数,输出函数)
2.定义长度为100的整型数组,将数组元素赋初值为1,2……100,将其中所有值为3或7倍数的值删除,最后打印输出数组中剩余数的个数及每个数。
附加题
1.将数组a中的10个元素后移m位,移出的m位顺序存放在数组的 前m位。要求:(1)数组值在程序中初始化(2)m从键盘输入。
2. 数字加密:输入一个四位数,将其加密后输出。方法是将该数每一位上的数字加9,然后除以10取余,做为该位上的新数字,最后将千位和十位上的数字互换,百位和个位上的数字互换,组成加密后的新四位数。例如输入1257,经过加9取余后得到新数字0146,再经过两次换位后得到4601。
三、实验要求
作业提交必须按照以下格式写,不能只写源代码,或只提交运行结果截图。
格式如下:
一、实验内容
- 实验要求:XXXXXXXXX
代码:(利用博客园的插入代码功能插入源代码,不要截图,严格按照标准格式来写,学习加入必要的注释)
程序运行结果:截图
每个实验题都按照上述格式完成。
二、实验总结(实验中遇到的问题及解决方法)
1、.......
2、.......
........
三、程序分析
程序1
#include <stdio.h> void swap(int x[]); int main() { int a[2]={1,2}; swap(a); printf("a[0]=%d a[1]=%d ",a[0],a[1]); return 0; } void swap(int x[]) { int z; z=x[0]; x[0]=x[1]; x[1]=z; }
程序2
#include <stdio.h> void swap(int x,int y); int main() { int a[2]={1,2}; swap(a[0],a[1]); printf("a[0]=%d a[1]=%d ",a[0],a[1]); return 0; } void swap(int x,int y) { int z; z=x; x=y; y=z; }
分析上述两个程序的执行结果。说明为什么?
四、作业评定:
满分10分,其中程序书写规范(缩格)及结果正确 5 分,程序书写不规范扣 1 分,程序少完成一题扣1分, 实验总结 2分,程序分析2分,每班提交的前5名同学 1分。奖励分:作业评阅 1分,附加题 2分
迟交作业 0 分,一周以后仍然没有交作业,倒扣 10 分,发现抄袭,一律倒扣10分。作业的评分将作为期末成绩中平时成绩和实验成绩的主要依据。