C语言嵌套函数



在编程领域,“嵌套”指的是将某个编程元素包含在另一个类似的元素中。就像嵌套循环、嵌套结构体等一样,嵌套函数是指在一个函数内部使用一个或多个函数。

什么是词法作用域?

在C语言中,不允许在一个函数内部定义另一个函数。简而言之,C语言不支持嵌套函数。函数只能在另一个函数内部进行声明(不能定义)。

当一个函数在另一个函数内部声明时,这被称为词法作用域。词法作用域在C语言中是无效的,因为编译器无法找到内部函数的正确内存位置。

嵌套函数用途有限

嵌套函数定义无法访问周围块的局部变量。它们只能访问全局变量。在C语言中,存在两种嵌套作用域:局部作用域和全局作用域。因此,嵌套函数的用途有限。

示例:嵌套函数

如果你想创建一个如下所示的嵌套函数,则会产生错误:

#include <stdio.h>

int main(void){

   printf("Main Function");

   int my_fun(){
   
      printf("my_fun function");
      
      // Nested 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

嵌套函数的跳板

“GNU C”中嵌套函数作为扩展功能受支持。GCC 使用一种称为跳板的技术来实现获取嵌套函数的地址。

跳板是在运行时创建的一段代码,用于获取嵌套函数的地址。它需要在声明中使用关键字auto作为函数前缀。

示例1

请看下面的例子:

#include <stdio.h>

int main(){

   auto int nested();
   nested();

   printf("In Main Function now\n");

   int nested(){
      printf("In the nested function now\n");
   }

   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”声明嵌套函数总是会产生错误。
广告