在本教程中,我们将学习 C 中的头文件。主要关注点是——我们为什么要在每个程序中使用头文件,然后讨论头文件的作用以及 C 中不同类型的头文件。
您一定注意到所有 C 程序都以文件 stdio.h 开头。这些带有“.h”扩展名的文件称为头文件。头文件通常包含各种常用函数、变量和常量的定义。除此之外,头文件还包含要在文件之间共享的宏定义。使用 #include 指令在程序中声明它意味着程序可以在需要时访问指定头文件的所有内容。
例如,stdio.h 是一个头文件,其中 stdio 代表标准输入输出,.h 是头文件扩展名。此头文件主要通过一些预定义函数(如 printf()、scanf()、getc()、putc()、gets()、puts() 等)从键盘获取用户输入并显示输出到监视器。在我们上一篇教程中,我们已经看到像 fprintf()、fscanf()、fgetc()、fputc()、fgets()、fputs() 等文件输入输出函数的使用。由于所有这些函数都打包在 stdio.h 中,因此在程序中包含 stdio.h 对于完成特定任务是必要的。
编写每一段基本代码并在我们编写的每个程序中进行编译是不可能的。而且,有一些通用函数几乎在每个程序中都需要。因此,将所有必需的代码写入一个单独的文件并随时可用是一种惯例。
例如,为了访问和显示,我们经常需要 scanf 和 printf 函数。显然,应该有一堆代码负责它们的正常运行。这些原始源代码写在名为“stdio.h”的头文件中,这就是为什么我们几乎在每个程序中都要写“#include <stdio.h>”。
我们现在对 #include 语法和预处理器指令的功能非常熟悉了。实际上,头文件有两种类型
顾名思义,预定义的库文件是系统中已定义的,如 stdio.h、math.h 等。预定义的头文件用尖括号括起来,语法如下:
#include <file_name.h>
用户定义的头文件包含用户定义的文件,通常用双引号括起来,语法如下:
#include "file_name"
OR
#include "file_name.h"
在这里,编译器将在当前目录中查找指定的文件并导入它。
#include 指令的操作是通过扫描头文件中写入的任何内容并将其嵌入程序来完成的。它还通过遵循程序中定义的顺序来工作。假设我们要创建一个名为“sum.h”的头文件,其中包含前 n 个自然数的求和代码。为了实现这一点,我们首先需要在编辑器中编写所需的代码,并将其保存为 .h 扩展名,因为我们在这里创建一个头文件。头文件的名称将是带有 .h 扩展名的文件名,在本例中是 sum.h。
int sum(int num)
{
int iter,num =0;
for(iter = 1; iter <= num; iter++)
{
sum = sum + iter;
}
return sum;
}
这里我们使用了记事本编辑器,并在其中编写了代码,并将其保存为 sum.h。现在,我们可以像下面这样使用 #include 指令将其导入到我们的程序中。
#include
#include "sum.h"
int main()
{
int number;
printf("Enter the number:");
scanf("%d",&number);
printf("\nSum of first %d numbers is : %d ",number,sum(number));
return 0;
}
代码将按顺序执行,输出为
Enter the number: 200 Sum of first 200 numbers is : 20100
这样,我们就可以增强代码的功能性和可读性,而不是创建一个庞大而复杂的程序。
注意:头文件和程序都应存储在同一位置。
这是一种可以克服重复错误的过程。如果我们一个程序中包含两次相同的头文件,编译器将运行相同的代码两次。这肯定会导致编译错误。在大型程序中,很难检查头文件是否已被包含。因此,如果有一种机制可以保护程序免受这些错误的影响,那就太好了。这种机制是通过条件预处理器指令实现的,如 #ifndef、#define 和 #endif。这些是常用的带条件的代码集,经常用于完成任务,其语法如下:
#ifndef HEADER_FILE_NAME
#define HEADER_FILE_NAME
Header file content
#endif
示例
#ifndef "test.h"
#define "test.h"
THE CONTENT OF THE HEADER FILE
#endif
因此,这里 test.h 是头文件,首先,它将检查程序中是否已存在 test.h 的定义。如果存在,编译器将退出“if”循环,并将控制直接转移到 closing endif。如果答案是否定的,那么 test.h 将被定义,然后是 closing endif。整个机制在 C 编程中被称为 #ifndef 包装器,因为它通过将代码放在 #ifndef 和 #endif 之间来确保代码仅读取一次。
到目前为止,我们已经学习了如何包含头文件,但没有任何条件。但有时情况需要根据情况或程序需求包含多个文件。在这些情况下,我们可能会对 #include 指令施加一系列条件,例如:
肯定,编写一系列复杂的代码会很麻烦,尤其是当有很多条件需要应用时。C 编程的预处理器指令能够使用每个头文件中的宏并利用这些功能使程序更紧凑。在 #include 之后只放一个宏名,而不是参数,这会容易得多。这种条件包含头文件的过程称为“计算包含”。
下面是一个演示宏使用的简单示例。
define FILE1 "file_1.h"
#include FILE1
.....
这里 FILE1 是头文件“file_1.h”的宏名。因此,宏简化了头文件的包含。
起初,我们已经看到头文件分为两类,即标准头文件和用户定义的头文件。基于各种功能,这些标准头文件进一步分类,下表列出了一些常用的头文件。
| 序号 | 头文件 | 描述 | 函数示例 |
|---|---|---|---|
| 1 | stdio.h | 标准输入输出头 | printf(), scanf(),fread(),fwrite() |
| 2 | string.h | 字符串头 | strlen(),strcpy(),strcat(),strcmp() |
| 3 | conio.h | 控制台输入输出头 | clrscr(),getch() |
| 4 | stdlib.h | 标准库头 | calloc(),malloc(),realloc(),free() |
| 5 | math.h | 数学头 | sqrt(),pow(),exp(),floor() |
| 6 | ctype.h | 字符类型头 | isalpha(),isdigit(),isupper(),islower() |
| 7 | assert.h | 断言头 | assert() |
| 8 | time.h | 时间头 | getdate(),setdate(),time(),difftime() |
| 9 | locale.h | 本地化头 | setlocale(),localeconv() |
| 10 | signal.h | 信号头 | signal(),raise() |
| 11 | stdarg.h | 标准参数头 | va_start(),va_arg() |
| 12 | setjmp.h | 跳转头 | setjmp(),longjmp() |
| 13 | errno.h | 错误处理头 | errno() |