[C语言]为什么要有include?——从Hello World说起

本文转自:http://mp.weixin.qq.com/s?__biz=MzAwOTgzNzQyMw==&mid=433613487&idx=1&sn=803995d612faadce6e4418789a6a65a8&scene=2&srcid=0312ElIT9UmR0ZygPGHxDxs2&from=timeline&isappinstalled=0#wechat_redirect


大家都会写的Hello World程序长这个模样:

#include <stdio.h>

int main( ){

    printf("Hello world!\n");

    return 0;

}

看,关键的就是第三行,调用了printf函数,在屏幕上打印了伟大的"Hello world!"。第一行那个include是个啥?我听到过这样的解释:“include是包含的意思,尖括号里的stdio.h是标准输入输出函数库文件,这个文件里有printf的代码,把这个代码包含到main函数之前,就可以使用printf函数进行打印啦~” —— 打住!这种话骗骗刚开始学习C语言的小孩还可以,怎么可以用来骗大学生呢?现在请大家把第一行删除,重新编译运行看看?奇葩,居然依然可以顺利执行!但是细心的孩纸会发现,这次尽管成功运行了,但是编译时有一条警告(Warning)信息,如果你的编译器是gcc的话,这条Warning的样子应该是:

warning: implicitly declaring library function 'printf' with type 'int (const char *, ...)'

What?这是咩意思?冷静一下,请大家不要一看到英文就头皮发麻、六神无主、举手问老师。至少可以翻翻词典嘛,前两个词就很明白了:隐含声明。先不解释,我们继续修改代码,变成这样:

int main(){

    printf("Hello world!\n");

    hehe(3, 5);

    return 0;

}

然后大家就笑了:这肯定不能运行了吧?那个hehe()函数根本就不存在嘛!没错,这个确实不能运行了,但是依然可以编译。据我所知大家都很偷懒,编好程序之后都是直接在集成开发环境(IDE)中直接点运行按钮的,那么这次请点击编译按钮,或者在命令行中手动输入编译命令,我们就能发现,又多了一条Warning:

 warning: implicit declaration of function 'haha' is invalid in C99

又是“隐含声明”!

为什么printf和hehe两个函数都提示“隐含声明”,前一个能运行,而后一个不行呢?我们从头梳理:

首先,了解一下什么叫做函数的“声明”(或者叫“原型”)。函数声明就是描述一下这个函数长什么样子,而不描述这个函数具体怎么实现的。举个例子: void hehe(int, int); 就是一个函数的声明,注意,括号后面是一个分号,而不是一对花括号{ },而且括号里面只写了参量类型,没有写参量名啊。函数的声明是给编译器看的,当编译器看到上面那个声明,她就会知道:哦,有一个函数,名字叫hehe,带有两个整型参量,没有返回值。至于这个函数具体是干什么的,编译器不关心~ 同样,编译器也不关心这个函数的两个参量叫什么名字,所以列表中可以只写类型,不写参量名。

然后,我们大家都学过:C语言规范要求在调用函数之前,必须出现该函数的声明。这是为什么呢?是为了让编译器高兴啊。编译器从上往下检查代码,当看到函数调用时,就会对照此前出现过的声明检查一下调用是否符合声明的格式。如果冷不丁地看到一个函数调用,但在此之前没见到过该函数的声明,编译器就郁闷了,她的内心活动是:“这函数,没见过、不认识啊,所以,这么个调用法,到底是正确呢?还是错误呢?我不知道啊!我作为一个编译器,不知道这句是正确还是错误,多没面子啊!”这时候,编译器能报一个“错误”(Error)吗?不能。但是编译器究竟还是负责人的,她觉得这句话可能会有问题,因此给了一个警告,让程序员自己看着办……

接下来,分析一下为什么printf没有声明,能够正确执行。大家可以翻翻前面我说的那个“骗小孩子”的话,stdio.h里面并没有printf的实现代码,而是有printf的声明(请在自己计算机中自行搜索stdio.h,并打开文件查找printf,看看是如何声明的)。printf的实现代码,是在C标准库的其它文件中(随着OS不同,具体文件也不同)的,而且是编译过之后的代码,不像stdio.h中,都是“源代码”。如果把include那行删去,编译器在看到printf调用时,就不知道printf应该长成啥样,所以不知道调用是否正确,给了一个警告。但是在编译之后的“链接”过程,C标准库就被链接到程序中了,所以只要printf的调用写得没有错误,就可以正确运行。

