关于条件编译的问题
2010-04-21 09:26
239 查看
这两天来忙活ucos-II在PIC18fxxx系列上的移植。在编译的时候老出现变量被多重定义的错误。花费了一天的功夫才成功编译通过,错误何在??就是因为没有搞明白条件编译的原理,二是对mcc18编译器的特点无知。下面学习条件编译方面的知识:
【例6.6】使用条件编译命令解决由于文件包含而出现的变量重名问题。
设有头文件exemple6_6.h,其内容如下:
# define R 6
float volume;
源文件exemple6_6.cpp的内容如下:
# include <iostream.h>
# include " exemple6_6.h"
# define PI 3.14159
# define R 6
# define AREA R*R*PI
float volume;
void main(void)
{ volume=4*PI*R*R*R /3;
cout<<"圆的面积="<<AREA<<endl;
cout<<"圆球体积="<<volume<<endl;
}
该题编译时出现,volume变量被重复定义的错误。事实上,经预编译后,将头文件包含在源文件中,因此,预编译后的源文件为:
# include <iostream.h>
# define R 6
float volume;
# define PI 3.14159
# define R 6
# define AREA R*R*PI
float volume;
void main(void)
{ volume=4*PI*R*R*R /3;
cout<<"圆的面积="<<AREA<<endl;
cout<<"圆球体积="<<volume<<endl;
}
显然,表示圆球体积的变量volude被重复定义了二次,表示圆半径的宏名R也被重复定义了二次。为了解决写在两个不同文件中可能出现变量名重名的问题,可使用条件编译命令。采用条件编译命令后的头文件exemple6_6.h修改如下:
#ifndef _EX_ H
# define _EX_ H //2
# define R 6 //3
float volume; //4
# endif
采用条件编译命令后的源文件exemple6_6.cpp修改如下:
# include <iostream.h>
# include "exemple6_6.h"
#ifndef _EX_ H
# define _EX_ H //4
# define R 6 //5
float volume; //6
# endif
# define PI 3.14159
# define AREA R*R*PI
void main(void)
{ volume=4*PI*R*R*R /3;
cout<<"圆的面积="<<AREA<<endl;
cout<<"圆球体积="<<volume<<endl;
}
程序执行后输出:
圆的面积=113.097
圆球体积=904.778
程序在预编译头文件时,先判断是否定义过标识符_EX_ H,若没有定义过,则执行第2、3、4行语句,定义标识符_EX_ H,定义全局变量volume与宏名R,否则不执行2、3、4行语句。编译源文件时,同样先判断是否定义过标识符_EX_ H,若没有定义过,则执行第4、5、6行语句,定义标识符_EX_ H,定义全局变量volume与宏名R,否则不执行4、5、6行语句,不定义全局变量volume与宏名R。由于头文件先编译,所以在头文件中已定义了标识符_EX_ H、全局变量volume与宏名R,所以编译源文件时,#ifndef _EX_ H为假,不再重复定义全局变量volume与宏名R。避免变量重名产生的编译错误。这种用条件编译命令解决由多个用户编写多文件程序中出现变量重名问题是非常有效的。
另链接C语言编译全过程剖析:
http://www.yuanma.org/data/2009/0506/article_3647.htm
【例6.6】使用条件编译命令解决由于文件包含而出现的变量重名问题。
设有头文件exemple6_6.h,其内容如下:
# define R 6
float volume;
源文件exemple6_6.cpp的内容如下:
# include <iostream.h>
# include " exemple6_6.h"
# define PI 3.14159
# define R 6
# define AREA R*R*PI
float volume;
void main(void)
{ volume=4*PI*R*R*R /3;
cout<<"圆的面积="<<AREA<<endl;
cout<<"圆球体积="<<volume<<endl;
}
该题编译时出现,volume变量被重复定义的错误。事实上,经预编译后,将头文件包含在源文件中,因此,预编译后的源文件为:
# include <iostream.h>
# define R 6
float volume;
# define PI 3.14159
# define R 6
# define AREA R*R*PI
float volume;
void main(void)
{ volume=4*PI*R*R*R /3;
cout<<"圆的面积="<<AREA<<endl;
cout<<"圆球体积="<<volume<<endl;
}
显然,表示圆球体积的变量volude被重复定义了二次,表示圆半径的宏名R也被重复定义了二次。为了解决写在两个不同文件中可能出现变量名重名的问题,可使用条件编译命令。采用条件编译命令后的头文件exemple6_6.h修改如下:
#ifndef _EX_ H
# define _EX_ H //2
# define R 6 //3
float volume; //4
# endif
采用条件编译命令后的源文件exemple6_6.cpp修改如下:
# include <iostream.h>
# include "exemple6_6.h"
#ifndef _EX_ H
# define _EX_ H //4
# define R 6 //5
float volume; //6
# endif
# define PI 3.14159
# define AREA R*R*PI
void main(void)
{ volume=4*PI*R*R*R /3;
cout<<"圆的面积="<<AREA<<endl;
cout<<"圆球体积="<<volume<<endl;
}
程序执行后输出:
圆的面积=113.097
圆球体积=904.778
程序在预编译头文件时,先判断是否定义过标识符_EX_ H,若没有定义过,则执行第2、3、4行语句,定义标识符_EX_ H,定义全局变量volume与宏名R,否则不执行2、3、4行语句。编译源文件时,同样先判断是否定义过标识符_EX_ H,若没有定义过,则执行第4、5、6行语句,定义标识符_EX_ H,定义全局变量volume与宏名R,否则不执行4、5、6行语句,不定义全局变量volume与宏名R。由于头文件先编译,所以在头文件中已定义了标识符_EX_ H、全局变量volume与宏名R,所以编译源文件时,#ifndef _EX_ H为假,不再重复定义全局变量volume与宏名R。避免变量重名产生的编译错误。这种用条件编译命令解决由多个用户编写多文件程序中出现变量重名问题是非常有效的。
另链接C语言编译全过程剖析:
http://www.yuanma.org/data/2009/0506/article_3647.htm
相关文章推荐
- qt的关于编译条件的一些定义问题
- 关于code::blocks的编译速度问题
- 关于OpenCV1.0的静态编译问题
- 关于模板的分离式编译问题
- 关于CC2540/2541编译Performing Post-Build Action卡住的问题
- 关于DNN模块独立编译,在DNN中调试的值得注意之问题
- 关于利用Dijkstra和DFS进行多条件选择路径问题范例
- 关于Mac os gradle 编译时报‘could not download gradle.jar…’的错误问题解决
- 关于unix下动态库编译、链接、加载的问题
- 关于jsp中条件页面跳转的问题
- 关于g++编译模板类的问题
- 关于Ubuntu编译Qt失败问题
- 关于windows 下sublime编译运行C中文不显示问题
- 关于vs编译后bin下的dll文件重新出现的问题
- 关于for循环条件性能问题
- 关于VC6编译LPDIRECT3D8不通过的问题
- 关于boost.regex库的编译问题(C/C++)
- 关于命令行中javac 编译成功,用 java 运行 class 文件出现 “ 找不到或无法加载主类 ” 的问题
- 关于mybatis中基本类型条件判断问题
- 关于webStorm设置less自动编译css和sourcemap问题