c语言.h文件怎么写,C 头文件怎么写

一些初学C语言的人,不知道头文件(*.h文件)原来还可以自己写的。只知道调用系统库函数时,要使用#include语句将某些头文件包含进去。其实,头文件跟.C文件一样,是可以自己写的。头文件是一种文本文件,使用文本编辑器将代码编写好之后,以扩展名.h保存就行了。头文件中一般放一些重复使用的代码,例如函数声明,变量声明,常数定义,宏的定义等等。当使用#include语句将头文件引用时,相当于将头文件中所有内容,复制到#include处。为了避免因为重复引用而导致的编译错误,头文件常具有

#ifndef LABEL

#define LABEL

//代码部分

#endif

的格式。其中,LABEL为一个唯一的标号,命名规则跟变量的命名规则一样。常根据它所在的头文件名来命名,例如,如果头文件的文件名叫做hardware.h,那么可以这样使用:

#ifndef __HARDWARE_H__

#define __HARDWARE_H__

//代码部分

#endif

这样写的意思就是,如果没有定义__HARDWARE_H__,则定义__HARDWARE_H__,并编译下面的代码部分,直到遇到#endif。这样,当重复引用时,由于__HARDWARE_H__已经被定义,则下面的代码部分就不会被编译了,这样就避免了重复定义。

另外一个地方就是使用include时,使用引号与尖括号的意思是不一样的。使用引号(“”)时,首先搜索工程文件所在目录,然后再搜索编译器头文件所在目录。而使用尖括号(<>)时,刚好是相反的搜索顺序。假设我们有两个文件名一样的头文件hardware.h,但内容却是不一样的。一个保存在编译器指定的头文件目录下,我们把它叫做文件I;另一个则保存在当前工程的目录下,我们把它叫做文件II。如果我们使用的是#include ,则我们引用到的是文件I。如果我们使用的是#include “hardware.h”,则我们引用的将是文件II。笔者以前就遇到过一个同事问,为什么他修改了那个头文件里面的内容,好象跟没有修改一样?就是因为他有两个一样的头文件(就像我们刚描述的那样),他是使用#include 引用的,而他修改时,却是当前工程所在的目录下的那个文件。

笔者所使用的编写c程序的IDE是CodeBlokcs, 我的头文件放置在D:\CodeBlocks\MinGW\include文件夹下。

我们在编写C语言或C++语言时,预处理文件都被表示为#include 、#include 或#include 等等。在这里的“h”表示的是头文件。那么是什么的头文件?头文件又是什么呢?如若不加上“h”的话,我运行了程序,似乎还是可以运行成功,但加不加“h”到底又有什么关系? #include 语句起的是文件包含作用。功能是把指定的文件插入该命令行位置取代该命令行,从而把指定的文件和当前的源程序文件连成一个源文件。要求这个语句必须在源程序的最前面。

所谓“头文件”,指的是在源文件头部引入的文件,顾名思义,即是头文件。至于头文件本身,则没有什么固定格式和固定扩展名。你可以将自己写的C文件作为头文件包含进来。至于扩展名h,则表示是系统提供的头文件类型。如果是TC,一般头文件的路径是:TC/INCLUDE 。 头文件都是纯文本格式,内容多数是函数定义或函数体等。

在调用系统函数时,有些是必须要包含进来相应的头文件才可以使用的,如isalpha函数,判断是否为字母,必须要包含ctype.h头文件。有些则不必,那是因为系统已经默认包含进来了,例如包含Printf函数的头文件stdio.h,是系统默认包含的,虽然显示的包含也没有任何问题。

另外,对于系统提供的头文件,如ctype.h 如果不写扩展名的话,系统会找不到这个头文件,而无法实现包含的功能。所以正确的系统.h文件,是一定要写上扩展名的。

头文件random_number.h(生成随机数)

#include

#include

#include

#include

#ifndef RANDOMNUMBER_H_INCLUDED

#define RANDOMNUMBER_H_INCLUDED

#endif // RANDOMNUMBER_H_INCLUDED

//随机数库实现

void Randomize()

{

srand((unsigned)time(NULL)); //使用当前时间作为伪随机数种子

}

int GenerateRandomNumber(int low, int high)

{

double _d;

if(low > high)

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);

// 打印出红色字体

printf("Make sure input number: Low < High .\n");

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7);

// 打印默认字体

exit(0);

}

_d = (double)rand()/((double)RAND_MAX + 1.0);

