C語言中const和#define的區別

程式像女孩子一樣發表於2016-09-01

轉載一

const是constant的縮寫,是亙古不變的意思,也翻譯為常數,常量等。但是認為被const修飾的詞是常量的認識是不正確的,精確的說是隻讀變數,其值在編譯時是不能被使用的。

const是關鍵字而define不是。

 

const與define的用法

 

其區別舉個例子說明吧。。。
如果是#define AAA 3+5
那麼表示式2*AAA*3就相當於2*3+5*3,結果是6+15=21
如果是const int AAA = 3+5
那麼表示式2*AAA*3就相當於2*8*3,結果是48

 

const變數還是常量


為什麼我像下面的例子一樣用一個const變數來初始化陣列,ANSIC的編譯器會報告一個錯誤呢?

const int n = 5;
int a[n];

 

答案與分析:

  1)、這個問題討論的是“常量”與“只讀變數”的區別。常量肯定是隻讀的,例如5,“abc”,等,肯定是隻讀的,因

為程式中根本沒有地方存放它的值,當然也就不能夠去修改它。而“只讀變數”則是在記憶體中開闢一個地方來存放它的

值,只不過這個值由編譯器限定不允許被修改。C語言關鍵字const就是用來限定一個變數不允許被改變的修飾符

(Qualifier)。上述程式碼中變數n被修飾為只讀變數,可惜再怎麼修飾也不是常量。而ANSIC規定陣列定義時維度必須

是“常量”,“只讀變數”也是不可以的。

  2)、注意:在ANSIC中,這種寫法是錯誤的,因為陣列的大小應該是個常量,而const int n,n只是一個變數(常量

 !=不可變的變數,但在標準C++中,這樣定義的是一個常量,這種寫法是對的),實際上,根據編譯過程及記憶體分配

來看,這種用法本來就應該是合理的,只是ANSIC對陣列的規定限制了它。

  3)、那麼,在ANSI C語言中用什麼來定義常量呢?答案是enum型別和#define巨集,這兩個都可以用來定義常量。

 

const 限定的內容

 

下面的程式碼編譯器會報一個錯誤,請問,哪一個語句是錯誤的呢?

typedef char * pstr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
  答案與分析:

  問題出在p2++上。

  1)、const使用的基本形式: const char m;

  限定m不可變。

  2)、替換1)式中的m, const char *pm;

  限定*pm不可變,當然pm是可變的,因此問題中p1++是對的。

  3)、替換1)式char, const newType m;

  限定m不可變,問題中的pstr就是一種新型別,因此問題中p2不可變,p2++是錯誤的。

轉載二

1、define是在編譯的預處理階段起作用,而const是在 編譯、執行的時候起作用。

2、define只是簡單的字串替換,沒有型別檢查。而const有對應的資料型別,是要進行判斷的。
3、儲存方式不同 
define僅僅是一個巨集,哪裡使用,就在哪裡展開,不佔用記憶體。 
const 常量會在記憶體中分配記憶體
總體來說const有一下有點: 
(1)const常量可以進行型別檢查,避免一些低階的錯誤 
(2)在我們除錯的時候,const常量可以進行除錯的,但是define是不能進行除錯的,因為在預編譯階段就已經替換掉了
原創三
int main()
{
	int a[N];//#define可以
	//printf("%d",&N); //編譯出錯,因為這種常量是由編譯器放在常量區,沒有地址,無從修改
	
	const int num=10; //此時num是可變的常量,可以強制去掉常量屬性
	//num=12;//不可以,在記憶體中可以修改(const主要涉及許可權問題:
			//限定程式碼不能修改,在記憶體中有實體,是可以變得數)
	printf("%d",&num);
	//int b[N];//這樣不可以
	
	return 0;
}
總結兩者的本質區別:#define定義的常量在任何情況都不能修改;而const限定的可變常量自己的程式碼不能修改,但在記憶體中可變,指標也可以

相關文章