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——函数定义的更多相关文章

  1. ISO/IEC 9899:2011 条款6.7.8——类型定义

    6.7.8 类型定义 语法 1.typedef-name: identifier 约束 2.一个typedef名指定了一个可变修改的类型,然后它应该具有语句块作用域. 语义 3.在一个声明中,该声明的 ...

  2. ISO/IEC 9899:2011 条款6.7.4——函数说明符

    6.7.4 函数说明符 语法 1.function-specifier: inline _Noreturn 约束 2.函数说明符应该只能被用在对一个函数标识符的声明中. 3.对一个含有外部连接函数的内 ...

  3. ISO/IEC 9899:2011 条款3——术语、定义与符号

    3. 术语.定义与符号 1.对于此国际标准的意图,应用了以下定义.其它术语是在用斜体类型或一个语法规则左侧出现的地方定义.在本国际标准中所显式定义的术语不被假定为对其它地方所定义的类似术语的隐式引用. ...

  4. ISO/IEC 9899:2011 条款5——5.2.1 字符集

    5.2.1 字符集 1.两个字符集和它们相关联的依次顺序应该被定义:写在源文件中的集合(源字符集),以及在执行环境中被解释的集合(执行字符集).每个集合此外被划分为一个基本字符集,其内容由本子条款给出 ...

  5. ISO/IEC 9899:2011 条款6.4.2——标识符

    6.4.2 标识符 6.4.2.1 通用 语法 1.identifier: identifier-nodigit identifier    identifier-nondigit identifie ...

  6. ISO/IEC 9899:2011 条款6.4.3——通用字符名

    6.4.3 通用字符名 语法 1.通用字符名: universal_character-name: \u hex-quad(四位十六进制数) \U hex-quad hex-quad hex-quad ...

  7. ISO/IEC 9899:2011 条款6.7.6——声明符

    6.7.6 声明符 语法 1.declarator: pointeropt    direct-declarator direct-declarator: identifier (    declar ...

  8. ISO/IEC 9899:2011 条款6.7.3——类型限定符

    6.7.3 类型限定符 语法 1.type-qualifier: const restrict volatile _Atomic 约束 2.除了指针类型(其被引用的类型是一个对象类型)之外的类型,不应 ...

  9. ISO/IEC 9899:2011 条款5——5.2.4 环境限制

    5.2.4 环境限制 1.翻译与执行环境都约束了语言翻译器和库的实现.下面概述了对一个顺应标准实现的语言相关的环境限制:库相关的限制在条款7中讨论. 5.2.4.1 翻译限制 1.实现应该能够翻译并执 ...

随机推荐

  1. 渗透之路基础 -- 跨站伪造请求CSRF

    漏洞产生原因及原理 跨站请求伪造是指攻击者可以在第三方站点制造HTTP请求并以用户在目标站点的登录态发送到目标站点,而目标站点未校验请求来源使第三方成功伪造请求. XSS利用站点内的信任用户,而CSR ...

  2. P1169 [ZJOI2007]棋盘制作[悬线法/二维dp]

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8 \times 88×8大小的黑白相间的方阵,对应八八六十四卦,黑白 ...

  3. [Schematics] 1. Copy and Manipulate Template

    1. Create a src/my-component/files/src/app directory to hold your templates. mkdir -p src/my-compone ...

  4. (二)IDEA使用,快捷键

    idea的快捷键设置: idea支持使用其他开发工具的快捷键,可以在此设置: idea 默认的本身的快捷键: 常用快捷键 Ctrl + Alt + s 打开设置选项 Alt + Enter 修复提示 ...

  5. SpringBoot第一次案例(以及jar包的生成)

    一.Springboot简介 Springboot框架就用于简化Spring应用的开发,约定大于配置,去繁从简.从以往的“Spring全家桶时代”正式过渡到”Spring boot,J2EE一站式解决 ...

  6. Poj 3233 Matrix Power Series(矩阵乘法)

    Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Description Given a n × n matrix A and ...

  7. 洛谷P1039侦探推理题解

    #include<cstdio> #include<cstring> #include<string> #include<iostream> using ...

  8. 读取中文文件到CString

      CString strFileName = _T("D:\\ai\\100.json"); CFile file; file.Open(strFileName, CFile:: ...

  9. mac Understand 安装破解

    下载:链接:https://pan.baidu.com/s/1UvxgFnjv9pRVJmZO-J2OrQ  密码:nyd4 启动后,开始激活,点击enter License code 点击“use ...

  10. 模板 - 数据结构 - 可持久化无旋Treap/PersistentFHQTreap

    有可能当树中有键值相同的节点时,貌似是要对Split和Merge均进行复制的,本人实测:只在Split的时候复制得到了一个WA,但只在Merge的时候复制还是AC,可能是恰好又躲过去了.有人说假如确保 ...