在学习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. qt 画多边形(实现鼠标拖动节点)

    ---恢复内容开始--- 2018-01-06 这个小例子实现了移动鼠标,鼠标的坐标信息跟随鼠标移动,多边形的实现,鼠标点击可以拖动多边形点的位置,(其中有个问题?我在QMainWindow下,用mo ...

  2. openFileDialog的Filter属性设置

    OpenFileDialog对话框的Filter属性说明: 首先说明一个示例,分析一下Filter属性的构成:“ Excel文件|*.xls ”,前面的“Excel文件”成为标签,是一个可读的字符串, ...

  3. Java文件类型工具类

    package *; import java.util.HashMap; import java.util.Map; /** * <p> * <b>FileTypeEnum2& ...

  4. Windows system 在python文件操作时的路径表示方法

    file_path =(r'i:\vacpy\ch10\pi_digits.txt') #将文件路径存储在变量file_path中with open (file_path) as file_objec ...

  5. html5css练习 旋转

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  6. 【javascript】上拉下拉弹窗实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. vue.js国际化vue-i18n插件的使用问题,在模版文本、组件方法、jsf方法里的使用

    vue.js国际化vue-i18n插件的使用问题,在模版文本.组件方法.jsf方法里的使用 1.在文本里使用{{$t("xxx")}} <span>{{$t(" ...

  8. java面试经常问到的计算机网络问题

    GET 和 POST 的区别 GET请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:/test/demo_form.asp?name1=value1&name2=val ...

  9. Appium(一)---环境搭建的一些问题

    最近开始学习Appium,一款很不错的自动化测试工具,网上已经有大量的环境搭建教程,我就不再细说,我搭建环境时主要参考如下两个博客https://www.cnblogs.com/yoyoketang/ ...

  10. Py 最全的常用正则表达式大全 ZZ

    很多不太懂正则的朋友,在遇到需要用正则校验数据时,往往是在网上去找很久,结果找来的还是不很符合要求.所以我最近把开发中常用的一些正则表达式整理了一下,在这里分享一下.给自己留个底,也给朋友们做个参考. ...