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的需要在預處理的時候做的事情.其實,這并非它的劣勢,而隻是不是它所要擔負的工作罷了.