随笔 - 23  文章 - 0 评论 - 68 
<2007年11月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

广告中国绩效网,注册立刻送10元 广告中国绩效网,注册立刻送10元

常用链接

留言簿(7)

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

预编译一般用来防止头文件的重复包含和编译。

在我们用C做开发的是候,有时候项目很大,我们所编写的程序会很长。这样我们如果还是写在一个文件中会出现管理上的问题和 
查看上的不方便。因此,我们可以分多个文件编写我们的程序,这样把一个功能的程序写到一个文件里,便于查看 也有助于我们管理。 
如main.c sd.h sd.c lcd.h lcd.c fat.h fat.c delay.h delay.c 

    至于头文件(sd.h)和源文件(sd.c)的写法应该是这样的: 
     在头文件中 我们写的是 函数的声明,和一些使用到的变量的声明; 
     在源文件中 我们写的是 对应于头文件中的函数的具体实现,即函数左大括号和右大括号中的内容。 

    在具体使用相关函数是可以使用#include 命令来包含其函数所在的头文件。下面我们虚拟如下的一个程序结构来展开说明: 

如在main.c中 
#include delay.h 
#include sd.h 
#include lcd.h 
#include fat.h 
main() 

  sd_init(); 
  delay_nms(10); 
  lcd_init(); 
  while(1) 
  { 
    .... 
    ....; 
  } 


在sd.c中 
void sd_init() 

 ...... 
 ......;  


在sd.h中 
#include delay.h 
#include ....... 
void sd_init(); 
..... 

在delay.c中 
void delay_nms(UINT n) 

 for(....) 
  {... 
   _asm_("nop"); 
   ... 
  }  


在delay.h中 
void delay_nms(UINT n); 

..... 

   我们看,如果在头文件的书写中都没加预编译指令 
#ifndef XXXXXXXX  
#define XXXXXXXX 
  .... 
  .... 
  (头文件内容) 
  .... 
#endif     


会出现怎么样的情况????    其实这样,编译会报错。编译器会提示 void delay_nms()定义了两次。为什么会出现这种情况呢? 
    我们顺着程序读一下,当我们在main.c中,编译器读到#include delay.h时会把 delay.h文件中的内容包含进来,这样delay.h中的 
delay_nms()函数定义了一次,当我们在往下,读到#include sd.h时,把sd.h包含进来,在把sd.h的内容展开,我们又读到了一次delay.h 
这样又把delay.h的内容包含近了main.c 。因此,我们发现delay.h被main.c重复包含了2次。这样使得void delay_nms()函数也被定义了二次。 

    如何解决重复定义的问题,我们是用条件编译,#ifndef ..等。在头文件中加入条件编译指令,如下: 

在sd.h中 
#ifndef _SD_H_  
#define _SD_H_ 

#include delay.h 
#include ....... 
void sd_init(); 
..... 

#endif 

在delay.h中 
#ifndef _DELAY_H_  
#define _DELAY_H_ 

void delay_nms(UINT n); 

..... 
#endif 

   这样,让我们再看下会出现什么情况。 
   当我们在main.c中,编译器读到#include delay.h时会把 delay.h文件中的内容包含进来,(#ifndef _DELAY_H_)我们先判断有没有定义 
了 _DELAY_H_  这个宏,由于这是第一次调用delay.h,_DELAY_H_这个宏还没定义,这样编译器会顺序向下执行,执行到#define _DELAY_H_ 
则定义了一个_DELAY_H_宏,宏值为NULL. 当我们main.c中再往下,读到#include sd.h时,把sd.h包含进来,在把sd.h的内容展开, 
我们又读到了一次delay.h。 这一次 我们判断 #ifndef _DELAY_H_ 结果是已经定义了,这样,编译器会跳过下面的内容,直接到 #endif。 
可见,我们的函数 void delay_nms(UINT n); 就不会被重复定义二次! 对于其他的头文件,我们现在也加上 预编译指令,防止被重复包含。 

  另外,在WinAVR中,如果使用多文件编译,需要在Makeflie中修改 SRC = $(TARGET).c 在其后面添加你的头文件的源文件的名字。如 
  SRC = $(TARGET).c delay.c sd.c fat.c lcd.h 




希望以上内容能对初学者有所帮助,有什么不对的地方也恳请大家指出修正。
posted on 2007-11-11 22:20 吴剑 阅读(1543) 评论(0)  编辑 收藏 引用 所属分类: 我的技术文摘
只有注册用户登录后才能发表评论。