结合我自己的经验,谈一谈模块化编程时#include应该出现的位置。总结起来大体有二条规则:

一、规则1:只包含必要的头文件

  看下面这个模块:

===foo.c====
#include <stdio.h>
#include <foo.h>
#include <uart.h>
void foo ()
{
printf ("hello world!\n");
}
===foo.h====
#ifndef __foo_h__
#define __foo_h__ extern void foo(); #endif

在foo()函数中也只有简单的一行打印语句。由于printf()函数的原型声明来源于stdio.h,因此foo.c中包含了stdio.h无可厚非,否则根本无法使用。但foo.c文件中除了包含stdio.h外还包含了另外一个多余的头文件 ——uart.h,这不会导致编译的出错,但我们并不需要使用uart.h中声明的接口,因此这种行为会导致编译效率的降低。如果此时uart.h中还包含了其它文件,那么全部都会在预处理时展开到foo.c中。当一个项目的代码量很大时,由于效率地下而多占用的时间就无法忽视了。

二、规则2:使#include出现在它被需要的地方

为了使用printf()函数,可以把#include<stdio.h>放在foo.h文件中,编译也可以正常通过,如下:

===foo.h====
#ifndef __foo_h__
#define __foo_h__ #include <stdio.h> extern void foo(); #endif
===foo.c====

#include <foo.h>

void foo ()
{
printf ("hello world!\n");
}

但这样会产生一个问题,stdio.h对于我们的头文件foo.h来说,是必须的么?当然不是!那么会导致什么样的问题呢?我们已经直到.h文件的作用相当于模块的使用说明书,如果其它模块要使用foo模块时,需要通过#include<foo.h>来添加接口函数,此时就会间接的包含了stdio.h,同样的会导编译致速度下降的问题。因此,正确的做法是将#include<stdio.h>放在foo.c中,如下:

===foo.h====
#ifndef __foo_h__
#define __foo_h__ extern void foo(); #endif ===foo.c====
#include <stdio.h>
#include <foo.h> void foo ()
{
printf ("hello world!\n");
}

理解了上面的例子,则看下面一条实例:

在system.h中,定义了如下结构体定义:

=====system.h=====

#ifndef __system_h__
#def __system_h__ typedef struct stuTAG{ char * name;
u8 age; }stu_st; #endif

同样在一个foo.c模块中,定义了一个函数:

===foo.h====
#ifndef __foo_h__
#define __foo_h__
#include "system.h" extern void print_info(stu_st * student); #endif
=====foo.c=====
#include "foo.h"
#include <stdio.h> void print_info(stu_st * student)
{
printf("name:%s\n",student->name);
printf("age :%d\n",student->age); }

从这个foo模块的实现代码来看,foo.h和foo.c都需要了解stu_st结构体的内容,也就是stu_st是被foo.c和foo.h同时需要的,因此它必须被放置在foo.h中,否则编译时会出现stu_st未定义的错误,此时将#include放置在.h文件中是必须的!

用一句话概括:只在必要的地方包含必要的头文件!

模块化编程时,#include到底要放在哪里?的更多相关文章

  1. keil采用C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法

    以前写单片机程序时总是把所用函数和变量都写在一个c文件里,后来遇到大点的项目,程序动则几千行,这种方式无疑会带来N多麻烦,相信大家都有所体验吧! 后来学会了在keil里进行模块化编程,即只把功能相同或 ...

  2. 详解keil采用C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法

    一.关于全局变量的定义.声明.引用: (只要是在.h文件中定义的变量,然后在main.c中包含该.h文件,那么定义的变量就可以在main函数中作为全局变量使用) 方法1: 在某个c文件里定义全局变量后 ...

  3. 【C语言探索之旅】 第二部分第一课:模块化编程

    内容简介 1.课程大纲 2.第二部分第一课: 模块化编程 3.第二部分第二课预告: 进击的指针,C语言王牌 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C ...

  4. 单片机 C 语言模块化编程

    好的开始是成功的一半 通过上一章的学习,我想你已经掌握了如何在程序中释放CPU了.希望能够继续坚持下去.一个良好的开始是成功的一半.我们今天所做的一切都是为了在单片机编程上做的更好. 在谈论今天的主题 ...

  5. 嵌入式C语言之---模块化编程

    当你在一个项目小组做一个相对较复杂的工程时,意味着你不再独自单干.你需要和你的小组成员分工合作,一起完成项目,这就要求小组成员各自负责一部分工程.比如你可能只是负责通讯或者显示这一块.这个时候,你就应 ...

  6. js模块化编程之彻底弄懂CommonJS和AMD/CMD!

    先回答我:为什么模块很重要? 答:因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写 ...

  7. [转]js模块化编程之彻底弄懂CommonJS和AMD/CMD!

    原文: https://www.cnblogs.com/chenguangliang/p/5856701.html ------------------------------------------ ...

  8. Javascript模块化编程(三):require.js的用法

    Javascript模块化编程(三):require.js的用法 原文地址:http://www.ruanyifeng.com/blog/2012/11/require_js.html 作者: 阮一峰 ...

  9. Javascript模块化编程之路——(require.js)

    转自:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html Javascript模块化编程(一):模块的写法 随着网站逐渐变成&q ...

随机推荐

  1. 通过全局getApp获取全局实例获取数据

    学习是每一个人都要面对的铁一般的事实,不进则退.学习同样讲究途径和方法,面对知识这个巨人,我们永远不会有成年的那一刻,但我们可以让自己毕生尽可能地吸取更多有价值的信息,好让自己人生充满各种“意义”存在 ...

  2. iOS开发 适配iOS10以及Xcode8

    iOS10的适配以及Xcode8使用上的一些注意点 一.证书管理 用Xcode8打开工程后,比较明显的就是下图了,这个是苹果的新特性,可以帮助我们自动管理证书.建议大家勾选这个Automaticall ...

  3. HTML5 input placeholder 颜色修改示例

    Chrome支持input=[type=text]占位文本属性,但下列CSS样式却不起作用: CSS 复制代码 代码如下: input[placeholder], [placeholder], *[p ...

  4. kernel/vsprintf.c

    /* *  linux/kernel/vsprintf.c * *  Copyright (C) 1991, 1992  Linus Torvalds */ /* vsprintf.c -- Lars ...

  5. 转:StrictMode使用

    最新的Android平台中(Android 2.3起),新增加了一个新的类,叫StrictMode(android.os.StrictMode).这个类可以用来帮助开发者改进他们编写的应用,并且提供了 ...

  6. C堆栈入门

    原文:http://student.csdn.net/link.php?url=http://www.top-e.org%2Fjiaoshi%2Fhtml%2F427.html 格式和部分内容稍作修改 ...

  7. 《Matrix Computation 3rd》读书笔记——第3章 一般线性系统

  8. .gitignore的多级目录配置

    在子目录下仍然可以建立.gitignore文件以用于忽略子目录的文件

  9. Hadoop Pipeline详解[摘抄]

    最近使用公司内部的一个框架写map  reduce发现没有封装hadoop streaming这些东西,查了下pipeline相关的东西 Hadoop Pipeline详解 20. Aug / had ...

  10. 【转】windows server 2012清除并重建SID

    windows server 2012清除并重建SID 2012-09-17 17:51:51 标签:SID windows server 2012 原创作品,允许转载,转载时请务必以超链接形式标明文 ...