最后,分析为什么添加hehe(3,5)之后能编译,但是不能正确执行。道理与上面是一样的,编译器看到hehe(3,5)的调用,因为没有声明过,她不认识这函数啊,所以,不能报错,只能给一个警告。接下来的步骤,链接,C标准库依然被链接到了程序中,但是……但是……但是……hehe( )是个什么鬼?这函数根本就不在C标准库中好吗!而且程序员自己所写的程序中也没有提供hehe( )的实现代码啊!所以链接失败……

哦,似乎忘了说,C代码写好之后要想运行,得经过这么几步:(1)对每个源文件分别进行编译(compile),各自生成目标代码(扩展名可能是.obj .o 或者其它)(2)把编译过后生成的这些目标代码以及C标准库链接起来(link),生成可运行的程序。

最后放一条冷笑话:某个峡谷上方架有一座桥,一次暴风雨过后,桥断了,负责维护的工人一时间还来不及修复,于是在桥头插了一块牌子,上面写道:“Warning! The bridge is broken!” 结果呢?还是有好多人毅然走上断桥,摔到了峡谷里。工人们感到很奇怪,于是到了谷底查看,发现摔到谷底的全都是程序员。

上面的笑话没看懂?没关系,作为程序员,记住下面这一点就行了:绝不放过任何一个warning,否则可能会死得很惨~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246707.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【caffe-Windows】cifar实例编译之model的使用

本文讲解如何对网上下载的一个图片利用训练好的cifar模型进行分类 第一步 上一篇文章训练好以后会得到两个文件 从网上查阅资料解释来看&#xff0c;第一个caffemodel是训练完毕得到的模型参数文件&#xff0c;第二个solverstate是训练中断以后&#xff0c;可以用此文件从中断…

Python 命令汇总

python 库windows安装 兵种&#xff1a;python程序员。 等级&#xff1a;二级。 攻击&#xff1a;较高。 防御&#xff1a;普通。 价格&#xff1a;低。 天赋&#xff1a;胶水&#xff0c;我方有c程序员时&#xff0c;速度可达到c程序员的80%。 天赋&#xff1a;成熟&…

spectral hashing--谱哈希源码解析

论文里面看到了谱哈希用来找子集的用处&#xff0c;不管有没有用&#xff0c;先转再说 原文地址&#xff1a;http://blog.sina.com.cn/s/blog_67914f290101d2xp.html 最近看了有关谱哈希的一些东西&#xff0c;记录一下备忘。理解十分粗浅&#xff0c;敬请各位大牛指导。 一、…

【PTVS+Theano+CPU/GPU】在windows下使用VS安装theano深度学习工具

唉。好不容易折腾完毕caffe&#xff0c;突然发现caffe比较适合搭建卷积神经网络&#xff0c;而对于DBN和LSTM的搭建好像比较麻烦&#xff0c;相关教程没有找到&#xff0c;手头上又有一个theano的代码想调试看看&#xff0c;所以入坑了。 准备工具&#xff1a; VS2013:链接&a…

人工神经网络——【BP】反向传播算法证明

第一步&#xff1a;前向传播 【注】此BP算法的证明仅限sigmoid激活函数情况。本博文讲道理是没错的&#xff0c;毕竟最后还利用代码还核对了一次理论证明结果。 关于更为严谨的BP证明&#xff0c;即严格通过上下标证明BP的博客请戳这里 简单的三层网络结构如下 参数定义&…

参数模型和非参数模型的区别

原文地址&#xff1a;http://blog.csdn.net/gao1440156051/article/details/44003051 参数与非参数模型  用代数方程、微分方程、微分方程组以及传递函数等描述的模型都是参数模型。建立参数模型就在于确定已知模型结构中的各个参数。通过理论分析总是得出参数模型。非参数模…

【matlab函数】——str2func函数的使用

官方点的叫法&#xff0c;在网上被称为函数句柄 用途在于&#xff0c;比如你定义了两个函数&#xff1a;strupper()用于寻找字符串的大写字母数目&#xff1b;strlower()用于寻找字符串的小写字母数目 现在使用str在这里面调换使用如下: funcstr;%统一前缀 myfuncstr2func(fu…

什么是NP完全问题?

本文转自&#xff1a;http://blog.csdn.net/xueyong4712816/article/details/6509592 NP完全问题&#xff0c;是世界七大数学难题之一&#xff0c;排在百万美元大奖的首位&#xff0c;够诱惑力吧&#xff01;咋不求得奖只需要了解了解它是什么就可以了。 什么是NP完全问题,NPN…

【caffe-Windows】微软官方caffe之 matlab接口配置

