函数调用
什么是函数调用呢?通常在C语言中,一个完整的项目程序是不可能在一个函数中实现所有的功能。而是由若干功能不同的函数来实现,并且函数之间会存在互相调用的情况。
当然了,也不是说就一定要把函数的功能模块都分开来写,但是如果你写成了下面这个样子:
我估计以后你的项目经理肯定会对你好(ba)言(dao)相(xiang)劝(xiang)的。
函数的调用方式
函数是C语言的基本组成元素,如果你要想实现函数的功能,那么你就必须学会正确调用函数。调用的语法格式如下:
从上面的语法格式可以看出,当我们调用一个函数时,需要明确函数名和实参列表。实参列表中的参数可以是常量、变量、表达式或者空,并且各参数之间要使用英文逗号分隔开来。
根据函数在程序中出现的位置,有下列三种函数调用方式:
1、将函数作为表达式调用
将函数作为表达式调用时,函数的返回值参与表达式的运算,此时要求函数必须有返回值。示例代码如下所示:
2、将函数作为语句调用
函数以语句的形式出现时,可以将函数作为一条语句进行调用。示例代码如下所示:
3、将函数作为实参调用
将函数作为另一个函数的实参时,要求该函数有返回值。示例代码如下所示:
在上面的语句中,将函数max()的返回值作为printf()函数的实参来使用。
嵌套调用
在C语言中,函数的定义是独立的,也就是说,一个函数不能定义在另一个函数内部。但在调用函数时,可以在一个函数中调用另一个函数,这就是函数的嵌套调用。接下来我们通过一个案例来演示函数的嵌套调用。
案例一:
运行结果:
在这个案例中,main()函数中调用了 max4()函数,max4()函数中又调用了max2()函数。为了让大家能够更好地理解这个程序执行的流程,我们通过一张图来描述:
这张图展示了程序中含有三层函数调用嵌套的情形,总共分为9个步骤,具体如下:
(1) 执行main()函数的开头部分;
(2) 遇到函数调用语句,调用max4()函数,流程转向max4()函数入口;
(3) 执行max4()函数的开头部分;
(4) 遇到函数调用语句,调用max2()函数,流程转向max2()函数入口; (5) 执行max2()函数,如果再无其他嵌套的函数,则完成max2()函数的全部操作;
(6) 返回到max2()函数中调用max4函数的位置;
(7) 继续执行max4()函数中尚未执行的部分,直到max4()函数结束;
(8) 返回main()函数中调用max4()函数的位置;
(9) 继续执行main()函数的剩余部分直到结束。
&多学一招:函数调用时最多可以嵌套多少层?
大家肯定会问:“既然函数嵌套调用和普通的调用看上去没什么区别,那是不是可以进行无限层的函数嵌套调用呢?”很遗憾,函数可以嵌套调用多少层是由程序运行时一个名为“栈”的数据结构决定的。一般而言,Windows上程序的默认栈大小大约为8KB,每一次函数调用至少占用8个字节,因此粗略计算下,函数调用只能嵌套大约一千层,如果嵌套调用的函数里包含许多变量和参数,实际值要远远小于这个数目。
当然,单纯手动书写代码写出一千层嵌套函数调用基本是不可能的,但是一种名为“递归”的方法可以轻松达到这个上限。
递归调用
在数学运算中,会遇到计算多个连续自然数之间的和的情况。例如要计算1~n之间自然数之和,就需要先计算1加2的结果,用这个结果加3再得到一个结果,用新得到的结果加4,以此类推,直到用1~(n-1)之间所有数的和加n。
在程序开发中,要想完成上述功能,就需要使用函数的递归调用,所谓的递归调用就是函数内部调用自身的过程。需要注意的是,递归必须要求有结束条件,不然就会陷入无限递归的状态,永远无法结束调用。接下来通过一个计算自然数之和的案例来学习递归调用。
案例二:
运行结果:
案例二中,我们定义了一个getsum()函数用于计算1~n之间自然数之和。案例中的第9行代码相当于在getsum()函数的内部调用了自身,这就是函数的递归,整个递归过程在n==1时结束。由于函数的递归调用过程很复杂,接下来通过一个图例来分析整个调用过程。
这张图中描述了递归调用的过程,整个递归过程中getsum()函数被调用了4次,每次调用时,n的值都会递减。当n的值为1时,所有递归调用的函数都会以相反的顺序相继结束,所有的返回值会进行累加,最终得到的结果为10。
END
想学习交流C语言可以申请加群:564950050,一个人单独学习效率是很低的,只有一群相同目标的小伙伴一起学习讨论,才是进步最快的方法。