©
This document uses PHP Chinese website manual Release
函数定义将函数体(声明和语句序列)与函数名称和参数列表关联起来。与函数声明不同,函数定义只允许在文件范围内(没有嵌套函数)。
C支持两种不同形式的函数定义:
specifiers-and-qualifiers parameter-list-declarator function-body | (1) | |
---|---|---|
specifiers-and-qualifiers identifier-list-declarator declaration-list function-body | (2) |
其中
符和限定符 | - | 类型说明符的组合,可能被声明器修改,形成返回类型存储类说明符,它确定标识符(静态,外部或无)与inline,noreturn或none |
---|---|---|
参数列表说明符 | - | 一个函数类型的声明符,它使用参数列表来指定函数参数 |
标识符列表说明符 | - | 一个函数类型的声明符,它使用标识符列表来指定函数参数 |
声明列表 | - | 在identifier-list-declarator中声明每个标识符的声明序列。这些声明不能使用初始化器,唯一允许的存储类说明符是寄存器。 |
功能体 | - | 一个复合语句,它是一个括号括起来的声明和语句序列,每当调用该函数时都会执行 |
可能由声明者修改的类型说明符构成返回类型
存储类说明符,其中确定所述识别符的键(static
,extern
或无)
函数说明符inline,noreturn或none
parameter-list-declarator - a declarator for a function type which uses a [parameter list](function_declaration) to designate function parameters identifier-list-declarator - a declarator for a function type which uses a [identifier list](function_declaration) to designate function parameters declaration-list - sequence of declarations that declare every identifier in identifier-list-declarator. These declarations cannot use initializers and the only [storage-class specifier](storage_duration) allowed is `register`. function-body - a [compound statement](statements#Compound_statements), that is a brace-enclosed sequence of declarations and statements, that is executed whenever this function is called
1)新式(C89)功能定义。该定义既引入了函数本身,又作为未来函数调用表达式的函数原型,强制从参数表达式转换为声明的参数类型。
int max(int a, int b){ return a>b?a:b;} double g(void){ return 0.1;}
2)旧式(K&R)功能定义。这个定义不像原型,任何未来的函数调用表达式都会执行默认参数促销。
int max(a, b)int a, b;{ return a>b?a:b;}double g(){ return 0.1;}
与函数声明一样,函数的返回类型由声明符中的类型说明符确定,并可能在声明中像通常一样由声明器修改,这些类型必须是完整的非数组对象类型或类型void
。
void f(char *s) { puts(s); } // return type is voidint sum(int a, int b) { return a+b: } // return type is intint (*foo(const void *p))[3] { // return type is pointer to array of 3 int return malloc(sizeof(int[3]));}
和函数声明一样,参数的类型从函数调整到指针,从数组到指针,为了构造函数类型,它们的顶级限定符被去除。
与函数声明不同,未命名的形式参数是不允许的,即使它们没有在函数中使用,它们也必须被命名。唯一的例外是特殊参数列表(void)
。
int f(int, int); // declaration// int f(int, int) { return 7; } // Errorint f(int a, int b) { return 7; } // definitionint 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);}
有关函数调用机制的其他详细信息,请参阅函数调用运算符,然后返回以从函数返回。
__func__在每个函数体中,可以使用具有块范围和静态存储持续时间的特殊预定义变量__func__,就像在紧跟在大括号之后定义的那样。static const char __func __ [] =“function name”; 这个特殊的标识符有时与预定义的宏常量__FILE__和__LINE__结合使用,例如通过assert。 | (自C99以来) |
---|
参数列表必须明确地出现在声明器中,它不能从 typedef 继承。
typedef int p(int q, int r); // p is a function type int(int, int)p f { return q + r; } // Error
在C89中,说明符和限定符是可选的,如果省略,函数的返回类型默认为int(可能由声明者修改)。另外,旧式定义不需要声明列表中的每个参数。任何声明缺失的参数都有int类型。max(a,b)// a和b的类型是int,返回类型是int {return a> b?a:b; } | (直到C99) |
---|
C11 standard (ISO/IEC 9899:2011):
6.9.1 Function definitions (p: 156-158)
C99 standard (ISO/IEC 9899:1999):
6.9.1 Function definitions (p: 141-143)
C89/C90 standard (ISO/IEC 9899:1990):
3.7.1 Function definitions