【发布时间】:2015-03-09 21:43:44
【问题描述】:
这两种方法的优缺点是什么?
源代码与标头实现
源文件中的函数定义
头文件 sourcefunction.h 仅包含声明。
#ifndef SOURCEFUNCTION_H
#define SOURCEFUNCTION_H
void sourcefunction(void);
#endif // SOURCEFUNCTION_H
源文件 sourcefunction.c 包含定义
#include "sourcefunction.h"
#include <stdio.h>
void sourcefunction(void) { printf(" My body is in a source file\n"); }
头文件内的函数定义
头文件headerfunction.h包含定义,同时也是声明。
#ifndef HEADERFUNCTION_H
#define HEADERFUNCTION_H
#include <stdio.h>
void headerfunction(void) { printf(" My body is in a header file\n"); }
#endif // HEADERFUNCTION_H
不需要源文件。
消费者
文件 main.c
#include "sourcefunction.h"
#include "headerfunction.h"
int main(void) {
sourcefunction();
headerfunction();
return 0;
}
为什么要编译很多源文件?
我们必须编译所有源文件并在链接期间记住它们。
gcc -c sourcefunction.c
gcc -c main.c
gcc main.o sourcefunction.o
Make 可以处理文件管理,但为什么还要麻烦呢?
接口和实现的分离总是一个问题吗?
这是大型项目和团队合作的明显原因。设计者指定接口。程序员实现功能。
较小的项目和非正式的方法呢?
从头文件中删除定义是否总能防止链接器错误?
假设我的程序正在使用另一个模块,它定义了具有相同名称的函数sourcefunction()。
#include "sourcefunction.h"
#include "sourcefunction1.h"
#include "headerfunction.h"
int main(void) {
headerfunction();
sourcefunction();
return 0;
}
不同的功能接口
文件sourcefunction1.h
#ifndef SOURCEFUNCTION1_H
#define SOURCEFUNCTION1_H
int sourcefunction(void);
#endif // SOURCEFUNCTION1_H
文件sourcefunction1.c
#include "sourcefunction1.h"
#include <stdio.h>
int sourcefunction(void) { int a = 5; return a; }
通过编译 main.c,我得到一个 nice 编译器错误
sourcefunction1.h:4:5: error: conflicting types for 'sourcefunction'
显示错误的位置。
相同的功能界面
文件sourcefunction1.h
#ifndef SOURCEFUNCTION1_H
#define SOURCEFUNCTION1_H
void sourcefunction(void);
#endif // SOURCEFUNCTION1_H
文件sourcefunction1.c
#include "sourcefunction1.h"
#include <stdio.h>
void sourcefunction(void) { int a = 5; printf("%d",a); }
编译器不介意多重声明。我收到 ugly 链接器错误。
头文件实现可以作为库吗?
jschultz410 说 如果您正在编写一个库并且您的所有函数定义都在标头中,那么如果在多个翻译单元中需要它们,其他将他们的开发分割成多个翻译单元的人将获得您的函数的多个定义
让我们拥有 文件 consumer1.c
#include "headerfunction.h"
void consume1(void) { headerfunction(); }
文件 consumer2.c
#include "headerfunction.h"
void consume2(void) { headerfunction(); headerfunction();}
文件 twoConsumers.c
extern void consume1(void);
extern void consume2(void);
int main(void) {
consume1();
consume2();
return 0;
}
让我们编译源代码。
gcc -c consumer1.c
gcc -c consumer2.c
gcc -c twoConsumers.c
到目前为止,一切都很好。现在,链接。
gcc consumer1.o consumer2.o twoConsumers.o
链接器错误:当然是multiple definition of 'headerfunction'。
但是我可以让我的库函数static。
文件 headerfunction.h,然后。
#ifndef HEADERFUNCTION_H
#define HEADERFUNCTION_H
#include <stdio.h>
static void headerfunction(void) { printf(" My body is in a header file\n"); }
#endif // HEADERFUNCTION_H
它对其他翻译单元隐藏了定义。
【问题讨论】:
-
首先,链接器错误。然后,谷歌“模块化”。
-
@TheParamagneticCroissant 1. 当您在不同的头文件和源文件中有 2 个相同函数的声明时,也会发生链接器错误。 2. 模块化的概念对于大型项目和团队合作很重要。
-
不,当两个定义出现在两个不同的文件中时,会发生链接器错误。就像你在两个地方包含相同的定义一样
标签: c definition