5.函数定义与调用 1 5.1.知识要点 1 .函数的概念及定义方法。 .函数的声明方法。 .函数的调用概念及方法。 .函数间参数传递的使用方法。 【知识点讲解】C语言中子程序的作用是由函数来完成的,该定义与数学中的函数概 念不完全相同。当需要完成某一个功能时,就定义一个函数,将实现某一功能的代码封装在 一个函数中,当程序需要实现函数的功能时,就可以通过调用该函数来实现。一个C语言 程序可以由一个主函数和若干子函数构成,由主函数调用其他函数,其他函数之间可以互相 调用,同一个函数可以被一个或多个函数调用任意多次。函数可以分为标准函数和用户定 义函数,并通过参数进行函数之间的数值传递。 一个函数定义是由函数首部和函数体构成的,函数首部用来确定函数有无返回值、返回 值的类型、函数名、函数形参的定义,函数体由函数中用到变量的定义和为完成函数功能的 语句组成。一个函数一旦被定义,就可在程序的其他函数中使用它,这个过程称为函数调 用。一个函数可以被其他函数多次调用,每次调用可以处理不同的数据。在函数调用过程 中完成实参与形参之间数据的传递。本次实验涉及的知识点关系如图5-1所示。 图5- 1 本次实验涉及的知识点关系图 5.1.上机实验 2 1. 实验目的 .理解函数的基本概念。 .掌握函数定义的一般形式、函数的调用方式、函数的声明方法。 C语言程序设计实验及习题解答(第46 2版) . 理解并掌握函数中的实参与形参的概念及函数间数值传递的方法。 . 了解函数类型定义与函数返回值之间的联系。 2.实验参考 【例5-1】 编写程序,判断输入数值是否为质数。 【源程序】 #include "stdio.h" int main() { int prime(int i); int i,j; printf("input a value:"); scanf("%d",&i); j=prime(i); if(j==0) printf("i is not a prime number"); else printf("i is a prime number"); return 0; }i nt prime(int i) { int j; for(j=2;j 【程序输出】 i is a prime number 【程序分析】 如果一个整数不能够被除1和它本身之外的任意一个整数整除,则认为 该整数为质数,也称素数。程序定义了函数prime实现判断任意一个整数是否为素数的功 能,为了实现数据在主函数和子函数之间的传递,在函数prime中定义一个形参接受主函数 传过来的实参数据,函数prime通过返回值0或者1来区分当前判断的整数是否为素数。 主函数通过子函数的计算结果进行判断,最终输出结果。注意由于被调函数定义在主调函 数之后,函数在使用前需要进行函数声明。 第1部分 知识点讲解及实验安排 47 【例5-2】 一个质数,如果其数字位置对换后仍然为质数,则称该数为绝对质数,编写 程序判断一个两位数是否为绝对质数。如13,数字位置对换后为31,仍然为质数,所以称 13和31为绝对质数。 【源程序】 #include "stdio.h" int invert(int i); int prime(int i); int main() { int i,j,k; printf("input a value:"); scanf("%d",&i); k=invert(i); j=prime(i)&&prime(k); if(j==0) printf("%d is not an absolute prime number", i); else printf("%d is an absolute prime number", i); return 0; }i nt prime(int i) { int j; for(j=2;j 【程序输出】 31 is an absolute prime number C语言程序设计实验及习题解答(第48 2版) 【程序分析】 程序定义三个函数分别为主函数、判断一整数是否为素数函数prime、将 任一整数翻转函数invert,在主函数中首先调用函数invert完成将输入的整数翻转,然后调 用函数prime判断原数值和翻转后的数值是否均为素数。如果原数值和翻转后的数值均为 质数,则该数值为绝对质数。由于本题只要求判断一个两位数,因此其翻转函数不具有普遍 性,只能处理两位数的翻转,该函数可以进行扩展,以支持多位数的翻转。注意由于被调函 数定义在主调函数之后,函数在调用前需要进行函数说明。 【例5-3】 编写一个程序,求所有的两位数的绝对质数。 【源程序】 #include "stdio.h" int invert(int i); int prime(int i); void output(); int main() { output(); return 0; }i nt prime(int i) { int j; for(j=2;j 【程序输出】 fac(14)=1278945280 【程序分析】 要得到n的阶乘,必须知道n-1的阶乘,且需要初始化0和1的阶乘值。 因此,当n为0或1时,fac(n)=1,该部分是函数用于递归调用结束时使用,因此必不可少; n大于1时,fac(n)=n*fac(n-1)。 【例5-5】 用递归算法写一个计算组合的函数。 【源程序】 #include "stdio.h" int zh(int m, int n); int main() { int m,n; printf("input m and n:"); scanf("%d%d",&m,&n); printf("the result is %d\n",zh(m,n)); return 0; }i nt zh(int m, int n) { if(n>m-n) 第1部分 知识点讲解及实验安排 53 return zh(m,m-n); else if(n==0) return 1; else if(n==1) return m; else return zh(m-1,n-1)+zh(m-1,n); } 【程序输入】 input m and n:5 2 【程序输出】 the result is 10 【程序分析】 组合计算的公式为Cnm = 1 n=0 m n=1 Cnm--11+Cnm-1 n>1 ì . í .. .. ,该公式可以保证函数的增量计算,进而 保证函数递归的实现。 【例5-6】 计算两个整数的最大公约数。 【源程序】 #include "stdio.h" int mcf(int a, int b); void main() { int x,y,z; printf("input x, y:"); scanf("%d%d",&x, &y); z=mcf(x,y); printf("the max common factor=%d\n",z); } int mcf(int a, int b) { if(a<=0 ‖ b<=0) return -1; if(a==b) return a; else if(a>b) return mcf(a-b,b); else return mcf(a,b-a); } C语言程序设计实验及习题解答(第54 2版) 【程序输入】 input x, y:16 27 【程序输出】 the max common factor=1 【程序分析】 最大公约数的性质包括三个:如果x>y,则x和y的最大公约数与x-y 和y的最大公约数相同;如果y>x,则x和y的最大公约数与x和y-x的最大公约数相 同;如果x=y,则x和y的最大公约数与x和y的值相同。 3.实验内容 编写程序并上机调试运行。 (1)用递归法将一个整数n转换成字符串。例如,输入483,应输出字符串“483”。n的 位数不确定,可以是任意位数的整数。 (2)用递归方法求n阶勒让德多项式的值,递归公式为 pn(x)= 1 (n=0) x (n=1) ((2n-1)×x-pn-1(x)-(n-1)×pn-2(x))/n (n>1) ì . í .. .. (3)采用递归方法计算x的n次方。 (4)编程利用函数递归实现如下函数的计算:f(1)=1;f(2)=2;f(n)=f(n-1)*f(n-2)。 5.2.3 实验过程中的常见问题与解决方法 【问题5-4】 递归无法结束。 缺少对输入的数据进行的合法性检查过程,当输入非法数据时也执行递归,导致递归不 能结束。 例如:计算n的阶乘,输入的n应该大于0,若n小于0则不应该进行计算。如果不对 输入的n进行判断,当n小于0时也会进行递归,这样肯定会出错的。 解决方法:加上对n是否小于0的判断,如果小于0,则不进行递归。 5.3 函数的高级应用 5.3.1 知识要点 . 理解并掌握局部变量和全局变量的概念、定义方法及其作用域。 . 理解当局部变量和全局变量同名时,在局部变量的作用域内,全局变量被覆盖。 . 了解使用全局变量的利与弊。 . 了解static和extern说明符对变量的影响。 . 不带参数的宏定义和带参数的宏定义。 【知识点讲解】 本次实验涉及的主要内容包括变量的存储属性和作用域以及简单的编 译预处理。变量的作用域和存储属性往往具有一定的关联。对于全局变量来说,其作用域