函式原型

電腦程式設計中,函式原型(英語:Function prototype)或函式介面(英語:Function interface)是用於指定函式的名稱和型別簽章元數,參數的資料型別和回傳值型別)的一種省略了函式體的函式宣告英語Declaration (computer programming)。雖然函式宣告規定了函式是如何被實作的,但僅包括對介面的定義(即接受的資料型別和回傳的資料型別),並不包括對函式體的定義。

函式原型被廣泛應用於CC++ 語言程式碼的上下文中,透過在標頭檔中放置函式的前向宣告來允許將程式碼拆分為多個翻譯單元英語Translation unit (programming)。即編譯器可以單獨編譯目的檔的這部分內容,然後由連結器組合成可執行檔函式庫。現代編譯器(如Arduino IDE英語Arduino#Software)不再需要函式原型,因為這些是在編譯時被確定和宣告的。

在原型中,參數名是非必需的(C/C++中存在函式原型作用域,這使參數名的作用域被限制在函式定義內),但是,型別和修飾詞都是必需的(如指標或常數參數)。

物件導向程式設計中, 介面和抽象方法的目的與此類似。

舉例

有函式原型如下:

void Sum(int a,int b);

void Sum(int, int);

首先,函式原型包括函式簽章(英語:function signature),函式名,回傳型別和訪問修飾詞英語Access modifiers。在該例中,函式的名稱是「Sum」。函式簽章確定參數的數量及其型別。在上面的範例中,回傳型別為「void」,這意味著該函式不會回傳任何值。要注意的是第一個範例中的參數名稱是非必需的,甚至實際定義時與函式原型中宣告的不同也沒關係。

應用

在早期的C語言中,如果一個函式之前沒有宣告,並且函式名出現在表達式中,後面跟著左括號,那麼它會被隱式宣告為回傳int型別的函式,並且對它的參數沒有任何假設。在這種情況下,當函式應用於某些參數時,編譯器將無法執行參數型別和語法元數的編譯時檢查。這可能會導致問題。以下程式碼說明了隱式宣告的函式的行為未定義的情況。

#include <stdio.h>

/* 简体中文:
 * 如果提供此函数原型,编译器将在main函数中捕获错误。
 * 如果省略,则错误可能会被忽略。
 */

/* 正體中文:
 * 若提供此函式原型,編譯器將在main函式中發現錯誤。
 * 若省略,則錯誤可能會被忽略。
 */
int MyFunction(int n);  /* 简:函数原型 正:函式原型 */ 

int main( void )  /* 简:调用函数 正:呼叫函式 */
{
  printf("%d\n", MyFunction());  /* Error: forgot argument to MyFunction */
  return 0;
}

int MyFunction( int n )  /* 简:被调用的函数声明 正:被呼叫的函式宣告 */
{
  if (n == 0)
  {
    return 1;
  }
  else
  {
    return n * MyFunction(n - 1);
  }
}

函式MyFunction被呼叫時會請求一個位於堆疊暫存器中的整數型別參數。如果省略函式原型,編譯器將無法執行此操作,函式MyFunction將在堆疊上的其他一些資料上執行(可能是回傳位址英語Return statement或當前不在作用域中的變數的值)。透過包含函式原型,您將通知編譯器函式myFunction接受一個整型參數,並使編譯器能夠擷取這些型別的錯誤,並使編譯過程順利執行。

透過包含函式原型,你可以告知編譯器函式MyFunction接受一個整數參數,並使編譯器能夠擷取這些型別的錯誤,使編譯過程順利執行。該特性已從C99標準中刪除,因此省略函式原型將導致編譯錯誤。[來源請求]


建立函式庫介面

透過在標頭檔中放置函式原型,可以為函式庫指定介面。

宣告類別

在C++中,函式原型也在類別定義中使用。

參見

參考文獻