当前位置:嗨网首页>书籍在线阅读

12-头文件示例

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

16.5.1 头文件示例

假设你开发了一个存放人名的结构,还编写了一些使用该结构的函数。可以把不同的声明放在头文件中。程序清单16.6演示了一个这样的例子。

程序清单16.6  names_st.h 头文件

// names_st.h -- names_st 结构的头文件
// 常量
#include <string.h>
#define SLEN 32
// 结构声明
struct names_st
{
   char first[SLEN];
   char last[SLEN];
};
// 类型定义
typedef struct names_st names;
// 函数原型
void get_names(names *);
void show_names(const names *);
char * s_gets(char * st, int n);

该头文件包含了一些头文件中常见的内容: #define 指令、结构声明、 typedef 和函数原型。注意,这些内容是编译器在创建可执行代码时所需的信息,而不是可执行代码。为简单起见,这个特殊的头文件过于简单。通常,应该用 #ifndef#define 防止多重包含头文件。我们稍后介绍这些内容。

可执行代码通常在源代码文件中,而不是在头文件中。例如,程序清单16.7中有头文件中函数原型的定义。该程序包含了 names_st.h 头文件,所以编译器知道 names 类型。

程序清单16.7  name_st.c 源文件

// names_st.c -- 定义 names_st.h中的函数
#include <stdio.h>
#include "names_st.h"   // 包含头文件
// 函数定义
void get_names(names * pn)
{
   printf("Please enter your first name: ");
   s_gets(pn->first, SLEN);
   printf("Please enter your last name: ");
   s_gets(pn->last, SLEN);
}
void show_names(const names * pn)
{
   printf("%s %s", pn->first, pn->last);
}
char * s_gets(char * st, int n)
{
   char * ret_val;
   char * find;
   ret_val = fgets(st, n, stdin);
   if (ret_val)
   {
     find = strchr(st, '\n'); // 查找换行符
     if (find)             // 如果地址不是NULL,
        *find = '\0';      // 在此处放置一个空字符
     else
        while (getchar() != '\n')
          continue;  // 处理输入行中的剩余字符
   }
   return ret_val;
}

get_names() 函数通过 s_gets() 函数调用了 fgets() 函数,避免了目标数组溢出。程序清单16.8使用了程序清单16.6的头文件和程序清单16.7的源文件。

程序清单16.8  useheader.c 程序

// useheader.c -- 使用 names_st 结构
#include <stdio.h>
#include "names_st.h"
// 记住要链接 names_st.c
int main(void)
{
   names candidate;
   get_names(&candidate);
   printf("Let's welcome ");
   show_names(&candidate);
   printf(" to this program!\n");
   return 0;
}

下面是该程序的输出:

Please enter your first name: Ian
Please enter your last name: Smersh
Let's welcome Ian Smersh to this program!

该程序要注意下面几点。

  • 两个源代码文件都使用 names_st 类型结构,所以它们都必须包含 names_st.h 头文件。
  • 必须编译和链接 names_st.cuseheader.c 源代码文件。
  • 声明和指令放在 nems_st.h 头文件中,函数定义放在 names_st.c 源代码文件中。