前言 按照微软的官方地址配置可能会出现一个问题caffe_.mexw64找不到引用模块问题&#xff0c;或者在matlab里面压根找不到caffe_这个函数&#xff0c;下面会提到这两个问题。还是按照步骤来吧 【PS1】有GPU同样按照下述步骤&#xff0c;进行即可 【PS2】文章在matlab2013a、…

【混淆矩阵】matlab画混淆矩阵

主要借鉴此博客代码&#xff1a;http://blog.csdn.net/sherry_gp/article/details/50560003 但是这个博主的代码达不到我想要的效果&#xff0c;所以修改了一下 我想要实现的效果是&#xff1a;给定一列的预测标签&#xff0c;以及这一列标签的哪一部分理应属于哪一部分标签。…

【caffe-Windows】mnist实例编译之model的生成

其实这个和cifar的实例基本相同&#xff0c;只不过数据转换的方法不一样 【说明&#xff0c;此博客按照我自己的路径设置的相关操作&#xff0c;读者如果自行选择其他路径&#xff0c;记得在bat和prototxt等文件修改路径】 第一步 下载数据集THE MNIST DATABASE of handwrit…

吉布斯采样——原理及matlab实现

原文来自&#xff1a;https://victorfang.wordpress.com/2014/04/29/mcmc-the-gibbs-sampler-simple-example-w-matlab-code/ 【注】评论区有同学指出译文理论编码有误&#xff0c;请参考更官方的文献&#xff0c;个人当时仅验证过红色字体部分理论与维基百科中二位随机变量吉…

【matlab知识补充】conv2、filter2、imfilter函数原理

原文地址&#xff1a;http://www.ilovematlab.cn/thread-293710-1-1.html -------------------------------------conv2函数---------------------------------------- 1、用法 Cconv2(A,B,shape); %卷积滤波 复制代码A:输入图像&#xff0c;B:卷积核假设输入图像A大…

【matlab函数】diff函数

diff函数是用来求导数的 更新日志&#xff1a;2021-3-16 经评论区SHolmesCSU 指正&#xff0c;此函数为求解差分&#xff0c;而非导数。 在matlab官方文档中&#xff0c;利用差分近似导数需要除以步长&#xff0c;即 diff(X)/step_size 目前用到的调用格式为diff(A&#x…

显示mnist手写数字

前言 可视化什么的&#xff0c;总是好的 方法一 其实也就是用到了Ruslan Salakhutdinov and Geoff Hinton提供的工具包 % Version 1.000 % % Code provided by Ruslan Salakhutdinov and Geoff Hinton % % Permission is granted for anyone to copy, use, modify, or distr…

【matlab函数】convn多维卷积

简单的卷积就不说了&#xff0c;向量卷积用此函数与用conv效果相同&#xff0c;矩阵卷积用此函数与conv2的二维卷积效果相同。 此函数的方便之处在于支持三维卷积&#xff1a;其实相对于conv2来说就是省了一个for循环。对于三维卷积&#xff0c;比如A矩阵大小为[2,3,3]&#x…

【caffe-Windows】mnist实例编译之model的使用-classification

仿照cifar10的模型使用&#xff0c;本文对mnist的训练方式做了部分修改 【注】本文caffe安装路径为E:\CaffeDev-GPU\caffe-master。请自行参考并修改相关路径(debug以及release参考你编译caffe时候采用的模式) 第一步 按照前面的model生成方法的前两步骤制作数据集&#xff…

误差error,偏置bias,方差variance的见解

更新日志&#xff1a;2020-3-10 谢谢ProQianXiao的指正。偏差-方差的确是在测试集中进行的。 之前的误解是&#xff0c;偏差和方差的计算是同一个模型对不同样本的预测结果的偏差和方差&#xff1b;而实际上是不同模型对同一个样本的预测结果的偏差和方差。 这时候就要祭出网…

【caffe-Windows】以mnist为例lmdb格式数据

前言 前面介绍的案例都是leveldb的格式&#xff0c;但是比较流行和实用的格式是lmdb&#xff0c;原因从此网站摘取 它们都是键/值对&#xff08;Key/Value Pair&#xff09;嵌入式数据库管理系统编程库。虽然lmdb的内存消耗是leveldb的1.1倍&#xff0c;但是lmdb的速度比level…

【caffe-Windows】mnist实例编译之model的使用-matlab

前言 针对上一个caffe文章留下的matlab手写数字识别的问题&#xff0c;感谢caffe中文社区的 ghgzh 的提示&#xff0c;原文请看&#xff1a;caffe中文社区 第一步 手写图片的制作方法我就不说了&#xff0c;直接把我自己画的几个数字放到云盘先&#xff1a; 三通道图像以及…