c-标准库多次包含在多个文件中



在K&R书(p59)(编辑:第二版,涵盖ANSIC),建议将较大的项目拆分为多个文件更容易。在每个文件中,像往常一样,顶部包括几个库:例如,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&R确实指出,将一个程序拆分为多个文件最终会使维护所有.h文件变得更加困难。

我想我真正想问的是编译器如何解决一个库在一个项目中多次被#包含的问题。

我已经阅读了关于使用include-guard的内容,但这似乎不需要用于此实现,因为它们处理的是确保相同的代码位不会被包含两次,如:

文件"module.h"

#ifndef MODULE_H
#define MODULE_H
struct foo {
    int member;
};
#endif /* MODULE_H */

文件"mod2.h"

#include "module.h"

文件"prog.c"

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

参考

我想我真正想问的是编译器如何解决一个库在一个项目中多次被#包含的问题。

#include <stdio.h>不包含库,只包含它的声明,所以编译器知道存在什么函数。链接器负责包含一个库并将所有内容组合在一起。

因为他们使用了一种名为include guard的东西,假设您自己的include文件不止一次被包含在其中,那么您就可以执行这个

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;
}

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

相关内容

  • 没有找到相关文章

最新更新