C-函数调用-控制流
在本教程中,我们将学习使用C编程语言调用函数时的控制流程。
我们在函数教程中了解了函数,并在函数类别教程中了解了类别。
当我们调用或者调用一个函数时,控制流从调用函数转移到被调用函数。
例如,如果我们从main()
函数调用greetings()
函数,则控制流将从main()
函数移至greetings()
函数。
在执行greetings()或者被调用函数中的所有语句后,控制流将返回到" main()"或者被调用函数。
了解控制流程
在以下示例中,我们具有一个main(),printSquare(),getSquare()和get10()函数。
#include <stdio.h> //function declaration void printSquare(int); int getSquare(int); int get10(void); int main(void) { //variable declaration int num; //function call num = get10(); printSquare(num); return 0; } //function definition void printSquare(int x) { int square = getSquare(x); printf("Square: %d\n", square); } int get10(void) { return 10; } int getSquare(int n) { return n * n; }
让我们逐行讨论上述代码的控制流程。
首先让我们创建一个函数调用堆栈。
在此,我们将跟踪函数调用。
最初它将是空的。
函数调用堆栈 |
---|
空 |
第1行。
此行将告诉编译器在我们的代码中获取stdio.h
头文件。
第2行。
因此,清空行,然后移至下一行。
第3行。
单行注释。
这是给我们开发人员的,编译器将忽略它。
第4行。
该行包含printSquare()
函数声明。
此函数以整数值作为参数,不返回任何值。
第5行。
该行包含getSquare()
函数声明。
此函数以整数值作为参数,并返回整数值。
第6行。
此行包含get10()
函数声明。
此函数不带参数,但返回一个整数值。
第7行。
空行。
第8行。
main()函数的启动。
第9行。
单行注释。
第10行。
声明了类型为int的变量num。
因此,计算机将分配内存空间来存储整数值,并以名称num引用它。
第11行。
空行。
第12行。
单行注释。
第13行。
调用get10()
函数。
此时,控制流将从第13行移至第25行,其中定义了" get10()"函数。
注意!这里的main()函数是调用函数,而get10()函数是被调用函数。
因此,main()函数正在调用或者调用get10()函数。
还要注意,计算机将记住在完成" get10()"功能后必须返回到第13行。
因此,请注意此返回点。
函数调用堆栈 |
---|
返回第13行 |
第25行。
get10()函数的启动。
第26行。
该行包含return语句,它向调用函数即main()返回整数10。
注意!在第26行,我们遇到return语句,因此控制流将移回到调用函数。
如果我们检查Function调用堆栈,可以看到我们必须返回到第13行。
函数调用堆栈 |
---|
返回第13行 |
因此,我们将清空堆栈并返回到第13行。
函数调用堆栈 |
---|
空 |
第13行。
在这一行,我们将整数值(即由get10()函数返回的10)分配给变量num。
第14行。
在这一行,我们要进行另一个函数调用。
这次我们调用printSquare()
函数并传递存储在num
变量中的值。
注意!在这种情况下,main()是调用函数,而printSquare()是调用函数。
因此,控制流将从第14行移至第20行,其中定义了printSquare()
函数。
完成printSquare()
函数后,控制流程将返回到第14行,因此,我们将在函数调用堆栈中注意到这一点。
函数调用堆栈 |
---|
返回第14行 |
第20行。printSquare()
函数的启动。
第21行。
在这行中,我们用方名来声明一个int变量,并调用getSquare()函数并将存储在变量x中的值作为函数参数传递。
这意味着,将由getSquare()函数返回的整数值将分配给变量sqaure
。
因为我们正在进行函数调用,所以printSquare()
函数成为调用函数,而getSqaure()
函数成为被调用函数。
因此,控制流将从第21行移至第29行。
在完成调用函数的操作后,控制流将返回至第21行。
因此,让我们在函数调用堆栈中注意这一点。
函数调用堆栈 |
---|
返回第21行 |
返回第14行 |
第29行。
getSquare()函数的启动。
第30行。
在这一行,我们遇到return语句。
因此,我们使用乘数*乘以乘数来计算平方,即乘以存储在变量n中的值,即10 * 10 = 100的n * n。
乘积将返回给调用函数。
此时,控制流将移回到调用函数。
因此,如果我们检查函数调用堆栈,我们可以看到我们必须返回到第21行。
函数调用堆栈 |
---|
返回第21行 |
返回第14行 |
因此,我们将其弹出功能调用堆栈,然后移至第21行。
函数调用堆栈 |
---|
返回第14行 |
第21行。
在调用了getSqaure()函数后返回了第21行,该函数返回了整数值100。
因此,该值已分配给变量sqaure
。
第22行,在这行中,我们使用printf()
函数打印正方形。
由于这是printSqaure()函数的最后一行,因此控制流将从此处返回到调用的函数。
如果我们看一下函数调用堆栈,可以看到我们必须返回到第14行。
函数调用堆栈 |
---|
返回第14行 |
因此,我们将返回到第14行,并将其从函数调用堆栈中弹出。
函数调用堆栈 |
---|
空 |
第14行。
在调用函数后,我们回到了这一行,这里不再需要做其他操作,因此,我们移至下一行。
第15行。
空行。
第16行。
我们遇到main()
函数的最后一行,该行返回0,程序执行到此结束。