标题是C程序员普遍接受的约定。
这是一个通常包含在C源文件中的.h文件,它提供了几个优点。
1.-提供数据类型,全局变量,常量和函数的声明。
因此,您不必一次又一次地重写它们。如果他们需要改变,你只需要在一个文件中改变它。
在这个例子中,由两个compliation单位(两个.c文件)组成的程序编译并运行得很好。
// File funcs.c
#include
struct Position {
int x;
int y;
};
void print(struct Position p) {
printf("%d,%d\n", p.x, p.y);
}
// File main.c
struct Position {
int x;
int y;
};
int main(void) {
struct Position p;
p.x = 1; p.y = 2;
print(p);
}
但更mantainable有对struct Position声明在头文件,只是#include它无处不在,它是必要的,就像这样:
// File funcs.h
#ifndef FUNCS_H
#define FUNCS_H
struct Position {
int x;
int y;
};
#endif // FUNCS_H
//File funcs.c
#include
#include "funcs.h"
void print(struct Position p) {
printf("%d,%d\n", p.x, p.y);
}
//File main.c
#include "funcs.h"
int main(void) {
struct Position p;
p.x = 1; p.y = 2;
print(p);
2:提供某种类型的安全。
C功能implicit declaration of functions。一个在C99中修复的“特征”(或者说是一种可论证的语言设计错误)。
考虑一下这个程序的两个.c文件组成:
//File funcs.c
#include
int f(long n)
{
n = n+1;
printf("%ld\n", n);
}
// File main.c
int main(void)
{
f("a");
return 0;
}
与海湾合作委员会这个程序编译没有警告或错误。但不表现为,我们可以合理的期待和渴望:
[email protected] ~/t/tt $ gcc -o test *.c
[email protected] ~/t/tt $ ./test
4195930
使用头文件是这样的:
//File funcs.h
#ifndef FUNCS_H
#define FUNCS_H
int f(long n);
#endif // FUNCS_H
//File funcs.c
#include
int f(long n) {
n = n+1;
printf("%ld\n", n);
}
// File main.c
#include"funcs.h"
int main(void) {
f("a");
return 0;
}
程序仍然编译和工程错误的,但至少我们得到一个警告:
[email protected] ~/t $ gcc -o test *.c
main.c: In function 'main':
main.c:5:5: warning: passing argument 1 of 'f' makes integer from pointer without a cast
f("a");
^
In file included from main.c:2:0:
funcs.h:3:5: note: expected 'long int' but argument is of type 'char *'
int f(long n);
^
[email protected] ~/t $ ./test
4195930
3.-提供一个公共接口,同时让实现细节保持隐藏状态。
当你设计你的程序时,最好使它成为模块化。这是为了确保它的不同部分(模块)尽可能地独立。所以,当你需要改变一个模块时,你不必担心影响其他模块的这种改变
头部有助于做到这一点,因为你在模块头部放置了数据结构,函数原型和常量这种模块的用户将会需要它。
实现细节进入.c文件。
这就是图书馆的工作方式。 API接口被指定并分布在头文件中。但API代码在.c文件中,不需要分发。作为库的用户,您只需要头文件和编译后的库,而不是源代码。
C语言头文件主要用于声明数据类型、全局变量、常量和函数,提供类型安全,实现模块间的接口隔离。当函数如`void print(struct Position p)`涉及到结构体时,将结构体定义放在头文件中能确保所有引用该结构体的文件保持一致。未使用头文件可能导致隐式函数声明,产生不可预期的行为。头文件通过预处理器避免重复声明,例如`#ifndef FUNCS_H`等防止重复包含。

2897

被折叠的 条评论
为什么被折叠?



