模塊化編程時,#include到底要放在哪裏?

結合我本身的經驗,談一談模塊化編程時#include應該出現的位置。總結起來大致有二條規則:編程

1、規則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中。當一個項目的代碼量很大時,因爲效率地下而多佔用的時間就沒法忽視了。spa

2、規則2:使#include出如今它被須要的地方code

爲了使用printf()函數,能夠把#include<stdio.h>放在foo.h文件中,編譯也能夠正常經過,以下:blog

===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中,定義了以下結構體定義:io

=====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文件中是必須的!

 

用一句話歸納:只在必要的地方包含必要的頭文件!

相關文章
相關標籤/搜索