?
? ????? PHP ??? ???? ??? ?? ??
函數(shù)聲明引入了一個指定函數(shù)的標識符,并且可選地指定函數(shù)參數(shù)的類型(原型)。函數(shù)聲明(與定義不同)可能出現(xiàn)在塊作用域和文件作用域中。
在函數(shù)聲明的聲明語法中,可能由聲明者修改的類型說明符序列指定返回類型(可以是除數(shù)組或函數(shù)類型之外的任何類型),聲明符具有以下兩種形式之一:
noptr-declarator ( parameter-list ) | (1) | |
---|---|---|
noptr-declarator ( identifier-list(optional) ) | (2) |
其中
noptr聲明符 | - | 除unparenthesized指針聲明符外的任何聲明符。包含在此聲明器中的標識符是成為函數(shù)標識符的標識符。 |
---|---|---|
參數(shù)列表 | - | 無論是單個關(guān)鍵字void還是以逗號分隔的參數(shù)列表(可能以省略號參數(shù)結(jié)尾) |
標識符表 | - | 逗號分隔的標識符列表(只有在該聲明符被用作舊式函數(shù)定義的一部分時),對于不是定義的舊式聲明,必須省略。 |
1)新式(C89)函數(shù)聲明。該聲明既引入了函數(shù)指示符本身,也作為未來函數(shù)調(diào)用表達式的函數(shù)原型,強制從參數(shù)表達式轉(zhuǎn)換為聲明的參數(shù)類型,并對參數(shù)個數(shù)進行編譯時檢查。
int max(int a, int b); // declarationint n = max(12.01, 3.14); // OK, conversion from double to int
2)舊式(K&R)功能聲明。這個聲明不像原型,任何未來的函數(shù)調(diào)用表達式都會執(zhí)行默認的參數(shù)提升,并且如果參數(shù)的數(shù)量與參數(shù)的數(shù)量不匹配,將會調(diào)用未定義的行為。
int max();int n = max(true, (char)'a'); // calls max with two int args (after promotions)int n = max(12.01f, 3.14); // calls max with two double args (after promotions)int max(a, b) int a, b; { return a>b?a:b; } // definition expects ints; the second call is undefined
函數(shù)的返回類型由聲明符中的類型說明符確定,并可能在聲明中像通常那樣可能由聲明器修改,這些類型必須是完整的非數(shù)組對象類型或類型void
。
void f(char *s); // return type is voidint sum(int a, int b); // return type of sum is int.int (*foo(const void *p))[3]; // return type is pointer to array of 3 int
函數(shù)聲明符可以與其他聲明符合在一起,只要它們可以共享它們的類型說明符和限定符。
int f(void), *fip(), (*pfi)(), *ap[3]; // declares two functions and two objectsinline int g(int), n; // error: inline qualifier is for functions onlytypedef int array_t[3];array_t a, h(); // error: array type cannot be a return type for a function
如果函數(shù)聲明出現(xiàn)在任何函數(shù)之外,它引入的標識符具有文件范圍和外部鏈接,除非static
被使用或者以前的靜態(tài)聲明是可見的。如果聲明發(fā)生在另一個函數(shù)中,則該標識符具有塊范圍(并且還有內(nèi)部或外部鏈接)。
int main(void){ int f(int); // external linkage, file scope f(1); // definition needs to be available somewhere in the program}
聲明中不是函數(shù)定義一部分的參數(shù)不需要命名:
int f(int, int); // declaration// int f(int, int) { return 7; } // Error, parameters must be named in definitions
參數(shù)列表中的每個參數(shù)都是引入單個變量的聲明,并具有以下附加屬性:
聲明符中的標識符是可選的(除非該函數(shù)聲明是函數(shù)定義的一部分)
int f(int, double); // OKint g(int a, double b); // also OKint f(int, double) { return 1; } // Error: definition must name parameters
唯一允許存在參數(shù)的存儲類說明符是register
,并且它在函數(shù)聲明中被忽略,而非定義
int f(static int x); // Errorint f(int [static 10]); // OK (array index static is not a storage class specifier)
數(shù)組類型的任何參數(shù)都會調(diào)整為相應(yīng)的指針類型,如果數(shù)組聲明符的方括號之間存在限定符(可能為C99)
int f(int[]); // declares int f(int*)int g(const int[10]); // declares int g(const int*)int h(int[const volatile]); // declares int h(int * const volatile)int x(int[*]); // declares int x(int*)
函數(shù)類型的任何參數(shù)都會被調(diào)整為相應(yīng)的指針類型
int f(char g(double)); // declares int f(char (*g)(double))int h(int(void)); // declares int h(int (*)(void))
參數(shù)列表可能會終止, ...
,詳見可變參數(shù)函數(shù)。
int f(int, ...);
參數(shù)不能有類型void
(但可以有指向void的類型指針)。完全由關(guān)鍵字組成的特殊參數(shù)列表void
用于聲明不帶參數(shù)的函數(shù)。
int f(void); // OKint g(void x); // Error
出現(xiàn)在參數(shù)列表中的任何標識符都可以作為typedef名稱或參數(shù)名稱處理為 typedef 名稱:int f(size_t,
uintptr_t)
被解析為函數(shù)的新樣式聲明器,該函數(shù)采用兩個未命名的 size_t 和 uintptr_t 類型的參數(shù),而不是一個舊式的聲明器,它以一個名為 “size_t” 和 “uintptr_t” 的參數(shù)開始函數(shù)的定義。
參數(shù)可能有不完整的類型,并可能使用 VLA 符號*(除了在函數(shù)定義中,數(shù)組間指針和函數(shù)指針調(diào)整后的參數(shù)類型必須完整)
有關(guān)函數(shù)調(diào)用機制的其他詳細信息,請參閱函數(shù)調(diào)用運算符,然后返回以從函數(shù)返回。
不像在 C ++中,說明符f()
和f(void)
具有不同的含義:該聲明符f(void))
是一種新的風(fēng)格(原型)聲明符聲明一個函數(shù),它沒有參數(shù)。聲明符f()
是一種舊式(K&R)聲明符,它聲明了一個函數(shù),該函數(shù)接受未指定數(shù)量的參數(shù)(除非在舊式函數(shù)定義中使用)。
int f(void); // declaration: takes no parametersint g(); // declaration: takes unknown parameters int main(void) { f(1); // compile-time error g(2); // undefined behavior} int f(void) { return 1; ) // actual definitionint g(a,b,c,d) int a,b,c,d; { return 2; } // actual definition
與函數(shù)定義不同,參數(shù)列表可以從 typedef 繼承。
typedef int p(int q, int r); // p is a function type int(int, int)p f; // declares inf f(int, int)
在 C89中,說明符和限定符是可選的,如果省略,函數(shù)的返回類型默認為 int(可能由聲明者修改)。* f(){//函數(shù)返回 int *返回NULL; } | (直到C99) |
---|
C11 standard (ISO/IEC 9899:2011):
6.7.6.3 Function declarators (including prototypes) (p: 133-136)
C99 standard (ISO/IEC 9899:1999):
6.7.5.3 Function declarators (including prototypes) (p: 118-121)
C89/C90 standard (ISO/IEC 9899:1990):
3.5.4.3 Function declarators (including prototypes)