這兩天來忙活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