首页 > 范文大全 > 正文

C/C++语言程序中函数调用解决办法

开篇:润墨网以专业的文秘视角,为您筛选了一篇C/C++语言程序中函数调用解决办法范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!

摘要:程序员在设计应用程序时,通常把程序划分为若干功能较为单一的模块,然后分别予以实现,最后再把所有的模块装配起来。这种程序设计中分而治之的策略,被称为模块化程序设计。C语言中,函数是程序的基本组成单位,也是模块化程序设计的惟一工具,使用函数调用和嵌套,可使程序设计变得简单直观、易读和易维护,并可大大地减轻程序员的代码工作量。文章就C/c++语言程序设计中的解决方法、特点进行阐述。

关键词:模块化程序设计;函数调用;嵌套;递归

0 引言

程序调用是指当前正在执行的程序(又称调用程序)中出现了调用其它程序的语句,使得程序的执行转移到另一个程序段(又称为被调用程序)中,同时保存必要的信息,以便在被调用程序执行结束后恢复执行调用程序的过程。在C/C++语言中,称程序调用为函数调用。当在一个函数中出现了函数名时,就发生了函数调用。在C/C++语言中,有以下两种函数调用方式:

(1)函数调用以一个语句的形式出现,这时被调用函数可以没有返回值(函数类型可以设置为void类型);

(2)以表达式中的一个项的形式出现,被调用函数必须有一个明确的返回值。

按照函数调用的性质的不同,函数调用又分为两类:函数嵌套调用和函数递归调用。以下就嵌套调用与递归调用概念进行一些说明。

1 存在问题和解决办法

C语言函数的定义都是独立的,互不包含。换句话来说,一个函数内不能包含对另一个函数的定义。

嵌套调用。C语言不能嵌套定义函数,但可以嵌套调用(nested calling)函数。嵌套调用过程如图1所示。

图1 C语言函数嵌套调用过程

递归调用。在调用一个函数的过程中出现了直接或间接地调用该函数本身,称为函数的递归调用。换句话说,当一个程序调用它自身时就发生了递归(recursive calling)。C/C++语言的特点之一就在于允许函数的递归调用,如图2所示。

递归算法的实质是将原来的问题分解为新的问题,而对新的问题又用到了原有问题的解法。按照这一原则分解下去,每次出现的新问题是原有问题的简化子集,而最终分解出来的问题,是一个已知解的问题(即调用至满足调用终止条件,得到一个可用的基础值),这便是有限的递归调用。只有有限的递归调用才是有意义的;无限的递归调用永远得不到解,没有实际意义。

图2 函数的递归调用过程

递归的过程有两个阶段:

第一阶段,递推。将原有的问题不断分解为新的子问题,逐渐从未知向已知推进,直到推进至满足调用终止条件,得到一个可用的基础值。

第二阶段,回归。从基础值出发,按照递推的逆过程,逐一求值回归,最后到达递推的开始处,结束递归调用。

2 函数嵌套调用与递归调用实例分析

现各举一个嵌套调用和递归调用的小程序,以说明上面的理解(为了表明C++也支持嵌套调用和递归调用,以下程序用C++语言编写)。

例1:输入两个整数,求它们和的平方。

分析:为了说明函数的嵌套调用,针对该问题可以设计两个函数,求平方的函数SQU及求另一个整数平方和的函数SUM。由主函数调用SQU,SQU又调用SUM(见图3)。

图3 函数的嵌套调用和递归调用

假设求平方的函数为为a,求整数平方和的函数为b,程序

如下(Source Code):

//

//nestf.cpp

//The C++program illustrates nested functiOn calling.

//CaIculation of the quadratic sum of two Integers.

//

#incIude<iOstream.h>

Vo|d math(void)

{int m,n;

int a(int x,inl y);//function prolotype

COUl<<"pIease enter two jntegers:"<<endI;

cin>>m>>n;

COUt<<“the quadratic sum of m and n is"<<a(m,n)<<endl;

//calIing function

}

int a(int x,int y) //function decIaration

{int b(int m);//function prototype

return(b(x)+b(y));

//calling nested functiOn and function retum

}

int b(int k)//function declaration

{reIum(k*k);)//funclion return

例2:求n!

分析:根据

程序流程:

图4 程序流程

以下以6 1为例:

我们可以进行以下分析:

6!=6*5!5!=5*4!4!=4*3!3!=3*2!2!=2*1!1!=1*0!0!=1

未知――――――(递推)――――――――――已知

6!=6*5!=7205=5*4!=1204!=4×3!=243!=3*2!=62!=21!=1*0!=10!=1

未知――――――(回归)―――――――――已知

Source Code:

//

//factof.cpp

//A C++program illustrating recursiVe functiOn caIIs.

//CaIcuIating the factorial of a number.

//ExamDIe:6!=6*5*4*3*2*1=720

//

#incIude<iOstream.h>

long flactof(int n)//funclion declaration

{long a;

if(n<0)

count<<"The integer(n)which you entered must be

greater than or equal to zero!"<<endI;

eIse if(n==0)a=1;//the basic condition to terminale

eIse a=facfof(n-1)*n;//iterating

retum(a);

}

void main()

{long faclof(inI n);//funclion procotype

int b=6;

long y;

y=factof(b);//recursiVe calling

COUl<<"6!="<<y<<endl;

}

3 结束语

嵌套调用是将功能独立的函数有机地结合起来,完成一项任务。采用嵌套调用,提高了程序的可读性、可维护性和可扩充性。而采用递归调用允许某些算法用简单的小例程来实现,但不能保证速度或效率。递归使用不当会导致程序在执行过程中耗尽空间(因为在递归调用时必然要一次次生成新的同名局部变量,并动态地为其分配存储单元),从而引起程序(有时是整个系统)崩溃。

函数定义中是否直接或间接的调用了自己是递归函数与函数嵌套调用两个概念的最根本区别。

注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。