7.2.3 函数的嵌套调用
对于函数定义来说,C语言不允许在函数内部再定义另外一个函数,也就是说C语言中,每个函数都是平行和独立的,这一点和某些编程语言不同,有些编程语言是允许在函数内部再定义其他函数的,这叫嵌套定义(一个函数定义里面套着另外一个函数定义)。如下代码这种函数嵌套定义,在C语言中就是错误的:

必须要把subfunc函数拿出来摆在和qiantaofunc平行(平等)的位置。如下代码:

虽然不能嵌套定义函数,但C语言允许嵌套调用函数。也就是说,在调用一个函数过程中,被调用的函数又去调用第三个函数,甚至第三个函数又去调用第四个函数……,都是被允许的。这里用最简单的无参无返回值函数演示一下如何进行函数嵌套调用,先定义三个独立的函数——qtfunc1、qtfunc2、qtfunc3,代码如下:

在源代码文件最前面,要对这三个函数进行函数声明:

在main中调用qtfunc1();,结果显示如下:

下面修改qtfunc1函数,在其中增加调用qtfunc2函数的代码。修改后的代码如下:

这里必须再次提醒读者,请严格区分函数定义、函数调用、函数声明三者的区别,千万不要混淆。
再次编译并执行程序查看结果如下:

这次修改qtfunc2函数,在其中增加调用qtfunc3函数的代码。修改后的代码如下:

再次编译并执行程序查看结果如下:

这里可以尝试设置断点并进行跟踪调试,看看整个程序的执行流程,看看函数之间的调用关系。这里给出一个函数调用关系图,帮助读者捋一捋思路,如图7.2所示。
这里讲解的函数嵌套调用,是为后面讲解函数递归调用打基础。函数递归调用是一个对于初学者相对比较难理解的函数调用方式,笔者会尽量完美地演绎函数的递归调用。

图7.2 函数嵌套调用关系图(注意:数字表明执行的顺序和步骤)