Cprogramming 简明教程

Header Files in C

#include preprocessor 指令用于将函数、常量和宏等的定义从一个文件(通常称为头文件)提供给另一个 C 代码使用。头文件有扩展名“ .h ”,您可以从中包含一个或多个预定义函数、常量、宏等的预先声明。C 中提供头文件方便程序模块化设计。

System Header Files

C compiler 软件与许多预编译头文件捆绑提供。它们称为 system header files 。一个著名的示例是“stdio.h”,几乎每个 C 程序中都包含此头文件。

每个系统头文件都包含许多实用函数。这些函数通常称为 library functions 。例如,用于执行 IO 操作的 printf() 和 scanf() 函数是“stdio.h”头文件中可用的库函数。

加载一个或多个头文件的前置处理器语句总是位于 C 代码的开头。我们将从学习一个基本 "Hello World" program 开始我们的 C 编程之旅,该 "Hello World" program 从包含 "stdio.h" file 开始 −

#include <stdio.h>

int main() {

   /* my first program in C */
   printf("Hello, World! \n");

   return 0;
}

C 预处理指令 #include 基本上是请求编译器加载特定头文件的内容,以便在程序中使用它们。

C 或 C++ 程序中常见的做法是,我们将所有常量、宏、系统范围的全局变量和函数原型保留在头文件中,并在需要时包含该头文件。

Syntax to Include Header Files in C

加载头文件时使用 #include directive 。它的用法遵循以下两种方法之一 −

#include <filename.h>

如果头文件名放在尖括号中,则说明它位于系统/默认目录中。

#include "filename.h"

预定义或非常规标题文件名称,文件内使用双引号,可在源文件所在的同一目录中使用

#include 指令通过指导 C preprocessor 在继续当前源文件其余部分之前扫描指定的文件作为输入来发挥作用。预处理器的输出包含已经生成的输出,然后是包含文件产生的输出,然后是 #include 指令之后的文本产生的输出。

Standard Header Files in C

一个典型的 C 编译器捆绑了许多已编译标题文件。每个标题文件包含一组预定义的标准库函数。"#include" 预处理指令用于在程序中包含扩展名为 ".h" 的标题文件。

以下是显示 C 语言中一些标题文件的一张表 −

Header Files

Description

Functions/macros/variables

stdio.h

Input/Output functions

scanf(), printf(), fopen(), FILE

stdlib.h

General utility functions

atoi(), atof(), malloc()

math.h

Mathematics functions

sin(), cos(), pow(), sqrt()

string.h

String functions

strcpy(), strlen(), strcat()

ctype.h

Character handling functions

isalpha(), isupper(), ispunct()

time.h

Date and time functions

asctime(), gmtime(), mktime()

float.h

Limits of float types

FLT_ROUNDS, FLT_RADIX,

limits.h

Size of basic types

CHAR_BIT, CHAR_MIN, CHAR_MAX

wctype.h

确定宽字符数据中包含的类型的函数。

iswalpha(), iswctype(),iswupper()

Example

一些标题文件中的几个库函数在下面的代码中使用 −

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int main() {

   char s1[20] = "53875";
   char s2[10] = "Hello";
   char s3[10] = "World";

   int res;
   res = pow(8, 4);
   printf("Using math.h, The value is : %d\n", res);

   long int a = atol(s1);
   printf("Using stdlib.h, the string to long int: %d\n", a);

   strcpy(s2, s3);
   printf("Using string.h, the strings s2 and s3: %s\t%s\n", s2, s3);

   return 0;
}

当你运行这段代码时,它将产生以下输出:

Using math.h, The value is: 4096
Using stdlib.h, the string to long int: 53875
Using string.h, the strings s2 and s3: World	World

User-defined Header Files

我们可以在 C 程序中添加一个或多个用户定义函数(与 main() function 无关)。但是,如果代码包含大量函数定义,那么将它们放入单个扩展名为 ".c" 的源代码文件中将会难以处理和维护。因此,将类似性质的函数/宏/变量组合到标题文件中,并像包含标准标题文件一样包含它们,然后调用其中定义的函数。

用户定义标题文件通常放置在 C 源代码所在的同一目录中。

在下面描述了使用 CodeBlocks IDE 创建和使用标题文件的过程。启动 CodeBlocks IDE 并创建一个新的控制台应用程序 −

header files

为项目选择一个合适的名字。在文件夹中添加一个新的空文件,并保存以下代码为 "myheader.h"

#ifndef MYHEADER_H
#define MYHEADER_H

void sayHello();
int add(int a, int b);
double area(double radius);
int length(char *x);

#endif

如果一个标题文件恰好被包含两次,编译器会处理其内容两次,这会导致一个错误。防止这种情况的标准方法是在条件定义中用 #ifndef directive, 称为 header guard 括起来文件的整个真实内容。

标头保护检查标题文件是否已定义。如果未定义,则表示该文件是第一次包含,并且保护中的代码将被处理。

标题文件包含要包含的函数的前向声明或原型。这些函数的实际定义在与标题文件同名的 ".c" 文件中提供。

Creating a Header File

将以下代码保存在 "myheader.c" 文件中 −

#include <stdio.h>
#include <string.h>
#include <math.h>

#define PI 3.142

void sayHello(){
   printf("Hello World\n");
}

int add(int a, int b){
   int result;
   result = a+b;
   return result;
}

double area(double radius){
   double areaofcircle = PI*pow(radius, 2);
   return areaofcircle;
}

int length(char *x){
   return strlen(x);
}

Using the Header File

我们现在可以在程序中包含 "myheader.h" 文件并调用以上任何函数。将以下代码作为 "main.c" 保存在项目文件夹中。

#include <stdio.h>
#include "myheader.h"

int main() {

   int p = 10, q = 20;
   double x = 5.25;

   sayHello();
   printf("sum of %d and %d is %d\n", p, q, add(p,q));
   printf("Radius: %lf Area: %lf", x, area(x));

   return 0;
}

构建项目并运行 "main.c",可以从 CodeBlocks IDE 的运行菜单中运行,也可以从命令行中运行以获得以下结果 −

Hello World
sum of 10 and 20 is 30
Radius: 5.250000 Area: 86.601375

Computed Includes

有时有必要选择几个不同的标题文件中的一个来包含到你的程序中。例如,它们可以指定要在不同类型操作系统上使用的配置参数。你可以使用一系列条件来实现这一点,如下所示 −

#if SYSTEM_1
   # include "system_1.h"
#elif SYSTEM_2
   # include "system_2.h"
#elif SYSTEM_3
   ...
#endif

但随着它的发展,它变得繁琐,取而代之的是预处理器提供了使用宏作为标题名的能力。这称为已计算包含。不要将标题名直接作为 #include 的参数来写,你只需在那里放置一个宏名 −

#define SYSTEM_H "system_1.h"
...
#include SYSTEM_H

SYSTEM_H 将被展开,并且预处理器将查找 system_1.h,就好像 #include 已经这样写过一样。SYSTEM_H 可以在 Makefile 中使用 -D 选项定义。