标准库包含多个文件多次?

时间:2015-02-15 14:39:38

标签: c compiler-construction c-preprocessor stdio kernighan-and-ritchie

在K& R书籍(第59页)(编辑:第二版,涵盖ANSI C )中,建议将较大的项目拆分为多个文件更容易。在每个文件中,像往常一样在顶部包含几个库:例如getop.c需要stdio.h,stack.c也是如此,main.c也是如此。

这些片段是这样的:

//main.c
#include <stdio.h>
#include <stdlib.h>
#include "calc.h"
int main(void)
{
    //etc
}


//getop.c
#include <stdio.h>
#include <ctype.h>
#include "calc.h"
getop()
{
    /*code*/
}

//stack.c
#include <stdio.h>
#include "calc.h"
void push(double val)
{
    //code
}

我无法弄清楚如何在项目中多次包含标准库。当然,要使自定义.c文件能够访问内置函数,我们需要包含#include <header.h>,以便他们知道printf()getchar()的存在等等但如果stdio.h包括四次而不是一次(如果所有内容都放在一个文件中),这种方法是否会增加最终程序的大小?

K&amp; R确实指出,将程序拆分为多个文件最终会使维护所有.h文件变得更加困难。

我想我真正想问的是编译器如何在一个项目中多次弄清楚一个库被#included的问题。

我已经阅读了使用 include guards ,但似乎这个实现不需要,因为它们可以确保相同的代码位不包含两次,如:

文件&#34; module.h&#34;

#ifndef MODULE_H
#define MODULE_H

struct foo {
    int member;
};

#endif /* MODULE_H */

文件&#34; mod2.h&#34;

#include "module.h"

文件&#34; prog.c&#34;

#include "module.h"
#include "mod2.h"

refs

2 个答案:

答案 0 :(得分:3)

  

我想我真正想问的是编译器如何在一个项目中多次弄清楚一个库被#included的问题。

您没有#include <stdio.h>包含库,只需包含它的声明,因此编译器知道存在哪些函数。链接器负责包含一个库并将所有内容放在一起。

答案 1 :(得分:1)

因为他们使用了名为 include guards 的东西,假设您自己的包含文件不止一次被包含在内,那么您可以这样做

<强> MyHeader.h

#ifndef MY_HEADER_H
#define MY_HEADER_H
/* file content goes here */
#endif /* MY_HEADER_H */

然后你有另一个标题

**AnotherHeader.h**

#ifndef MY_ANOTHER_HEADER_H
#define MY_ANOTHER_HEADER_H
#include "MyHeader.h"
/* file content goes here */
#endif /* MY_ANOTHER_HEADER_H */

并在你的程序中

<强>的main.c

/* 
 * MY_HEADER_H is undefined so it will be defined and MyHeader.h contents 
 * will be included.
 */
#include "MyHeader.h" 
/*
 * MY_HEADER_H is defined now, so MyHeader.h contents will not be included
 */
#include "AnotherHeader.h"

int main()
{
    return 0;
}

由于包含的文件每个编译单元只包含一次,因此生成的二进制文件大小不会增加,除了包含头文件只会增加编译的文件大小,例如在这些头文件中声明了字符串文字,否则它们只提供有关如何调用给定函数的编译器信息,即如何将参数传递给它以及如何存储它的返回值。