另一篇:.c文件和.h文件的关系

引言:

我们经常在c工程中发现,源文件中要包含自己的头文件。一直以来,都不知道为什么这样做。现在,我知道了。

以前的认知:

我认为,.c文件没有必要包含自己的.h文件。.h文件包含.c文件中定义的函数和全局变量的声明,.h文件就是.c文件提供的对外接口文件。既然.h文件就是.c文件提供的对外接口文件,那么.c文件就没必要包含自己的.h文件了(.h文件是对外提供用的,对内又何必再包含进来呢)。

鉴于这样的理解,我对于工程中.c源文件包含自己的.h头文件很是不理解,不知道为什么要这样做。

现在对此的理解:

但是现在,我知道为什么要源文件包含自己的头文件了。

如下,一段书中的原话:

“如果希望让编译器检查声明的一致性,一定要把全局声明放到头文件中。特别是,永远不要把外部函数的原型(也就是函数声明)放到.c文件中:通常它与定义的一致性不能得到检查,而矛盾的原型(也就是函数声明)比不用还糟糕。”

注意:外部函数的原型,就是外部函数的声明。

对这段话的理解:

为什么:“永远不要把外部函数的原型放到.c 文件中”

这个外部函数A指的是B.c文件之外定义的函数,B.c文件中需要使用外部函数A,就需要先对外部函数A声明(对外部函数的声明就是外部函数原型)。对这个外部函数A的声明,不能放在B.c文件里面来实现。

以实例说明:

①假若工程中有2个源文件a.c和b.c;a.c的头文件为a.h,b.c的头文件为b.h。

②a.c中定义了一个函数sum。

③b.c要引用sum这个函数。做法是:在b.c中声明sum这个函数。然后b.c就可以使用sum函数了。

这样的做法就是把外部函数sum的声明放到了b.c中来。然而,这样的做法很不妥。

不妥的原因:

sum是在a.c中定义的,而声明确是在b.c中,sum函数的定义和声明不是在同一个文件中的。定义和声明不在同一个文件中,编译的时候,编译器就不能对定义和声明的一致性进行检查。这样,如果sum的定义和声明不一致,编译器就无法检查出来(定义和声明不在同一个文件中),那么编译的时候不会报错,但是程序运行的时候就可能会出错。而这样的错误,查找起来又不是很容易。

鉴于此,才这样说:“永远不要把外部函数的原型放到.c文件中”。

那如何才能让编译器检查定义和声明的一致性呢?

前面说,如果把外部函数的原型放到.c文件中,编译器就无法检查声明和定义的一致性(声明和定义不在同一个文件中)。那么,要让编译器检查定义和声明的一致性呢,自然是把定义和声明放在同一个文件中,而如何实现把定义和声明放在同一个文件里呢?

答案:源文件定义的函数,在源文件对应的头文件中声明,然后源文件包含自己的头文件。这样定义和声明就放在同一个文件里了。

援引上述例子:a.c中定义了函数sum,而函数本质上是外部的,函数sum是可以被其它源文件调用的。那么,我们把sum函数的声明放在a.h中。然后a.c源文件还要包含自己的头文件,也就是a.h文件。而b.c文件要引用sum函数,就直接包含a.h文件就可以。

sum函数的定义在a.c中,声明是在a.h中,但是由于a.c包含了a.h,所以sum的定义和声明就是在同一个文件a.c中了。这样,编译器编译的时候,就能对sum函数定义和声明的一致性做检查,如果不一致,就会报错。

至于其他源文件引用这个外部函数sum,不再采用直接声明的方式,而是通过包含a.h头文件的方式。

这样,编译器检查了sum函数定义和声明的一致性没有报错,也就表明a.c中sum函数的定义和a.h中sum函数的声明是一致的。那么其他源文件都是通过直接包含a.h,来使用函数sum,就也保证了sum函数声明和定义的一致性了。

结论

c源文件要包含自己的头文件,目的就是让编译器检查定义和声明的一致性。

转自:https://blog.csdn.net/khwkhwkhw/article/details/49798985

