函式定義
函式定義將函式體(一系列宣告和語句)與函式名和引數列表關聯起來。與函式宣告不同,函式定義只允許在檔案作用域內(沒有巢狀函式)。
C 支援兩種不同形式的函式定義
attr-spec-seq(可選) specifiers-and-qualifiers parameter-list-declarator function-body | (1) | ||||||||
specifiers-and-qualifiers identifier-list-declarator declaration-list function-body | (2) | (直至 C23) | |||||||
其中
屬性說明序列 | - | (C23)應用於函式的屬性的可選列表 |
specifiers-and-qualifiers | - | 以下各項的組合 |
parameter-list-declarator | - | 用於函式型別的宣告符,它使用引數列表來指定函式引數 |
identifier-list-declarator | - | 用於函式型別的宣告符,它使用識別符號列表來指定函式引數 |
declaration-list | - | 宣告序列,宣告identifier-list-declarator中的每個識別符號。這些宣告不能使用初始化器,並且唯一允許的儲存類說明符是register。 |
function-body | - | 一個複合語句,即一個用大括號括起來的宣告和語句序列,每當呼叫此函式時都會執行 |
int max(int a, int b) { return a>b?a:b; } double g(void) { return 0.1; }
int max(a, b) int a, b; { return a>b?a:b; } double g() { return 0.1; }
目錄 |
[編輯] 解釋
與函式宣告一樣,函式的返回型別(由specifiers-and-qualifiers中的型別說明符決定,並可能像宣告中通常那樣被declarator修改)必須是完整的非陣列物件型別或void型別。如果返回型別是 cvr-qualified,則為了建構函式型別,它會調整為非限定版本。
與函式宣告一樣,為了建構函式型別,引數的型別會從函式調整為指標,從陣列調整為指標,並且為了確定相容函式型別,所有引數型別的頂層 cvr-限定符都被忽略。
與函式宣告不同,不允許使用未命名的形式引數(否則,舊式 (K&R) 函式定義中會出現衝突),即使它們在函式中未使用,也必須命名。唯一的例外是特殊引數列表(void)。 |
(直至 C23) |
形式引數在函式定義中可以不命名,因為舊式(K&R)函式定義已被移除。未命名的引數在函式體內無法透過名稱訪問。 |
(自 C23 起) |
int f(int, int); // declaration // int f(int, int) { return 7; } // Error until C23, OK since C23 int f(int a, int b) { return 7; } // definition int g(void) { return 8; } // OK: void doesn't declare a parameter
在函式體內,每個命名引數都是一個左值表示式,它們具有自動儲存期和塊作用域。引數在記憶體中的佈局(或者它們是否儲存在記憶體中)未指定:它是呼叫約定的一部分。
int main(int ac, char **av) { ac = 2; // parameters are lvalues av = (char *[]){"abc", "def", NULL}; f(ac, av); }
有關函式呼叫機制的其他詳細資訊,請參見函式呼叫運算子,有關從函式返回的資訊,請參見return。
__func__在每個函式體內,特殊預定義變數__func__,具有塊作用域和靜態儲存期,可用,如同緊接在開大括號後由以下內容定義: static const char __func__[] = "function name"; |
(C99 起) |
[編輯] 注意
引數列表必須明確地出現在宣告符中,不能從 typedef 繼承
typedef int p(int q, int r); // p is a function type int(int, int) p f { return q + r; } // Error
在 C89 中,specifiers-and-qualifiers 是可選的,如果省略,函式的返回型別預設為int(可能由declarator修改)。 此外,舊式定義不需要為declaration-list中的每個引數提供宣告。任何缺少宣告的引數都具有int型別 max(a, b) // a and b have type int, return type is int { return a>b?a:b; } |
(直到 C99) |
[編輯] 缺陷報告
以下行為改變的缺陷報告被追溯地應用於以前釋出的 C 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
DR 423 | C89 | 返回型別可能受限 | 返回型別隱式解除限定 |
[編輯] 參考
- C17 標準 (ISO/IEC 9899:2018)
- 6.9.1 函式定義 (p: 113-115)
- C11 標準 (ISO/IEC 9899:2011)
- 6.9.1 函式定義 (p: 156-158)
- C99 標準 (ISO/IEC 9899:1999)
- 6.9.1 函式定義 (p: 141-143)
- C89/C90 標準 (ISO/IEC 9899:1990)
- 3.7.1 函式定義
[編輯] 另請參閱
C++ 文件,關於函式定義
|