C 语言中的嵌套函数
在编程语境中,术语嵌套指的是将一个特定的编程元素封装在另一个类似的元素中。与嵌套循环、嵌套结构等类似,嵌套函数是用来描述一个或多个函数在另一个函数中的使用的术语。
什么是词法作用域?
在 C 语言中,无法在另一个函数中定义一个函数。简而言之,C 语言不支持嵌套函数。一个函数只能在另一个函数中声明(而不是定义)。
当一个函数在另一个函数中声明时,这被称为词法作用域。词法作用域在 C 语言中无效,因为编译器无法到达内部函数的正确内存位置。
嵌套函数的用途有限
嵌套函数定义无法访问周围块的局部变量。它们只能访问全局变量。在 C 语言中,有两种嵌套作用域:局部 和 全局。因此,嵌套函数的用途有限。
示例:嵌套函数
如果您想创建一个如下所示的嵌套函数,则会生成错误 -
#include <stdio.h> int main(void){ printf("Main Function"); int my_fun(){ printf("my_fun function"); // 嵌套函数 int nested(){ printf("This is a nested function."); } } nested(); }
输出
运行此代码时,您将收到错误 -
main.c:(.text+0x3d): undefined reference to `nested' collect2: error: ld returned 1 exit status
嵌套函数的 Trampolines
GNU C 扩展支持嵌套函数。GCC 使用一种名为 trampolines 的技术来实现获取嵌套函数的地址。
Trampoline 是在运行时获取嵌套函数地址时创建的一段代码。它要求在函数声明中以关键字 auto 为前缀。
示例 1
请看以下示例 -
#include <stdio.h> int main(){ auto int nested(); nested(); printf("In Main Function now "); int nested(){ printf("In the nested function now "); } printf("End of the program"); }
输出
运行此代码时,将产生以下输出 -
In the nested function now In Main Function now End of the program
示例 2
在此程序中,函数 square() 嵌套在另一个函数 myfunction() 中。嵌套函数使用 auto 关键字声明。
#include <stdio.h> #include <math.h> double myfunction (double a, double b); int main(){ double x = 4, y = 5; printf("Addition of squares of %f and %f = %f", x, y, myfunction(x, y)); return 0; } double myfunction (double a, double b){ auto double square (double c) { return pow(c,2); } return square (a) + square (b); }
输出
运行代码并检查其输出 −
Addition of squares of 4.000000 and 5.000000 = 41.000000
嵌套函数:注意事项
使用嵌套函数时需要注意以下几点:
- 嵌套函数可以访问其定义之前的所有包含函数的标识符。
- 嵌套函数不能在包含函数退出之前调用。
- 嵌套函数不能使用 goto 语句跳转到包含函数中的标签。
- 嵌套函数定义可以在任何块中的函数内使用,并与块中的其他声明和语句混合使用。
- 如果在包含函数退出后尝试通过其地址调用嵌套函数,则会引发错误。
- 嵌套函数始终没有链接。使用"extern"或"static"声明嵌套函数始终会产生错误。