return low + (int)(_d * (high - low +1));

}

double GenerateRandomReal(double low, double high)

{

double _d;

if(low > high)

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);

printf("Make sure input number: Low < High .\n");

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7);

exit(0);

}

_d = (double)rand()/((double)RAND_MAX + 1.0);

return low + _d * (high - low);

}

现在我们只需要在需要使用到随机数的文件中写上

#ifndef RANDOMNUMBER_H_INCLUDED

#include "random_number.h"

#endif // RANDOMNUMBER_H_INCLUDED

即可使用上面的函数调用了。

头文件(random_number.h)进阶

上面的文件是只写了一个头文件并且将定义和实现都写在了头文件中,其实我们可以将定义和实现分离(为了更好的封装性,让用户专注于接口的使用,而忽略实现的细节)。

头文件(random_number.h)中代码如下:

#ifndef RANDOM_H_INCLUDED

#define RANDOM_H_INCLUDED

void Randomize(); //初始化伪随机数发生器

int GenerateRandomNumber(int low, int high); //生成一个随机整数介于low 和 high 之间

double GenerateRandomReal(double low, double high); //生成一个随机实数介于low 和 high 之间

#endif // RANDOM_H_INCLUDED

同时需要一个.c文件来实现在头文件中定义的函数。(random_number.c)具体代码如下:

#include

#include

#include

#include

#ifndef RANDOM_H_INCLUDED

#include "random.h"

#endif

//随机数库实现

void Randomize()

{

srand((unsigned)time(NULL)); //使用当前时间作为伪随机数种子

}

int GenerateRandomNumber(int low, int high)

{

double _d;

if(low > high)

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);

// 打印出红色字体

printf("Make sure input number: Low < High .\n");

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7);

// 打印默认字体

exit(0);

}

_d = (double)rand()/((double)RAND_MAX + 1.0);

return low + (int)(_d * (high - low +1));

}

double GenerateRandomReal(double low, double high)

{

double _d;

if(low > high)

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);

printf("Make sure input number: Low < High .\n");

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7);

exit(0);

}

_d = (double)rand()/((double)RAND_MAX + 1.0);

return low + _d * (high - low);

}

这个库与上一种写法使用方法相同。但我们更推荐这种写法

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是将上述程序进行模块化编,分别成.c和.h文件的示例: dht11.h文件: ```c #ifndef DHT11_H_ #define DHT11_H_ void delay(unsigned int time_ms); unsigned char read_dht11_byte(); void read_dht11_data(unsigned char *humi, unsigned char *temp); #endif /* DHT11_H_ */ ``` dht11.c文件: ```c #include <reg51.h> #include "dht11.h" #define DHT11_PIN P3_2 void delay(unsigned int time_ms) { unsigned int i, j; for (i = 0; i < time_ms; i++) { for (j = 0; j < 120; j++); } } // 从DHT11读取一个字节 unsigned char read_dht11_byte() { unsigned char i; unsigned char data = 0; for (i = 0; i < 8; i++) { while (!DHT11_PIN); delay(30); if (DHT11_PIN) { data |= (1 << (7 - i)); while (DHT11_PIN); } } return data; } // 从DHT11读取湿度和温度数据 void read_dht11_data(unsigned char *humi, unsigned char *temp) { unsigned char humi_high, humi_low, temp_high, temp_low, check_sum; DHT11_PIN = 0; delay(20); DHT11_PIN = 1; while (DHT11_PIN); humi_high = read_dht11_byte(); humi_low = read_dht11_byte(); temp_high = read_dht11_byte(); temp_low = read_dht11_byte(); check_sum = read_dht11_byte(); if (check_sum == humi_high + humi_low + temp_high + temp_low) { *humi = humi_high; *temp = temp_high; } } ``` 主程序文件: ```c #include <stdio.h> #include "dht11.h" // 主函数 void main() { unsigned char humi, temp; while (1) { read_dht11_data(&humi, &temp); printf("Humidity: %d%%, Temperature: %d°C\n", humi, temp); delay(5000); } } ``` 在上述代码中,我将读取DHT11数据的函数放置到了dht11.h和dht11.c文件中,方便后续的代码复用和维护。同时,我也在dht11.h文件中声明了三个函数:delay、read_dht11_byte和read_dht11_data,这样其他文件在需要使用这些函数的时候,只需要include这个头文件即可。最后,在主程序文件中,我include了dht11.h文件,并调用了read_dht11_data函数,完成了DHT11数据的读取和输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值