您好,登錄后才能下訂單哦!
我們之前說過在 C 語言中:const 修飾的變量是只讀的,其本質還是變量;它修飾的局部變量在棧上分配空間,修飾的全局變量在只讀存儲區分配空間;const 只在編譯期有效,在運行期無用;const 修飾的變量不是真的常量,它只是告訴編譯器該變量不能出現在賦值符號的左邊而已。
C 語言中的 const 使得變量具有只讀屬性,所以它在 C 語言中不能定義真正意義上的常量!在 C 語言中,能定義常量的只有 enum(枚舉)啦。但是 C++ 在 C 語言的基礎上對 const 進行了進化處理:當碰見 const 聲明時在符號表中放入常量;編譯過程中若發現使用常量則直接以符號表中的值替換;編譯過程中若發現下述情況則給對應的常量分配存儲空間:a> 對 const 常量使用了 extern,b> 對 const 常量使用 & 操作符。符號表是編譯器中的一種數據結構。C++ 編譯器雖然可能為 const 常量分配空間,但不會使用其存儲空間中的值。那為什么還有這樣做呢?是為了兼容 C 語言的特性!
下來我們以示例代碼為例進行分析
#include <stdio.h> int 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 編譯器編譯下,應該是兩個都打印 5。我們看看編譯結果
結果如我們所分析的那樣,因為 c 雖然是由 const 修飾的,但其本質還是變量,所以我們可以通過指針來修改它的值。下來我們用 g++ 編譯器編譯下看看結果會一樣嗎?
我們看到 c 為 0,*p 為 5。這就符合了我們之前講的,在 C++ 中,它會將由 const 修飾的變量放入符號表中,在后面見到它會直接在符號表中進行查找,但是 *p 確實改變了,所以 *p 為 5。我們用下面這張圖來具體說明
那么在 C 語言中的 const 變量是只讀變量,會分配存儲空間;在 C++ 中,const 就為常量了,可能會為其分配空間:a> 當 const 常量為全局,并且需要在其他文件中使用時;b> 當使用 & 操作符對 const 常量取地址;
在 C++ 中,const 常量有點就類似于宏定義了,但是它們是不一樣的。const 常量是由編譯器處理,編譯器對 const 常量進行類型檢查和作用域檢查;宏定義由預處理器處理,是單純的文本替換,并沒有作用域的限制。下來我們以代碼為例進行分析
#include <stdio.h> void 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 函數定義了兩個 const 修飾的變量,我們用它們的和來定義數組的大小。在 C 語言中肯定是不行的,因為它們在本質上是變量,數組大小怎么可能用變量定義。但是在 C++ 中,它們就已經被放入了符號表,就為常量了。我們來看看分別用 gcc 和 g++ 編譯器編譯下是什么結果
我們看到用 gcc 編譯器編譯直接報錯,但是我們用 g++ 編譯器編譯則通過,并且成功運行。我們再來看看 C++ 中的 const 常量和宏定義有什么區別,我們在 f() 中分別定義了宏 a 和 const b,在 g() 中進行打印。我們之前說過,宏定義是沒有作用域的限制的,而 const 常量則是由作用域的,所以 b 的作用域僅為 f 函數,在 g 中打印是會出錯的。我們去掉 main 函數中的第 28 行的注釋,看看是什么結果
我們看到它報的是 b 沒有定義。我們注釋掉第 12 行,再次編譯
通過實驗,我們更加清晰的認識到宏定義和 const 常量的區別。通過對 C 和 C++ 中的 const 的學習,總結如下:1、與 C 語言不同,C++ 中的 const 不只是只讀變量;2、C++ 中的 const 是一個真正意義上的常量;3、C++ 編譯器可能會為 const 常量分配空間;4、C++ 完全兼容 C 語言中的 const 常量的語法特性。
歡迎大家一起來學習 C++ 語言,可以加我QQ:243343083。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。