8 函數嵌套調用
我們學習了函數的定義和使用,那么,函數在被調用之前,必須先進行定義或者聲明。
如下是一個程序測試例子:

程序運行結果如下:

可以看到,在main函數中調用了func函數。就是說:函數調用了函數;那么,我們稱為:函數嵌套調用。
注意:不能夠在函數中定義函數,就是不能夠“嵌套定義函數”。我們不可以把func函數的定義放在main函數的定義中。例如:
int main(int argc, char* argv[])
{
//定義func函數
void func(int a)
{
printf("in func, a = %dn", a);
}
func(6);
return 0;
}
注意:這樣的代碼,在VC編譯器,或者Visual Studio編譯器中,是非法定義的代碼。
這樣的代碼是錯誤的,雖然在func函數的調用之前,定義了func函數。但是,不能夠在main函數中定義func函數,就是不能夠嵌套定義函數。
但是,在Ubuntu系統的GCC編譯器中,支持嵌套定義函數的語法。
雖然GCC支持這樣的語法,但是,我們不建議嵌套定義函數。這樣的語法,是不提倡的寫法。不便于代碼的移植。
但是,函數可以嵌套調用,就是在函數的定義中,調用其他函數,程序測試例子如下:
注意:下面的例子,作者舉例有些復雜,在分析的過程中,還分析函數的返回值等數據的傳遞。如果只是說明函數的嵌套調用,那么,沒有那么復雜。很簡單,就是:在一個函數中,調用一個函數,這就是函數的嵌套調用。
下一章節,我們講解函數的遞歸調用,才是重點。

程序運行結果如下:

我們來分析該程序的執行過程如下:
(1) 定義了main函數,是程序的入口地址;程序從main函數開始執行;
(2) 在main函數中調用func3函數,執行到 int x = func3(); 代碼的時候,就跳轉到func3函數執行;
(3) 在func3函數中調用func2函數,執行到 int c = func2(); 代碼的時候,就跳轉到func2函數執行;
(4) 在func2函數中調用func1函數,執行到int b = func1(); 代碼的時候,就跳轉到func1函數執行;
(5) 此時,一步一步嵌套調用函數,調用到func1函數,執行func1函數體定義的代碼,執行:
printf("in func1, a = %dn", a);
輸出調試代碼,然后,執行return a; 返回變量a的值;
(6) 結束func1函數的調用,返回到func2函數的int b = func1(); 代碼,此時,把func1函數的返回值賦給變量b,那么,變量b得到func1函數的返回值10。
(7) 繼續執行func2函數的代碼:
printf("in func2, b = %dn", b);
return b;
此時,在func2函數中輸出信息,然后,返回變量b的值;
(8) 結束func2函數的調用,返回到func3函數的int c = func2(); 代碼,此時,把func2函數的返回值賦給變量c,那么,變量c得到func2函數的返回值12。
(9) 繼續執行func3函數的代碼:
printf("in func3, c = %dn", c);
return c;
輸出調試信息,然后,返回變量c的值。最終,結束func3函數的調用,返回到main函數的int x = func3(); 代碼,此時,結束func3函數的調用,把返回值賦給變量x。在main函數中輸出變量x的值。執行完main函數之后,結束程序的運行。
通過這個程序的分析,我們知道了函數的嵌套調用,就是在函數中調用函數。碰到調用函數時,就跳轉到函數定義的函數體中運行。例如,在main函數中調用func3函數的時候,就跳轉到func3函數定義函數體中運行。