我們之前說過在 C 語言中:const 修飾的變量是只讀的,其本質(zhì)還是變量;它修飾的局部變量在棧上分配空間,修飾的全局變量在只讀存儲(chǔ)區(qū)分配空間;const 只在編譯期有效,在運(yùn)行期無用;const 修飾的變量不是真的常量,它只是告訴編譯器該變量不能出現(xiàn)在賦值符號(hào)的左邊而已。
我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、貞豐ssl等。為上千余家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的貞豐網(wǎng)站制作公司
C 語言中的 const 使得變量具有只讀屬性,所以它在 C 語言中不能定義真正意義上的常量!在 C 語言中,能定義常量的只有 enum(枚舉)啦。但是 C++在 C 語言的基礎(chǔ)上對(duì) const 進(jìn)行了進(jìn)化處理:當(dāng)碰見 const 聲明時(shí)在符號(hào)表中放入常量;編譯過程中若發(fā)現(xiàn)使用常量則直接以符號(hào)表中的值替換;編譯過程中若發(fā)現(xiàn)下述情況則給對(duì)應(yīng)的常量分配存儲(chǔ)空間:a> 對(duì) const 常量使用了 extern,b> 對(duì) const 常量使用 & 操作符。符號(hào)表是編譯器中的一種數(shù)據(jù)結(jié)構(gòu)。C++ 編譯器雖然可能為 const 常量分配空間,但不會(huì)使用其存儲(chǔ)空間中的值。那為什么還有這樣做呢?是為了兼容 C 語言的特性!
下來我們以示例代碼為例進(jìn)行分析
#includeint main() { const int c = 0; int* p = (int*)&c; printf("Begin...\n"); *p = 5; printf("c = %d\n", c); printf("*p = %d\n", *p); printf("End...\n"); return 0; }
我們先在 gcc 編譯器編譯下,應(yīng)該是兩個(gè)都打印 5。我們看看編譯結(jié)果
結(jié)果如我們所分析的那樣,因?yàn)?c 雖然是由 const 修飾的,但其本質(zhì)還是變量,所以我們可以通過指針來修改它的值。下來我們用 g++ 編譯器編譯下看看結(jié)果會(huì)一樣嗎?
我們看到 c 為 0,*p 為 5。這就符合了我們之前講的,在 C++ 中,它會(huì)將由 const 修飾的變量放入符號(hào)表中,在后面見到它會(huì)直接在符號(hào)表中進(jìn)行查找,但是 *p 確實(shí)改變了,所以 *p 為 5。我們用下面這張圖來具體說明
那么在 C 語言中的 const 變量是只讀變量,會(huì)分配存儲(chǔ)空間;在 C++ 中,const 就為常量了,可能會(huì)為其分配空間:a> 當(dāng) const 常量為全局,并且需要在其他文件中使用時(shí);b> 當(dāng)使用 & 操作符對(duì) const 常量取地址;
在 C++ 中,const 常量有點(diǎn)就類似于宏定義了,但是它們是不一樣的。const 常量是由編譯器處理,編譯器對(duì) const 常量進(jìn)行類型檢查和作用域檢查;宏定義由預(yù)處理器處理,是單純的文本替換,并沒有作用域的限制。下來我們以代碼為例進(jìn)行分析
#includevoid f() { #define a 5 const int b = 3; } void g() { printf("a = %d\n", a); printf("b = %d\n", b); } int main() { const int A = 1; const int B = 2; int array[A + B] = {0}; int i = 0; for(i=0; i<(A + B); i++) { printf("array[%d] = %d\n", i, array[i]); } f(); //g(); return 0; }
我么看到在 main 函數(shù)定義了兩個(gè) const 修飾的變量,我們用它們的和來定義數(shù)組的大小。在 C 語言中肯定是不行的,因?yàn)樗鼈冊诒举|(zhì)上是變量,數(shù)組大小怎么可能用變量定義。但是在 C++ 中,它們就已經(jīng)被放入了符號(hào)表,就為常量了。我們來看看分別用 gcc 和 g++ 編譯器編譯下是什么結(jié)果
我們看到用 gcc 編譯器編譯直接報(bào)錯(cuò),但是我們用 g++ 編譯器編譯則通過,并且成功運(yùn)行。我們再來看看 C++ 中的 const 常量和宏定義有什么區(qū)別,我們在 f() 中分別定義了宏 a 和 const b,在 g() 中進(jìn)行打印。我們之前說過,宏定義是沒有作用域的限制的,而 const 常量則是由作用域的,所以 b 的作用域僅為 f 函數(shù),在 g 中打印是會(huì)出錯(cuò)的。我們?nèi)サ?main 函數(shù)中的第 28 行的注釋,看看是什么結(jié)果
我們看到它報(bào)的是 b 沒有定義。我們注釋掉第 12 行,再次編譯
通過實(shí)驗(yàn),我們更加清晰的認(rèn)識(shí)到宏定義和 const 常量的區(qū)別。通過對(duì) C 和 C++ 中的 const 的學(xué)習(xí),總結(jié)如下:1、與 C 語言不同,C++ 中的 const 不只是只讀變量;2、C++ 中的 const 是一個(gè)真正意義上的常量;3、C++ 編譯器可能會(huì)為 const 常量分配空間;4、C++ 完全兼容 C 語言中的 const 常量的語法特性。
歡迎大家一起來學(xué)習(xí) C++ 語言,可以加我QQ:243343083。