c源文件中为什么要包含自己对应的头文件的更多相关文章

  1. 一个".java"源文件中是否可以包含多个类(不是内部类)?有什么限制?

    可以,但一个源文件中最多只能有一个公开类(public class)而且文件名必须和公开类的类名完全保持一致.

  2. 一个包含所有c++的头文件的头文件

    #include <bits/stdc++.h> 做CF看见别人用这个函数,然后就能直接用vector,set,string那些函数了,摸不着头脑,感觉特神奇就百度了一下,才发现这个是C+ ...

  3. 【转】Eclipse中一键调用javah生成jni的头文件

    这里定义了一个本地方法jni_test,该方法返回一个String.其中System.loadLibrary是用来加载本地库的(dll或者so). 有了这个类以后,就可以调用javac命令编译,得到E ...

  4. virtualbox linux客户机中安装增强功能包缺少kernel头文件问题解决

    linux客户机中安装增强功能包总会提示缺少kernel头文件 根据发行版的不同,用命令行软件包管理命令安装dkms build-essential linux-headers-$(uname -r) ...

  5. 一个”.java”源文件中是否可以包含多个类(不是内部类)?有什么限制

    这个是可以的,一个“.java”源文件里面可以包含多个类,但是只允许有一个public类,并且类名必须和文件名一致. 每个编译单元只能有一个public 类.这么做的意思是,每个编译单元只能有一个公开 ...

  6. kali 软件源 包含virtualbox所需头文件

    # deb cdrom:[Debian GNU/Linux 7.0 _Kali_ - Official Snapshot i386 LIVE/INSTALL Binary 20130905-08:50 ...

  7. C++中头文件、源文件之间的区别与联系

    .h头文件和.cpp文件的区别 疑惑1:.h文件能够编写main函数吗? 实验: 编写test.h文件,里面包含main函数 若直接编译g++ test.h -o test,通过file命令 file ...

  8. CPP-基础:内部函数应该在当前源文件中说明和定义

    static函数与普通函数作用域不同,仅在本文件.只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义.对于可在当前源文件以外使用的函数,应该在一个头文件 ...

  9. C++中头文件与源文件的作用详解

    一.C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件―― .cpp 文件和 .h 文件.其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码:而 .h 文件则被称作 ...

随机推荐

  1. Java多线程编程核心技术---多线程技能

    1.继承Thread /** * Copyright (C), 2018-2018, * FileName: MyThread * Author: 大象 * Date: 2018-06-08 22:3 ...

  2. node-java的使用及源码分析

    上篇文章简单提了下node调用java的方法但也只属于基本提了下怎么输出helloworld的层度,这次将提供一些案例和源码分析让我们更好地了解如何使用node-java库. 前置知识: 1.桥接模式 ...

  3. Python的内置数据结构

    Python内置数据结构一共有6类: 数字 字符串 列表 元组 字典 文件 一.数字 数字类型就没什么好说的了,大家自行理解 二.字符串 1.字符串的特性(重要): 序列化特性:字符串具有一个很重要的 ...

  4. linux基本篇--入门成神之路

    一.linux基础操作 1.初识bash shell概念  shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口,他接受用户输入的命令并把它送入内核去执行,实际上shell是一个命令解释 ...

  5. php 23种设计模型 - 享元模式

    享元模式 享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. ...

  6. 通信原理:基于MATLAB的AM调幅分析

    目的: 通过matlab仿真AM调制,通过图像分析来更好的了解AM调制的过程 1.为什么基带信号要加上一个直流分量. 2.所加直流分量为什么要大于基带信号的最大值. 3.时域中调制信号与载波和基带信号 ...

  7. AE功能扩展一

    1.添加栅格影像 基本思路:声明栅格工作空间→创建栅格数据集对象→创建金字塔→声明图层对象→刷新地图控件 private void AddBaseMap(string filepath) { IWor ...

  8. Python的安装教程与环境配置

    安装环境:Windows7或者Windows10 Python版本:最新即可,这里选用 python 3.7.2: 一.下载:在python的官网下载python版本,需要下载对应版本(在计算机-属性 ...

  9. 使用pyautogui自动在某网站投票的脚本

    网页自动投票: # !/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan import re import pypercli ...

  10. Flutter入门教程(二)开发环境搭建

    学习Flutter,首先需要搭建好Flutter的开发环境,下面我将一步步带领大家搭建开发环境并且成功运行flutter项目. Flutter环境配置主要有这几点: 系统配置要求 Java环境 Flu ...