在学习C语言函数的时候,老师总会告诉我们函数要写声明,然后再定义。这是个稳健的做法。等我自己学习了其他高级语言以后,回头再来写C,突然就觉得函数要写声明有点麻烦。无意间发现有一次函数没写声明居然编译(GCC 5.3)也通过了,而且都没有报错。于是想起来要好好研究一下这个C语言的函数声明什么时候可以不写,什么时候必须写。

这其实谈不上是技术性问题。就好像讨论i++ 和++i那么无聊。这都是编译器导致的语法问题。说他们都是历史遗留问题都不为过。

但是在C语言学习过程中,你不得不去把这些鬼问题弄清楚。这样在以后面对千奇百怪的C语言代码的时候才能做到内心毫无波动。

有的书上是这么说的,如果函数定义放在main函数前面,可以不用写声明。如果函数放在main函数后面,就规定要写函数声明。这么说没毛病。不过我自己又无聊地尝试了一下,发现了更准确的规则。如果在函数定义在这个函数调用之前,就不需要写声明。否则就要写声明。

关于这个函数定义的位置其实也是个可以摸索的事情。C语言不允许在一个函数中定义其他函数,但是main函数除外。我发现可以在main函数中定义函数。如果你在main函数中定义函数,如果在函数被调用之前就定义了这个函数,那么就不需要声明了,这样编译连警告都没有,如果你在main函数中定义函数,而函数定义的位置比函数调用还要后,那么就无法通过编译了。进一步做无聊事情,假设我们在函数调用语句之后再定义函数,这个条件下有两种情况(单文件下),在main函数外面定义这个函数,编译会出警告信息,但是可以通过。如果是在main函数里面定义的。那就编译就会有警告+错误信息。

同样的关于函数声明的位置也是可以无聊地摸索一下。因为函数声明可以放在main函数外面,也可以放在main函数里面。我说可以放在main函数外面肯定说的是放在main函数上面。这个是正常做法。有的书会把声明放在main函数里面,也是可以的。只要只要声明函数的位置在函数调用前面就OK了。由此可以弱弱地推测出,C编译器是看到了声明,然后去寻找对应函数定义进行编译。如果没有声明,但是函数定义写在函数调用前面,那这个函数定义也比函数调用的代码先一步编译了也没问题了。这个弱弱地推测,就可以解释我以上无聊的实验结果了。

当时除了我这样无聊的初学者,谁会一直在main函数里写函数呢?

C语言函数声明什么时候可以省略,什么时候不能省?的更多相关文章

  1. 05. Go 语言函数

    Go 语言函数 函数是组织好的.可重复使用的.用来实现单一或相关联功能的代码段,其可以提高应用的模块性和代码的重复利用率. Go 语言支持普通函数.匿名函数和闭包,从设计上对函数进行了优化和改进,让函 ...

  2. C语言中函数声明实现的位置

    在学习C语言的时候我遇到了这么个事情,因为之前先学习的C#,在C#编译器中,函数的声明位置不会影响编译的结果,但是在C语言中却发生了错误 先看一段代码: #include <stdio.h> ...

  3. C语言函数的声明以及函数原型

    C语言代码由上到下依次执行,原则上函数定义要出现在函数调用之前,否则就会报错.但在实际开发中,经常会在函数定义之前使用它们,这个时候就需要提前声明.所谓声明(Declaration),就是告诉编译器我 ...

  4. c语言中的隐式函数声明(转)

    本文转自:http://www.jb51.net/article/78212.htm 在c语言里面开来还是要学习c++的编程习惯,使用函数之前一定要声明.不然,即使编译能通过,运行时也可能会出一些莫名 ...

  5. 万恶之源:C语言中的隐式函数声明

    1 什么是C语言的隐式函数声明 在C语言中,函数在调用前不一定非要声明.如果没有声明,那么编译器会自己主动依照一种隐式声明的规则,为调用函数的C代码产生汇编代码.以下是一个样例: int main(i ...

  6. C语言的函数声明,定义,调用以及exit退出

    #include <stdio.h> #include <stdlib.h> void singing(); int main() { singing(); system(&q ...

  7. C与C++的函数声明中省略参数的不同意义

    一直都以为C/C++中形如 int func(); 这样的函数声明其意义就是一个参数 void(没有参数)的函数.然而今天在看C++的时候突然看到这么一句: 对于带空参数表的函数,C和C++有很大的不 ...

  8. C语言的“隐式函数声明”违背了 “前置声明” 原则

    这个问题来源于小组交流群里的一个问题: 最终问题落脚在 : 一个函数在main中调用了,必须在main之前定义或者声明吗? 我在自己的Centos上做了实验,结果是函数不需要,但是结构体(变量也要)需 ...

  9. C语言中函数声明、形参、实参

    函数原型: 原型prototype是函数的声明:描述了函数的返回值与参数: 函数原型说明了两点: 1.该函数的返回值 2.该函数的参数及其类型 ++++++++++++++++++++++++++++ ...

随机推荐

  1. 2.第一个python 程序

    第一个python程序 一..python程序的编写步骤 1.创建  xxx.py文件(文件名不要中文) 文件名要以py为扩展名,因为导入的时候其他扩展名会报错.如果不导入的情况可以不限制扩展名. 2 ...

  2. js点击出现二级菜单,点击二级菜单主菜单换成二级菜单

    点击出现二级菜单 *{ margin:0px auto; padding:0px; } .yiji{ width:200px; height:40px; background-color:red; c ...

  3. Linux程序性能分析和火焰图

    Linux程序性能分析和火焰图 Linux程序的性能分析工具数量比较多,涉及到整个操作系统的方方面面,可能是开源的原因吧,相对于Windows来说丰富太多.其中应用分析性能方面Dtrace, Syst ...

  4. pygame 游戏舞台搭建典型应用

    #两个文件要放在同一目录中,包括图片 一.搭建游戏舞台主程序 #!/usr/bin/env python3#_*_coding:utf-8_*_ author ==$ VACyp import sys ...

  5. zimbra填坑记录

    邮件服务器上架,问题记录. 1.DNS解析设置,zimbra收发邮件均使用统一域名,mail.xxxx.com.cn,因此在做SMTP,POP,MX记录时均应指向此域名. 2.实际上架内部网络和安装所 ...

  6. git 本地提交代码到 github 远程库,没有弹框 github login

     git 本地提交代码到 github 远程库,没有弹框 github login:  原因: win10 有个凭据管理器,给保存了历史登陆用户名密码,导致无法切换用户. 解决办法: 删除历史登陆用户 ...

  7. pandas 时间格式转换

    OUTLINE 常见的时间字符串与timestamp之间的转换 日期与timestamp之间的转换 常见的时间字符串与timestamp之间的转换 这里说的字符串不是一般意义上的字符串,是指在读取日期 ...

  8. Matlab学以致用--模拟os任务装载情况

    2012-06-08 21:26:42 用matlab来建模,仿真不同时刻os task在队列中的装载情况.输入参数如下 作为初学者,M文件写的有点长.能实现功能就算学以致用了. clear;clc ...

  9. Linux基础篇

    Linux入门 2.1 Linux介绍 1)Linux是一款操作系统,特点:免费.开源.安全.高效.稳定.处理高并发非常强悍,半年至一年重启一次机即可,比Windows强悍,现在很多企业级项目都部署到 ...

  10. Solr中在使用过程中遇到的"与"和"或"的问题

    在进行全文检索的过程中,如果使用三星和手机,两个一块进行搜索的时候,关于三星的会被搜索出来,关于手机的信息也会被搜索出来,然后,需要将一些配置文件进行配置, <!-- DEPRECATED: T ...