如果我有这样的程序
一个头文件,它声明我的主库函数primary()
并定义了一个简短的辅助函数helper()
。
/* primary_header.h */
#ifndef _PRIMARY_HEADER_H
#define _PRIMARY_HEADER_H
#include <stdio.h>
/* Forward declare the primary workhorse function */
void primary();
/* Also define a helper function */
void helper()
{
printf("I'm a helper function and I helped!\n");
}
#endif /* _PRIMARY_HEADER_H */
我的主要功能的实现文件,用于定义它。
/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>
/* Define the primary workhorse function */
void primary()
{
/* do the main work */
printf("I'm the primary function, I'm doin' work.\n");
/* also get some help from the helper function */
helper();
}
main()
文件,通过调用primary()
/* main.c */
#include "primary_header.h"
int main()
{
/* just call the primary function */
primary();
}
使用
gcc main.c primary_impl.c
没有链接,因为primary_header.h
文件被包含两次,因此函数helper()
存在非法的双重定义。构造此项目的源代码的正确方法是什么,以便不会发生双重定义?
答案 0 :(得分:4)
你应该只在头文件中编写你的函数原型,你的函数体应该用.c文件写。
这样做:
primary_header.c
/* primary_header.h */
#ifndef PRIMARY_HEADER_H
#define PRIMARY_HEADER_H
#include <stdio.h>
/* Forward declare the primary workhorse function */
void primary(void);
/* Also define a helper function */
void helper(void);
#endif /* PRIMARY_HEADER_H */
primary_impl.c
/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>
/* Define the primary workhorse function */
void primary()
{
/* do the main work */
printf("I'm the primary function, I'm doin' work.\n");
/* also get some help from the helper function */
helper();
}
void helper()
{
printf("I'm a helper function and I helped!\n");
}
修改:将_PRIMARY_HEADER_H
更改为PRIMARY_HEADER_H
。正如@Jonathan Leffler和@Pablo所说,下划线名称是保留标识符
答案 1 :(得分:3)
除非标记为始终内联,否则几乎不会在头文件中编写函数。相反,您将函数写入.c
文件并将函数的声明(非定义)复制到头文件中,以便在其他地方使用。
答案 2 :(得分:0)
你可以在头文件中定义一个函数,如果它是 weak linkage 像:
// test.h
__attribute__((weak)) int test() {
static int s = 0;
return s++;
}
// a.c
#include "test.h"
#include <stdio.h>
void a(){
print("%d", test());
}
// b.c
#include "test.h"
#include <stdio.h>
void b(){
print("%d", test());
}
// main.c
#include "test.h"
#include <stdio.h>
void a();
void b();
void main(){
a();
b();
print("%d", test());
}
cc a.c b.c main.c
不会引发多个定义错误,输出应该是 012
预期的,这意味着 a.c
、b.c
和 main.c
共享相同的 { {1}} 函数。
您可以在 C++ 中使用 test
获得相同的结果。
此外,还可以在变量定义上使用弱链接,允许您在没有源文件的头文件中定义和初始化全局变量(类似于c++中的inline
)。
注意:
<块引用>C 或 C++ 语言标准未提及弱符号。
所以在c中使用时要小心。但是在 c++ 中,inline static
和 inline
是可移植的形式 c++11 和 c++17。