函數原型
此條目需要補充更多來源。 (2018年12月17日) |
在電腦程式設計中,函數原型(英語:Function prototype)或函數接口(英語:Function interface)是用於指定函數的名稱和類型簽名(元數,參數的數據類型和返回值類型)的一種省略了函數體的函數聲明。雖然函數聲明規定了函數是如何被實現的,但僅包括對接口的定義(即接受的數據類型和返回的數據類型),並不包括對函數體的定義。
函數原型被廣泛應用於C、C++ 語言程序代碼的上下文中,通過在頭文件中放置函數的前向聲明來允許將代碼拆分為多個翻譯單元。即編譯器可以單獨編譯目標文件的這部分內容,然後由鏈接器組合成可執行文件或庫。現代編譯器(如Arduino IDE)不再需要函數原型,因為這些是在編譯時被確定和聲明的。
在原型中,參數名是可選的(C/C++中存在函數原型作用域,這使參數名的作用域被限制在函數定義內),但是,類型和修飾符都是必需的(如指針或常量參數)。
舉例
有函數原型如下:
void Sum(int a,int b);
或
void Sum(int, int);
首先,函數原型包括函數簽名(英語:function signature),函數名,返回類型和訪問修飾符。在該例中,函數的名稱是「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將在堆棧上的其他一些數據上運行(可能是返回地址或當前不在作用域中的變量的值)。通過包含函數原型,您將通知編譯器函數myFunction接受一個整型參數,並使編譯器能夠捕獲這些類型的錯誤,並使編譯過程順利運行。
通過包含函數原型,你可以告知編譯器函數MyFunction接受一個整數參數,並使編譯器能夠捕獲這些類型的錯誤,使編譯過程順利運行。該特性已從C99標準中刪除,因此省略函數原型將導致編譯錯誤。[來源請求]
建立函式庫介面
通過在頭文件中放置函數原型,可以為庫指定接口。
聲明類別
在C++中,函數原型也在類定義中使用。
參見
參考文獻
- Kernighan, Brian W.; Ritchie Afree, Dennis M. The C Programming Language 2nd. Upper Saddle River, NJ: Prentice Hall PTR. 1988. ISBN 0-13-110362-8.