C 参考手册
- C 语言
- C 的历史
- 基本概念
- 表达式
- 声明
- 初始化
- 函数
- 语句
- 静态断言
- 字符常量
- 函数声明
- 函数定义
- 转义序列
- 翻译阶段
- 标识符
- 作用域
- 生存期
- 查找与命名空间
- ASCII 码表
- 类型
- 遵从性
- 算术类型
- restrict 类型限定符
- 类型
- 对象与对齐
- 主函数
- 未定义行为
- 内存模型
- if 语句
- switch 语句
- for 循环
- while 循环
- do-while 循环
- continue语句
- break 语句
- goto语句
- return 语句
- 值类别
- 求值顺序
- 整数常量
- 浮点常量
- 字符串字面量
- 复合字面量
- 常量表达式
- 隐式转换
- 成员访问运算符
- 逻辑运算符
- 比较运算符
- 算术运算符
- 赋值运算符
- 自增/自减运算符
- 其他运算符
- sizeof 运算符
- _Alignof 运算符
- 转型运算符
- C 运算符优先级
- 泛型选择
- 标量初始化
- 数组初始化
- 结构体与联合体初始化
- 指针声明
- 数组声明
- 枚举
- 存储类指定符
- const 类型限定符
- volatile 类型限定符
- 结构体声明
- 联合体声明
- 位域
- _Alignas
- typedef 声明
- 原子类型
- 外部及试探性定义
- inline 函数指定符
- _Noreturn 函数指定符
- 变长参数
- 内联汇编
- 可分析性
- 替用运算符及记号
- C 关键词
- 预处理器
- C 标准库头文件
- 类型支持
- 程序支持工具
- 变参数函数
- 错误处理
- 动态内存管理
- 日期和时间工具
- 字符串库
- 算法
- 数值
- 文件输入/输出
- 本地化支持
- 原子操作库
- 线程支持库
- 实验性 C 标准库
- 有用的资源
- 符号索引
- 注释
函数定义
函数定义将函数体(声明与语句的序列)与函数名及参数列表关联。不同于函数声明,函数定义只允许在文件作用域(不存在嵌套函数)。
C 支持二种函数定义的形式:
说明符与限定符 形参列表声明符 函数体 | (1) | ||||||||
说明符与限定符 标识符列表声明符 声明列表 函数体 | (2) | (C2x 前) | |||||||
其中
说明符与限定符 | - | 下列的组合 |
形参列表声明符 | - | 用参数列表指代函数参数的函数类型的声明器 |
标识符列表声明符 | - | 用标识符列表指代函数参数的函数类型的声明器 |
声明列表 | - | 在 标识符列表声明符 中声明每个参数的声明序列。这些声明不能使用初始化器,而且仅允许 register 作为存储类说明符。 |
函数体 | - | 复合语句,是花括号所包括的声明及语句序列,只要调用此函数就会被执行 |
1) 新式 (C89) 函数定义。此定义引入函数自身,并为任何将来的函数调用表达式提供函数原型,强迫从实参表达式转换到声明形参类型。
int max(int a, int b) { return a>b?a:b; } double g(void) { return 0.1; }
2) (C2x 前) 旧式 (K&R) 函数定义。此定义不表现为原型,而任何将来的函数调用表达式将进行默认参数提升。
int max(a, b) int a, b; { return a>b?a:b; } double g() { return 0.1; }
解释
同函数声明,函数的返回类型由 说明符与限定符 中的类型说明符确定,并像在声明中一样可以由 声明符 修改。返回类型必须是完整的非数组对象类型或 void 类型。
同函数声明,若返回类型会有 cvr 限定,则为构造函数类型的目的,将它调整到其无限定版本。 |
(C17 起) |
同函数声明,为构造函数类型的目的,将参数类型从函数调整到指针,从数组调整到指针,并且为确定兼容函数类型的目的,忽略所有参数类型的顶层 cvr 限定符。
不同于函数声明,不允许无名形参,即使不在函数中使用也必须命名它们。仅有的例外是参数列表 (void) 。
int f(int, int); // 声明 // int f(int, int) { return 7; } // 错误 int f(int a, int b) { return 7; } // 定义 int g(void) { return 8; } // OK : void 不声明参数
在函数体内,每个参数都是左值表达式,它们拥有自动存储期和块作用域。参数在内存中的布局(或者它们究竟是否存储于内存中)是未指定的:这是调用约定的一部分。
int main(int ac, char **av) { ac = 2; // 参数是左值 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 是类型为 int(int, int) 的函数 p f { return q + r; } // 错误
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