搜索
bottom↓
回复: 9

请指教:关于#define _MAIN_H_ 1 的意思

[复制链接]

出0入0汤圆

发表于 2007-1-29 00:09:00 | 显示全部楼层 |阅读模式
如下:

#ifndef _MAIN_H_

#define _MAIN_H_ 1



最后一句的意思是不是: _MAIN_H_ 的值为 1 ?如果是,这样定义有什么作用?
-----此内容被hzwyl2000于2007-01-29,00:14:50编辑过

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2007-1-29 00:15:51 | 显示全部楼层
纯属笔误~

出0入0汤圆

 楼主| 发表于 2007-1-29 00:57:36 | 显示全部楼层
哦,是这样,我翻了几天书,都想不通。谢谢

出0入0汤圆

发表于 2007-1-29 01:17:14 | 显示全部楼层
这个一般是出现在头文件中的预编译指令

一般是这样的



#ifndef _MAIN_H_

#define _MAIN_H_

  ....

  ....

  (头文件内容)

  ....

#endif





而楼主所说的

#ifndef _MAIN_H_

#define _MAIN_H_ 1

其实也并没有错, #ifndef _MAIN_H_  是判断有没有定义了 _MAIN_H_ 这个宏,如果没有,则执行

#define _MAIN_H_ 1。   而有1和没1其实是一样的,虽然没有1,但是_MAIN_H_ 这个宏确实是定义了,

定义的是一个空值,也就是NULL。所以,有1和没1是没区别的。



下面我讲讲头文件中预定义的重要性,我也是刚了解不久,也做抛砖引玉吧。希望能帮助到初学者。





  在我们用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









希望以上内容能对初学者有所帮助,有什么不对的地方也恳请大家指出修正。


-----此内容被kimiyang于2007-01-29,01:25:44编辑过

出0入0汤圆

 楼主| 发表于 2007-1-29 01:31:41 | 显示全部楼层
看了三楼的讲解,理解了很多,感谢。

出0入0汤圆

发表于 2011-10-28 20:21:20 | 显示全部楼层
最近正好在看avr的头文件内容,三楼的解释真是到位~感谢三楼好人!!!

出0入0汤圆

发表于 2011-11-30 16:17:13 | 显示全部楼层
严重感谢三楼啊,预编译这个东西我一直没弄明白,今天算是恍然大悟了。

出0入0汤圆

发表于 2012-4-6 13:02:36 | 显示全部楼层
终于懂了

出0入0汤圆

发表于 2012-10-25 10:56:49 | 显示全部楼层
多谢三楼啦!

出0入0汤圆

发表于 2013-4-7 12:52:45 来自手机 | 显示全部楼层
学习一下....
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 03:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表