预处理器如何处理“#include”指令?

时间:2015-01-08 18:55:27

标签: c include c-preprocessor

预处理器在源代码中遇到#include指令时到底做了什么?

我认为它用所包含文件的内容替换#include,但我想要比我的假设更强大的东西。

是否有任何理由不直接在源代码中输入所包含文件的内容而不是#include除了它在眼睛上更好?

4 个答案:

答案 0 :(得分:3)

预处理器会将#include语句替换为文件内容。

使用#include而不是简单地粘贴文件内容的优点是,如果修改了头文件,您只需重新编译源文件即可。如果您粘贴了文件的内容,那么您将不得不用新版本的头文件替换它。

另外,如果您#include在多个地方使用文件(与常量和类型定义文件一样),您不必修改所有重复的声明,多次包含的文件会使一个地方发生变化而不是几个。

答案 1 :(得分:1)

从我的C11标准第6.10.2条第3款草案的副本

  

表单

的预处理指令

# include "q-char-sequence" new-line

  

导致由该标识的源文件的全部内容替换该指令   “分隔符”之间的指定序列。

答案 2 :(得分:0)

这是#include个文件的重点。

#include <stdio.h>这是一个分布式库头。如果您有一套项目源文件,则可能需要将stdio.h的内容粘贴到每个文件中。 #include文件的重点在于您不必。

现在取#include "mycommon.h"这是您当地常用的项目功能。如果您每次修改本地#include时都不使用mycommon.h,则必须将其重新粘贴到所有源文件中。

答案 3 :(得分:0)

  

有没有理由不直接在源代码中输入所包含文件的内容而不是#include它而不是它的眼睛更好?

这不是一件轻松的事情。

头文件的主要目的是为单独的翻译单元中的定义的函数原型和数据对象提供常见的声明。大多数非平凡的应用程序在单独编译和链接的单独翻译单元中包含多个模块。函数或数据对象必须仅在一个翻译单元中定义,但可以多次引用 - 所有这些都必须具有正确匹配的声明才能使链接成功。确保声明在每个翻译单元中都是正确的最简单且最不容易出错的方法是使用头文件;在多个翻译单元中输入相同的信息将非常难以维护。

另一方面,如果您的翻译单元包含仅在该翻译单元内访问的功能和数据(或您的应用程序是单个翻译单元),那么相应的声明可能确实出现在同一个源文件中,并且还应该声明static明确禁止外部链接。

例如考虑标准库头文件,例如stdio.h。例如,您可以在代码中直接输入printf()的原型 - 它可能看起来像:

extern int printf ( const char * format, ... );

但你必须每次都完全正确,并为你想要使用的每个功能做到这一点。你真的会这样做吗??