天天看點

C語言const與define的使用

const是一個C語言的關鍵字,它限定一個變量不允許被改變。使用const在一定程度上可以提高程式的健壯性,另外,在觀看别人代碼的時候,清晰了解const所起的作用,對了解對方的程式也有一些幫助。  雖然這聽起來很簡單,但實際上,const的使用也是c語言中一個比較微妙的地方,微妙在何處呢?請看下面幾個問題。

  問題:const變量 & 常量

  為什麼我象下面的例子一樣用一個const變量來初始化數組,ANSI C的編譯器會報告一個錯誤呢?

const int n = 5;

int a[n];

  答案與分析:

  1)、這個問題讨論的是“常量”與“隻讀變量”的差別。常量肯定是隻讀的,例如5,

“abc”,等,肯定是隻讀的,因為程式中根本沒有地方存放它的值,當然也就不能夠去修改它。而“隻讀變量”則是在記憶體中開辟一個地方來存放它的值,隻不過這個值由編譯器限定不允許被修改。C語言關鍵字const就是用來限定一個變量不允許被改變的修飾符(Qualifier)。上述代碼中變量n被修飾為隻讀變量,可惜再怎麼修飾也不是常量。而ANSI

C規定數組定義時次元必須是“常量”,“隻讀變量”也是不可以的。

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

!=

不可變的變量,但在标準C++中,這樣定義的是一個常量,這種寫法是對的),實際上,根據編譯過程及記憶體配置設定來看,這種用法本來就應該是合理的,隻是ANSI

C對數組的規定限制了它。

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

  問題:const變量 & 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不可變,問題中的charptr就是一種新類型,是以問題中p2不可變,p2++是錯誤的。

  問題:const變量 & 字元串常量

  請問下面的代碼有什麼問題?

char *p = "i‘m hungry!";

p[0]= ‘I‘;

  上面的代碼可能會造成記憶體的非法寫操作。分析如下, “i‘m

hungry”實質上是字元串常量,而常量往往被編譯器放在隻讀的記憶體區,不可寫。p初始指向這個隻讀的記憶體區,而p[0] =

‘I‘則企圖去寫這個地方,編譯器當然不會答應。

  問題:const變量 & 字元串常量2

  請問char a[3] = "abc" 合法嗎?使用它有什麼隐患?

  在标準C中這是合法的,但是它的生存環境非常狹小;它定義一個大小為3的數組,初始化為“abc”,,注意,它沒有通常的字元串終止符‘

define和const的差別!

1.const定義常量是有資料類型的,而#define宏定義常量卻沒有,一是const有類型;二是const可以有不同的作用域。

2.const常量有資料類型,而宏常量沒有資料類型。編譯器可以對const進行類型安全檢查,

   而對後者隻進行字元替換,沒有類型安全檢查,并且在字元替換中可能會産生意料不到的錯誤

3.有些內建化的調試工具可以對const常量進行調試,但是不能對宏常量進行調試。

問題?

1.還有其他的劣勢麼,是什麼導緻c++要求用const取代#define,有參考文檔麼?原理?

2.既然有這樣那樣的劣勢,c為什麼不要求用const取代#define?

3.#define的優勢是是什麼?

4.const的劣勢是什麼?

第三問:define不僅是定義常量,還可以定義帶參數的宏,做到一定程度的泛型(利用#或者##操作符)。

引用樓主 ch_tei_hyou 的回複:

無論是const還是#define,都是幫助編譯器/預處理器 來生成可執行程式的。

用const引入資料類型後,可以幫助編譯器識别資料的“屬性”,這對編譯器是非常重要的

有興趣的話可以簡單看一下編譯原理。

#define是預處理階段的工作,和編譯器無關了。

要知道,一門語言是有标準的,而且要求标準的穩定。如果在C中加入太多的C++特性,将會

導緻C編譯器前端過于龐大,這就喪失了C的一些優勢。

如果C還有存在的道理,保持自己的簡潔、小巧是必須的。

C标準委員會沒有接納這1點,很遺憾。

從寫編譯器的角度講,最大的優勢是簡單。因為預處理就可以解決掉#define,

不必讓編譯器來處理這個。

從應用上講,#define也是不可或缺的。因為它可以讓寫代碼的人體會到友善性。

const與#define最大的差别在于:前者在堆棧配置設定了空間,而後者隻是把具體數值直接傳遞到目标變量罷了(存儲到字元串清單,沒有配置設定具體的空間,直接在預編譯階段直接進行替代) define是應用于預處理的,而const是在編譯的時候處理的.

在程式語句中使用的常量的地方, 最好是使用const定義,在這方面來說, const隻有優勢,沒有劣勢.如果要說const劣勢的地方,那就是它不能做上面3中的define的需要在預處理的時候做的事情.其實,這并非它的劣勢,而隻是不是它所要擔負的工作罷了.