本帖最后由 09927306 于 2011-1-8 18:34 编辑
第7章:程序的模块结构和C函数
【例7-1】
计算组合的公式为: 这里需要求出3个阶乘,于是我们可以编制一个通用的阶乘函数factor(),通过使用不同的参数调用实现一个函数被多次使用的目的。程序如下:
- main()
- { int m,n;
- long cmn,temp;
- long factor(int); /* 被调用的函数类型说明 */
- void print(); /* 被调用的函数类型说明 */
- printf("Input m and n:");
- scanf("%d%d",&m,&n);
- cmn=factor(m); /* 函数名调用,计算m! */
- temp=factor(n); /* 函数名调用,计算n! */
- cmn=cmn/temp; /* 函数名调用,计算m!/n! */
- cmn=cmn/factor(m-n); /* 函数名调用,计算m!/n!/(m-n)! */
- print(cmn); /* 函数名调用,打印结果 */
- }
- long factor(int x) /* 定义阶乘函数 */
- { long y;
- for(y=1;x>0;x--)
- y=y*x;
- return (y);
- }
-
- void print(long x) /* 定义打印函数 */
- { printf("The combinations:%d\\n",x);
- }
复制代码
main()函数接收了m和n的值后,要通过3次调用factor()函数来分别求得m!、n!和(m-n)!,最后调用print()函数输出结果。 【例7-2】 考察下面的程序,mian()函数能否通过调用函数swap()用来实现变量x和y的交换。
- main()
- { int x,y,swap(int a,int b);
- scanf("%d,%d",&x,&y);
- printf("output in main before calling swap:x=%d,y=%d\\n",x,y);
- swap(x,y); /* 函数调用 */
- printf("output in main after calling swap:x=%d,y=%d\\n",x,y);
- }
- swap(int a,int b)
- { int t;
- t=a,a=b,b=t; /* 变量交换 */
- printf("output in swap:a=%d,b=%d\\n",a,b);
- }
复制代码
函数swap()的功能是实现a、b的交换。当main()调用swap()时,通过虚实结合将实参x、y的值复制到swap()的形参a、b中,使a和b所在的存储单元中分别得到了x和y的值。在swap()执行时,由于a、b、x、y各自占有自己的存储单元,当a、b的值发生了交换后,不会被复制到x和y中,因此,x和y不受a和b的影响,并未发生交换,参见图7-3。程序的运行情况如下:
1234
5678↙
output in main before calling swap:x=1234,y=5678
output in swap:a=5678,b=1234
output in main after calling swap:x=1234,y=5678
【例7-3】 考察下面的程序,mian()函数能否通过调用函数swap()用来实现变量x和y的交换。
- main()
- { int x,y,swap(int *,int *);
- scanf("%d%d",&x,&y);
- printf("output in main before calling swap:x=%d,y=%d\\n",x,y);
- swap(&x,&y);
- printf("output in main after calling swap:x=%d,y=%d\\n",x,y);
- }
- swap(int *a,int *b)
- { int t;
- t=*a,*a=*b,*b=t; /* 指针所指的存储单元的内容交换 */
- printf("output in swap:a=%d,b=%d\\n",*a,*b);
- }
复制代码
当main()调用swap()时,实参变量x和y的地址被复制到形参a和b(a和b是指针变量)中,使a和b分别指向x和y。在swap()执行时,由于*a和x等价,*b和y等价,*a和*b的交换实际上是在x和y的存储单元中进行的,所以,*a和*b的交换实际就是变量x和y的交换
【例7-4】 调用函数通过指针传递不仅可以将数据传递到被调用函数中,还能从被调用函数获得所需要的数据。下面的程序将2个加数传递给被调用函数,并从被调用函数获得两数之和。
- main()
- { float a,b,c,*pa=&a,*pb=&b;
- void plus(float *,float *,float *);
- printf("Input a and b:");
- scanf("%f%f",pa,pb);
- plus(pa,pb,&c);
- printf("%.1f+%.1f=%.1f\\n",a,b,c);
- }
- void plus(float *x,float *y,float *z)
- {
- *z=*x+*y;
- }
复制代码
程序执行时,main()将变量a、b的指针pa、pb及变量c的地址&c分别复制到plus()的形参x、y和z中,因此*x和*y分别表示取a和b值,二者相加后的结果保存在*z中,而*z与c是等价的,即c中存放的是a+b的值。程序运行情况如下:
20 30↙
20.0+30.0=50.0
【例7-5】 编制子函数mean()用来求虚拟一维数组各元素的平均值。主函数main()中提供一维数组的数据,并调用mean()获得实际数组的平均值。 主函数用数组名作为实参,子函数用数组名作为形参。程序如下:
- main()
- { int i,a[10];
- float mean(int *),mv;
- for (i=0;i<10;i++)
- scanf("%d",&a[i]);
- mv=mean(a);
- printf("MEAN=%f\\n",mv);
- }
- float mean(int d[10]) /* 计算平均值 */
- { int i;
- float avg;
- for (avg=0,i=0;i<10;i++)
- avg+=d[i];
- avg/=10;
- return avg;
- }
复制代码
函数mean()的形参虽然被说明为int d[10],但在虚实结合时,数组名d被转换成数组指针*d并接收实参数组a的首地址。由于d变成了指向数组a的指针,因此,虚参数组d[10]并没有自己的存储单元,而是共享实参数组a的存储单元,见图7-5所示。
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]
d[0] d[1] d[2] d[3] d[4] d[5] d[6] d[7] d[8] d[9] 图7-5
一维数组传递时,形参和实参的共享 ② 由于形参数组在虚实结合时被转换成数组指针,因此形参数组的说明中,维界的大小无关紧要,通常都写成隐含尺寸数组或指针的形式。即在例7-5中,被调用函数mean()可以定义成以下形式之一:
float mean(int d[10])
其中,维界的大小无关紧要
float mean(int d[])
float mean(int *d)
上一章:C语言案例教程 - 第六章:指 针
下一章:C语言案例教程 - 第八章 复合数据类型
|