進化後的 const(二)

        我們之前說過在 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。我們看看編譯結果

圖片.png

        結果如我們所分析的那樣,因爲 c 雖然是由 const 修飾的,但其本質還是變量,所以我們可以通過指針來修改它的值。下來我們用 g++ 編譯器編譯下看看結果會一樣嗎?

圖片.png

        我們看到 c 爲 0,*p 爲 5。這就符合了我們之前講的,在 C++ 中,它會將由 const 修飾的變量放入符號表中,在後面見到它會直接在符號表中進行查找,但是 *p 確實改變了,所以 *p 爲 5。我們用下面這張圖來具體說明

圖片.png

        那麼在 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++ 編譯器編譯下是什麼結果圖片.png

        我們看到用 gcc 編譯器編譯直接報錯,但是我們用 g++ 編譯器編譯則通過,並且成功運行。我們再來看看 C++ 中的 const 常量和宏定義有什麼區別,我們在 f() 中分別定義了宏 a 和 const b,在 g() 中進行打印。我們之前說過,宏定義是沒有作用域的限制的,而 const 常量則是由作用域的,所以 b 的作用域僅爲 f 函數,在 g 中打印是會出錯的。我們去掉 main 函數中的第 28 行的註釋,看看是什麼結果

圖片.png

        我們看到它報的是 b 沒有定義。我們註釋掉第 12 行,再次編譯

圖片.png

        通過實驗,我們更加清晰的認識到宏定義和 const 常量的區別。通過對 C 和 C++ 中的 const 的學習,總結如下:1、與 C 語言不同,C++ 中的 const 不只是只讀變量;2、C++ 中的 const 是一個真正意義上的常量;3、C++ 編譯器可能會爲 const 常量分配空間;4、C++ 完全兼容 C 語言中的 const 常量的語法特性。


        歡迎大家一起來學習 C++ 語言,可以加我QQ:243343083

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章