是否应将ANSI C函数定义放在头文件(.h)或源文件(.c)中? [英] Should ANSI C function definition be placed inside header (.h) or source (.c) file?

查看:72
本文介绍了是否应将ANSI C函数定义放在头文件(.h)或源文件(.c)中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两种方法的优缺点是什么?

What are advantages and disadvantages of both approaches?

头文件sourcefunction.h仅包含声明.

Header file sourcefunction.h contains declaration only.

#ifndef SOURCEFUNCTION_H
#define SOURCEFUNCTION_H

void sourcefunction(void);

#endif // SOURCEFUNCTION_H

源文件sourcefunction.c包含定义

Source file sourcefunction.c contains definition

#include "sourcefunction.h"
#include <stdio.h>
void sourcefunction(void) { printf(" My body is in a source file\n"); }

头文件中的函数定义

头文件headerfunction.h包含同时是声明的定义.

Function definition inside header file

Header file headerfunction.h contains definition which is the declaration at the same time.

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

为什么要编译许多源文件?

我们必须编译所有源文件,并在链接期间记住它们.

Why compile many source files?

We have to compile all source files and remember about them during linking.

gcc -c sourcefunction.c
gcc -c main.c
gcc main.o sourcefunction.o

Make 可以处理文件管理,但是为什么还要打扰呢?

Make can handle file managing but why even bother?

这显然是大型项目和团队合作的原因.设计人员指定接口.程序员实现功能.

It is obvious reason for big projects and teamwork. The designer specifies the interface. The programmers implement functionality.

较小的项目和非正规方法又如何呢?

What about smaller projects and non-formal approach?

假设我的程序正在使用另一个模块,该模块定义了具有相同名称 sourcefunction()的函数.

Let's assume my program is using another module that defines the function with the same name 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,我得到一个好的编译器错误 sourcefunction1.h:4:5:错误:"sourcefunction"的类型冲突向我显示错误的位置.

By compiling main.c, I get a nice compiler error sourcefunction1.h:4:5: error: conflicting types for 'sourcefunction' showing me the location of error.

文件 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); }

编译器不介意多个声明.我收到难看的链接器错误.

Compiler does not mind multiple declarations. I get ugly linker error.

jschultz410说如果您正在编写一个库,并且所有函数定义都在标头中,那么将其开发划分为多个翻译单元的其他人将在您需要多个翻译单元的情况下获得您函数的多个定义

jschultz410 says If you are writing a library and all your function definitions are in headers, then other people who do segment their development into multiple translation units will get multiple definitions of your functions if they are needed in multiple translation units

让我们拥有文件consumer1.c

Lets' have File consumer1.c

#include "headerfunction.h"
void consume1(void) { headerfunction(); }

文件consumer2.c

File consumer2.c

#include "headerfunction.h"
void consume2(void) { headerfunction();  headerfunction();}

文件twoConsumers.c

File 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

到目前为止,太好了.现在,链接.

So far, so good. Now, linking.

gcc consumer1.o consumer2.o twoConsumers.o

链接器错误:"headerfunction"的多个定义,当然.

但是我可以使我的库函数为 static .然后是文件标头功能.h.

But I can make my library function static. File headerfunction.h, afterwards.

#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

它将其他翻译单元的定义隐藏起来.

It hides the definition from other translation units.

推荐答案

我不应该回答,但我会回答.

I shouldn't answer this, but I will.

  1. 这可以创建重复的定义,除非您的项目中实际上只有一个.c文件(不明智).如果头文件保护多次也使用不同的.c文件,那么即使头文件保护也不会阻止文件头被多次包含.将.obj文件链接在一起时,将发生冲突.
  2. 如果仅函数声明而不是定义位于标头中,则仅对接口的更改(函数名称,参数或返回类型)需要重新编译依赖项.但是,如果整个定义都在标头中,则对该函数所做的任何更改都需要重新编译依赖于该函数的所有.c和.h文件,这在较大的项目中会创建很多不必要的重新编译.
  3. 这不是惯例.库将不使用此约定,因此您将不得不处理它们的头文件结构.其他开发人员将不会使用此约定,因此您可以在那里造成混乱或烦恼.

这篇关于是否应将ANSI C函数定义放在头文件(.h)或源文件(.c)中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