一.头文件的使用
如果把main函数放在第一个文件中,而把自定义函数放在第二个文件中,那么就需要在第一个文件中声明函数原型。如果把函数原型包含在一个头文件里,那么就不必每次使用函数的时候都声明其原型了。把函数声明放入头文件是很好的习惯。
二.#include 与 #define的意义
#include 是预编译指令,代表头文件包含。#define定义一个宏常量。
三.#ifdef #ifndef与#endif
#ifdef 这是个预编译指令,代表只要定义了一个常量,那么就预编译下面的代码
基本语法:
#ifdef 宏
代码
#endif
#ifndef也是个预编译指令,代表如果这个宏不存在,就编译下面的代码
#ifndef 宏 // 如果这个宏不存在,就编译下面的代码
代码
#endif
四.解决C语言头文件重复包含的问题
比如有一个外部引用的a.h头文件,那么在a.h头文件中应当这样定义:
#ifndef ____AH____ #define ____AH_____ int mymax(int a, int b); // 声明 int add(int a, int b); // 声明 #endif
实际应用:
下面是在一个C文件中使用另一个C文件中定义的函数并包含其头文件的例子。
test.c
#include <stdio.h> // 这个头文件在系统目录下 #include <stdlib.h> // 使用了system函数 #include "a.h" // 这个头文件在当前目录下 void main() { /*char *a = "hello1234"; printf("当前字符串的长度为:%d ",mystrlen(a,0));*/ for (int i = 0; i < 11; i++) { printf("第%d个数的结果为:%d ",i,fib(i)); } system("pause"); }
a.h
#ifndef __AH__ #define __AH__ int mystrlen(const char *p, int n); // 计算当前字符串长度 int fib(int n); // 斐波那契数列 int getBinary(int n); // 将十进制数转换为二进制数 int getAge(int n); // 计算第n个人的年龄 void decreasing(int n); // 先序递归 输出结果:10 9 8 7 6 5 4 3 2 1 void increasing(int n); // 后序递归 输出结果:1 2 3 4 5 6 7 8 9 10 #endif
a.c
#include <stdio.h> // 计算当前字符串长度 int mystrlen(const char *p, int n) { if (p[n]) { // 这里判断是否到达字符串末尾的0 return mystrlen(p, n + 1); } else { return n; } } // 斐波那契数列 int fib(int n) { if (n == 0) return 0; if (n == 1) return 1; if (n > 1) return fib(n - 1) + fib(n - 2); } //将十进制数转换为二进制数 void getBinary(int n) { int i = n % 2; if (n >= 2) { getBinary(n / 2); } printf("%d", i); } // 计算第n个人的年龄 int getAge(int n) { int age; if (n == 1) { age = 10; } else{ age = getAge(n - 1) + 2; } return age; } // 先序递归 输出结果:10 9 8 7 6 5 4 3 2 1 void decreasing(int n) { if (n > 0){ // 递归终止条件,递归一定要有终止条件 printf("n=%d ", n); decreasing(n - 1); } } // 后序递归 输出结果:1 2 3 4 5 6 7 8 9 10 void increasing(int n) { if (n > 0) { increasing(n - 1); printf("n=%d ", n); } }