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