.c和.h文件扩展名对C来说意味着什么?

这是所有的标题; 我觉得非常简单,但是很难在任何地方search语法的东西。

这些是我从CS50.net复制的两个库文件,我想知道他们为什么有两个不同的扩展名。

.c:c文件(一般来说,真正的动作是)

.h:头文件(包含在预处理器的#include指令中)。 包含通常被认为与你的代码的其他部分共享的东西,如函数原型,#define'd东西,全局variables的外部声明(哦,恐怖)等。

从技术上讲,你可以把所有东西放在一个文件中。 一个完整的C程序。 百万行。 但是我们人类倾向于组织事物。 所以你创build了不同的C文件,每个文件都包含特定的function。 这一切都很好,干净。 然后突然间你意识到你已经进入一个给定的C文件的声明也应该存在于另一个C文件中。 所以你会复制它们。 因此,最好是提取声明,并把它放在一个共同的文件,这是.h

例如,在cs50.h中,你可以find你的函数所谓的“前向声明”。 前向声明是告诉编译器应该如何调用一个函数(比如input参数是什么)以及它返回什么的一个快速方法,所以它可以执行适当的检查(例如,如果调用一个参数数量错误的函数,会抱怨)。

另一个例子。 假设你写了一个包含执行正则expression式匹配的函数的.c文件。 你希望你的函数接受正则expression式,要匹配的string,以及一个参数,告诉比较是否不区分大小写。

在.C你将因此放

 bool matches(string regexp, string s, int flags) { the code } 

现在,假设你想传递下面的标志:

0:如果search区分大小写

1:如果search是不区分大小写的

而且你想保持开放的新标志,所以你没有把布尔值。 玩数字是很难的,所以你为这些标志定义有用的名字

 #define MATCH_CASE_SENSITIVE 0 #define MATCH_CASE_INSENSITIVE 1 

这个信息进入.h,因为如果任何程序想要使用这些标签,除非包含信息,否则无法知道它们。 当然你可以把它们放在.c中,但是你必须包含.c代码(整个!),这是浪费时间和麻烦的根源。

当然,没有什么说头文件的扩展名必须是.h并且C源文件的扩展名必须是.c 。 这些是有用的惯例。

 E:\Temp> type my.interface #ifndef MY_INTERFACE_INCLUDED #define MYBUFFERSIZE 8 #define MY_INTERFACE_INCLUDED #endif E:\Temp> type my.source #include <stdio.h> #include "my.interface" int main(void) { char x[MYBUFFERSIZE] = {0}; x[0] = 'a'; puts(x); return 0; } E:\Temp> gcc -xc my.source -o my.exe E:\Temp> my a 

他们不是真正的库文件。 他们只是源文件。 就像Stefano说的那样, .c文件是C源文件,它实际上使用/定义了.h文件(头文件)中仅列出的实际源文件。 头文件通常概括了将在实际源文件中使用的所有函数原型和结构。 把它想成一个参考/附录。 这在查看头文件时很明显,因为你会看到:)所以当你想使用这些源文件中写的东西的时候, #include头文件,它包含了编译器需要知道的信息。

.c是源文件,.h是头文件 。

.c文件是将被编译的源文件。 .h文件用于将程序的API暴露给该程序的其他部分或其他程序是否正在创build库。

例如,PizzaDelivery程序可以具有主程序的1.c文件和具有实用程序function的1 .c文件。 现在,为了能够使用实用程序function的程序的主要部分,您需要通过函数原型公开的API到一个.h文件,这个.h文件被包含在主.c文件中。

 .c : 'C' source code .h : Header file 

通常, .c文件包含实现, .h文件包含实现的“接口”。

假设你必须从命令提示符或使用任何IDE打开你创build的c程序,那么如果你没有通过.c保存你的文件,那么IDE将很难search和区分你的文件和其他将延迟search的文件。 所以.c告诉文件的types和它的来源,如.java等