C/C++中define定義的常量與const常量

  常量是在程序中不能更改的量,在C/C++中有兩種方式定義常量,一種是利用define宏定義的方式,一種是C++中新提出來的const型常變量,下面主要討論它們之間的相關問題;安全

  define定義的常量:spa

  define是預處理指令的一種,它用來定義宏,宏只是一個簡單的替換,將宏變量所對應的值替換,以下面的代碼:code

#define NUM 2
int main()
{
    printf("%d", NUM);
}

編譯器在編譯時處理的並非這樣的代碼,編譯器會首先處理預處理指令,根據預處理指令生成相關的代碼文件,而後編譯這個文件,獲得相關的.obj文件,最後經過連接相關的.obj文件獲得一個可執行文件,最典型的是咱們通常在.cpp文件中寫的#include指令,在處理時首先將所需包含的頭文件整個拷貝到這個.cpp文件中,並替換這個#include指令,而後再編譯生成的文件,這個中間文件在Windows中後綴爲.i,在Visual C++ 6.0中以此點擊Project-->Settings-->C/C++,在Project Options最後一行加上'/P'(P爲大寫)這樣在點擊編譯按鈕時不會編譯生成obj文件,只會生成.i文件,經過這個.i文件能夠看到在作預處理的時候會將 NUM替換成2而後在作編譯處理,這個時候點擊生成時會出錯,由於咱們將編譯選項修改後沒有生成.obj文件可是在生成時須要這個文件,所以會報錯,因此在生成時要去掉這個/P選項。而咱們看到在使用const 定義的時候並無這個替換的操做,與使用正常的變量無異。const型變量只是在語法層面上限定這個變量的值不能夠修改,咱們能夠經過強制類型轉化或者經過內嵌彙編的形式修改這個變量的值,好比下面的代碼:blog

int main(int argc, char* argv[])
{
    const nNum = 10;
    int *pNum = (int*)&nNum;
    printf("%d\n", nNum);
    return 0;
}
    const nNum = 10;
    __asm
    {
        mov [ebp - 4], 10
    }
    printf("%d\n", nNum);
    return 0;

可是咱們看到,這兩種方式修改後,輸出的值仍然是10,這個緣由咱們能夠經過查看反彙編代碼查看內存

;printf("%d\n", nNum);
00401036   push        0Ah
00401038   push        offset string "%d\n" (0042001c)
0040103D   call        printf (00401070)
00401042   add         esp,8

在調用printf的時候,入棧的參數是10,根本沒有取nNum值得相關操做,在利用const定義的常量時,編譯器認爲既然這是一個常量,應該不會修改,爲了提高效率,在使用時並不會去對應的內存中尋址,而是直接將它替換爲初始化時的值,爲了防止這種事情的發生,能夠利用C++中的關鍵字:volatile。這個關鍵字保證每次在使用變量時都去內存中讀取。編譯器

咱們能夠總結出const和define的幾個不一樣之處:string

1)define是一個預處理指令,const是一個關鍵字。io

2)define定義的常量編譯器不會進行任何檢查,const定義的常量編譯器會進行類型檢查,相對來講比define更安全asm

3)define的宏在使用時是替換不佔內存,而const則是一個變量,佔內存空間編譯

4)define定義的宏在代碼段中不可尋址,const定義的常量是能夠尋址的,在數據段或者棧段中。

5)define定義的宏在編譯前的預處理操做時進行替換,而const定義變量是在編譯時決定

6)define定義的宏是真實的常量,不會被修改,const定義的其實是一個變量,能夠經過相關的手段進行修改。

相關文章
相關標籤/搜索