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,程序执行到此结束。

