ISO/IEC 9899:2011 条款6.9.1——函数定义
6.9.1 函数定义
语法
1、function-definition:
declaration-specifiers declarator declaration-listopt compound-statement
declaration-list:
declaration
declaration-list declaration
约束
2、在一个函数定义中所声明的标识符(它是函数名)应该是一个函数类型,它通过函数定义的声明符部分指定。[注:这样的目的是在一个函数定义中的类型类别不能从一个typedef继承:
typedef int F(void); // 类型F是一个“返回int,不带有形参的函数”
F f, g; // f和g都具有与F相兼容的类型
F f { /* ... */ } // 错误:语法/约束错误
F g() { /* ... */ } // 错误:将g声明为返回一个函数
int f(void) { /* ... */ } // 正确:f具有与F相兼容的类型
int g() { /* ... */ } // 正确:g具有与F相兼容的类型
F *e(void) { /* ... */ } // e返回指向一个函数的指针
F *((e))(void) { /* ... */ } // 与上述相同,不用去管圆括号
int (*fp)(void); // fp指向具有类型F的一个函数
F *fp; // fp指向一个具有类型F的函数
]
3、一个函数的返回类型应该是void或一个完整的对象类型,但不能是数组类型。
4、如果存在存储类说明符,那么在声明说明符中应该要么是extern,要么是static。
5、如果声明符包含一个形参类型列表,那么每个形参的声明应该包含一个标识符,除了一个形参列表由一单个void类型形参构成的特殊情况,在这种情况下,不应该有一个标识符。后面不应该跟着任何声明列表。
6、如果声明符包含了一个标识符列表,那么在声明列表中的每个声明应该至少具有一个声明符,那些声明符应该尽从声明列表声明标识符,并且标识符列表中的每个标识符应该被声明。被声明为一个typedef名的一个标识符不应该重新声明为一个形参。在声明列表中的声明不应该包含除了register之外的其它存储类说明符,并且不能包含初始化。
语义
7、一个函数定义中的声明符指定了正被定义的函数名以及其形参标识符。如果声明符包含一个形参类型列表,那么该列表也指定了所有形参的类型;这么一个声明符也担任一个函数原型为稍后对同一函数的调用,在同一翻译单元中。如果声明符包含了一个标识符列表,[注:见“未来语言方向”(6.11.7)。]形参的类型应该在后续声明列表中被声明。在任何一种情况下,一个形参类型列表的每个形参的类型被调整为6.7.6.3中描述的;结果类型应该是一个完整的对象类型。
8、如果接受一可变数量实参的函数定义时没有一个用省略号记号结尾的形参类型列表,那么行为是未定义的。
9、每个形参具有自动存储周期;其标识符是一个左值。[注:一个形参标识符不能在函数体内被重新声明,除了在一个封闭的语句块内。]形参存储的布局是未定义的。
10、在函数入口处,每个可变修改的形参的size表达式都被计算,并且每个实参表达式的值被转换为相应形参的类型,就好比是一个赋值操作。(作为实参的数组表达式与函数指派符在调用之前被转换为指针。)
11、在所有形参被赋值之后,由函数定义体所构成的复合语句被执行。
12、如果终结一个函数的}到达,那么行为是未定义的。
13、例1 在下列代码中:
extern int max(int a, int b)
{
return a > b ? a : b;
}
extern是存储类说明符,而int是类型说明符;max(int a, int b)是函数声明符;{ return a > b ? a : b; } 是函数体。以下类似的定义使用了标识符列表形式给形参声明:
extern int max(a, b)
int a, b;
{
return a > b ? a : b;
}
这里int a, b;是形参的声明列表。这两个定义的不同之处是第一种形式扮演了一个原型声明,它迫使后续对此函数的调用对实参类型进行转换,而第二种形式则不然。
14、例2 为了将一个函数传递给另一个,有人会说
int f(void);
/* ... */
g(f);
然后对g的定义可能写作
void g(int (*funcp)(void))
{
/* ... */
(*funcp)(); /* 或funcp(); ... */
}
或者等价地
void g(int func(void))
{
/* ... */
func(); /* 或(*func)(); ... */
}
本结完。
ISO/IEC 9899:2011 条款6.9.1——函数定义的更多相关文章
- ISO/IEC 9899:2011 条款6.7.8——类型定义
6.7.8 类型定义 语法 1.typedef-name: identifier 约束 2.一个typedef名指定了一个可变修改的类型,然后它应该具有语句块作用域. 语义 3.在一个声明中,该声明的 ...
- ISO/IEC 9899:2011 条款6.7.4——函数说明符
6.7.4 函数说明符 语法 1.function-specifier: inline _Noreturn 约束 2.函数说明符应该只能被用在对一个函数标识符的声明中. 3.对一个含有外部连接函数的内 ...
- ISO/IEC 9899:2011 条款3——术语、定义与符号
3. 术语.定义与符号 1.对于此国际标准的意图,应用了以下定义.其它术语是在用斜体类型或一个语法规则左侧出现的地方定义.在本国际标准中所显式定义的术语不被假定为对其它地方所定义的类似术语的隐式引用. ...
- ISO/IEC 9899:2011 条款5——5.2.1 字符集
5.2.1 字符集 1.两个字符集和它们相关联的依次顺序应该被定义:写在源文件中的集合(源字符集),以及在执行环境中被解释的集合(执行字符集).每个集合此外被划分为一个基本字符集,其内容由本子条款给出 ...
- ISO/IEC 9899:2011 条款6.4.2——标识符
6.4.2 标识符 6.4.2.1 通用 语法 1.identifier: identifier-nodigit identifier identifier-nondigit identifie ...
- ISO/IEC 9899:2011 条款6.4.3——通用字符名
6.4.3 通用字符名 语法 1.通用字符名: universal_character-name: \u hex-quad(四位十六进制数) \U hex-quad hex-quad hex-quad ...
- ISO/IEC 9899:2011 条款6.7.6——声明符
6.7.6 声明符 语法 1.declarator: pointeropt direct-declarator direct-declarator: identifier ( declar ...
- ISO/IEC 9899:2011 条款6.7.3——类型限定符
6.7.3 类型限定符 语法 1.type-qualifier: const restrict volatile _Atomic 约束 2.除了指针类型(其被引用的类型是一个对象类型)之外的类型,不应 ...
- ISO/IEC 9899:2011 条款5——5.2.4 环境限制
5.2.4 环境限制 1.翻译与执行环境都约束了语言翻译器和库的实现.下面概述了对一个顺应标准实现的语言相关的环境限制:库相关的限制在条款7中讨论. 5.2.4.1 翻译限制 1.实现应该能够翻译并执 ...
随机推荐
- python算法与数据结构-快速排序算法(36)
一.快速排序的介绍 快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外 ...
- LG4723 【模板】常系数线性递推
P4723 [模板]常系数齐次线性递推 题目描述 求一个满足$k$阶齐次线性递推数列${a_i}$的第$n$项. 即:$a_n=\sum\limits_{i=1}^{k}f_i \times a_{n ...
- JOIN序列化过程中日期的处理
一.在后台进行处理: System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serializa ...
- 测试工具( Burp Suite)介绍了解篇
Mac 安装 Burp Suite破解版,参考链接: https://www.jianshu.com/p/3224c2308ffa 建议:目前官网的最新版为2.1.4.建议使用1.7.36版本,有破解 ...
- (15)打鸡儿教你Vue.js
组件化vue.js 组件单向绑定 组件双向绑定 组件单次绑定 创建组件构造器 注册组件 使用组件 Vue.extend() Vue.component() 使用组件 <div id=" ...
- 地区sql
/*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...
- ShellExecute打开文件,打开文件夹的用法
转自https://www.cnblogs.com/nxopen2018/p/11070031.html //方法1 //转换 //char msg[256]; //sprintf_s(msg, &q ...
- Django REST framework优点?
1.提供了定义序列化器Serializer的方法,可以快速根据Django ORM 或者其他库自动序列化/反序列化2.提供了丰富的类视图\MIXIN扩展类,简化视图的编写3.丰富的定制层级:函数视图\ ...
- CentOS 6.5开放端口方法
lsof -i tcp:80 列出所有端口 netstat -ntlp 1.开启端口(以80端口为例) 方法一: /sbin/iptables -I ...
- 我为什么选择Vim
总看到一些飞快敲击键盘而不用鼠标的时候你可以很羡慕和佩服,其实这完全没有必要.就像一个吉他手熟练地弹吉他有必要羡慕吗?一个瓦匠熟练地砌砖有必要羡慕吗?这些都是他们赖以生存的工具而已,熟练地运用工具是理 ...