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”宣告巢狀函式總是會產生錯誤。
廣告