当前位置: 首页 > news >正文

C语言用好写好头文件

C语言用好写好头文件

特此说明: 内容主要参考魏永明老师老师的课程 C 语言最佳实践之头文件使用,也可以看下面我整理的笔记。建议初级C程序员多看,干货多水分少,质量很高。

1 说明背景

1)基本认识

  • 头文件作用: 用于公用的函数、宏、数据类型或结构的声明和定义
  • 头文件类型: 对外头文件、全局内部头文件、模块内部头文件、构建系统生成的头文件

2)遵循原则

  • 最少包含原则
    • 只包含必需的头文件
    • 只包含被多个源文件共用的内容
  • 自立原则
    • 任意一个头文件放到源文件的第一行,都不会出现未定义或者未声明的编译错误

2 合理使用条件编译

CASE01: 防止头文件被重复包含

方法一:保卫宏
命名规则:<macro_name>

/* in src file */
#include "a/utils.h"
#include "b/utils.h"

/* in a/utils.h file */
#ifndef _FORBAR_A_UTILS
#define _FORBAR_A_UTILS
....
#endif /* not defined _FORBAR_A_UTILS */

/* in b/utils.h file */
#ifndef _FORBAR_B_UTILS
#define _FORBAR_B_UTILS
....
#endif /* not defined _FORBAR_B_UTILS */

方法二:pragma once
这个方法在C头文件比较少用

#pragma once
....

CASE02: 支持头文件被CPP源文件包含

/* in include/foobar.h file */
#include "foobar_macros.h"

FOOBAR_EXTERN_C_BEGIN
....
/* 外部函数和全局变量做特殊处理, 会生成符号信息 */
....
FOOBAR_EXTERN_C_END

/* in include/foobar_macros.h file */
#ifdef __cplusplus
#define FOOBAR_EXTERN_C_BEGIN extern "C" {
#define FOOBAR_EXTERN_C_END }
#else
#define FOOBAR_EXTERN_C_BEGIN
#define FOOBAR_EXTERN_C_END
#endif

3 了解CMAKE构建系统

CASE01: 编译时配置选项生成头文件

通过CMAKE构建系统配置CMakeLists.txt,举例对于系统头文件,安装到系统:/usr/include/<product name>/XXX.h

# TODO: List the headers should be installed to system here.
set(FooBar_INSTALLED_HEADERS
    "${FooBar_DERIVED_SOURCES_DIR}/foobar_version.h"
    "${FooBar_DERIVED_SOURCES_DIR}/foobar_features.h"
    "${FOOBAR_DIR}/include/foobar_macros.h"
    "${FOOBAR_DIR}/include/foobar_errors.h"
    "${FOOBAR_DIR}/include/foobar_utils.h"
    "${FOOBAR_DIR}/include/foobar_ports.h"
    "${FOOBAR_DIR}/include/foobar.h"
)

CASE02: 通过构建系统的宏替换功能

CMAKE利用宏替换模板文件foobar_features.h.in中的指定内容,然后根据宏替换后的文件内容生成目标文件foobar_features.h,该头文件作用到系统上

/* 模板文件 foobar_features.h.in , 此时 ENABLE_HTML 值为 ON */
#define _FOOBAR_ON      1
#define _FOOBAR_OFF     0

#define FOOBAR_ENABLE_HTML                 _FOOBAR_@ENABLE_HTML@

/* 目标文件 foobar_features.h  */
#define _FOOBAR_ON      1
#define _FOOBAR_OFF     0

#define FOOBAR_ENABLE_HTML                 _FOOBAR_@ENABLE_HTML@

/* CMakeLists.txt定义转换规则 */
configure_file(include/foobar_features.h.in ${FooBar_DERIVED_SOURCES_DIR}/foobar_features.h)

3 抽象设计: 隐藏细节,统一接口

/* 模块内部使用头文件: 对隐藏的数据类型和接口的细节,放在context.h */

/* 对外提供的头文件: 抽象的接口等资源,安装到系统 */

4 参考资料

  • best-practices-of-c
  • C 语言最佳实践之头文件使用

相关文章:

  • 程序员过圣诞 | 用HTML写出绽放的烟花
  • 源码系列 之 HashMap
  • docker logs实时查看日志tail
  • Win10从零安装、训练、部署yolov5 6.x一条龙实战案例
  • 东北大学c++实验最后一次
  • 十六、Docker Compose容器编排第一篇
  • 时序预测 | MATLAB实现IWOA-LSTM和LSTM时间序列预测(改进的鲸鱼算法优化长短期记忆神经网络)
  • CSS预处理语言LESS与SCSS的介绍
  • 互联网摸鱼日报(2022-12-26)
  • 【Python学习记录】matplotlib绘图基本配置
  • java语言的resource 接口
  • 【C语言进阶】想用好C++?那就一定要掌握动态内存管理
  • 【Maven基础】单一架构案例(三)
  • Nacos 寻址机制
  • Python绘制地磁场
  • Apache Pulsar 2.1 重磅发布
  • CSS 专业技巧
  • css布局,左右固定中间自适应实现
  • docker容器内的网络抓包
  • Git学习与使用心得(1)—— 初始化
  • JavaScript创建对象的四种方式
  • Java教程_软件开发基础
  • jquery ajax学习笔记
  • Laravel5.4 Queues队列学习
  • Median of Two Sorted Arrays
  • PAT A1120
  • Python3爬取英雄联盟英雄皮肤大图
  • Redis中的lru算法实现
  • SOFAMosn配置模型
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • spring-boot List转Page
  • Zsh 开发指南(第十四篇 文件读写)
  • 如何选择开源的机器学习框架?
  • 手写一个CommonJS打包工具(一)
  • 小程序button引导用户授权
  • 译米田引理
  • 你对linux中grep命令知道多少?
  • 数据可视化之下发图实践
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • #、%和$符号在OGNL表达式中经常出现
  • #define
  • #include
  • (12)目标检测_SSD基于pytorch搭建代码
  • (2020)Java后端开发----(面试题和笔试题)
  • (39)STM32——FLASH闪存
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (Note)C++中的继承方式
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)程序员技术练级攻略
  • .java 9 找不到符号_java找不到符号
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现