1. 程式人生 > 程式設計 >C++ const關鍵字的例項用法

C++ const關鍵字的例項用法

C++中的const更像編譯階段的#define

const int m = 10;
int n = m;

變數是要佔用記憶體的,即使被const修飾也不例外。m,n兩個變數佔用不同的記憶體,int n = m;表示將m的值賦給n。

  • 在C語言中,編譯器會先到m所在的記憶體取出一份資料,再將這份資料賦給n;
  • 在C++中,編譯器會直接將10賦給m,沒有讀取記憶體的過程,和int n = 10效果一樣。
  • 在C++中的常量更類似於#define命令,是一個值替換的過程,只不過#define是在預處理階段替換,而常量是在編譯階段替換。

C++中的const

  • 優點:提高了程式執行效率
  • 缺點:不能反映記憶體的變化,一旦const變數被修改,C++就不能取得最新的值。

const變數禁止被修改 --- 只是語法層面上的限制,通過指標仍然可以修改。

#include <stdio.h>
int main(){
 const int n = 10;
 //注意:&n得到的指標的型別是const int*,必須強制轉換為int*後才能賦給p,否則型別是不相容的。 
 int *p = (int*)&n; //必須強制型別轉換
 *p = 99; //修改const變數的值
 printf("%d\n",n);
 return 0;
}
//以C語言的方式編譯,執行結果是99
//以C++的方式編譯,執行結果是10

//在C語言中,輸出n時會到記憶體中獲取n的值,這個時候n所在的記憶體中的資料已經被修改成了99
//在C++中,print("%d\n",n);語句在編譯時就將n的值替換成了10,不管n所在記憶體如何變化,都不影響輸出結果。 

C++中全域性const變數的可見範圍是當前檔案

普通全域性變數的作用域是當前檔案,但是在其他檔案中也是可見的,使用extern聲明後就可以使用。

/*原始檔1*/
#include <stdio.h>
#include"func.cpp"

int n = 10;
void func();
int main(){
func();
printf("main: %d\n",n);
return 0;
}
/*原始檔2*/
#include <stdio.h>

extern int;
void func();
{
printf("module: %d\n",n);
}
/*執行結果:*/
module:10
main:10

//在C語言中,const變數和普通變數一樣,在其他原始檔中也是可見的。
const int n = 10;

//在C語言中的const變數在多檔案編譯時的表現和普通變數一樣,除了不能修改,沒有其他區別。
//在C++中,修改後的程式碼是錯誤的。

C++規定全域性const變數的可見範圍僅限於當前原始檔,所以可以將它放在標頭檔案中,這樣即使標頭檔案被包含多次也不會出錯。

總結:

C++中的const變數雖然也會佔用記憶體,也能使用&獲取它的地址,但是使用時卻更像編譯時期的#define;
#define也是值替換,可見範圍也是當前檔案;
#define定義的常量僅僅是字串的替換,不會進行型別檢查,
而const定義的常量是有型別的,編譯器會進行型別檢查。

知識點補充

const修飾函式引數

const修飾引數是為了防止函式體內可能會修改引數原始物件。因此,有三種情況可討論:

  • 函式引數為值傳遞:值傳遞(pass-by-value)是傳遞一份引數的拷貝給函式,因此不論函式體程式碼如何執行,也只會修改拷貝而無法修改原始物件,這種情況不需要將引數宣告為const。
  • 函式引數為指標:指標傳遞(pass-by-pointer)只會進行淺拷貝,拷貝一份指標給函式,而不會拷貝一份原始物件。因此,給指標引數加上頂層const可以防止指標指向被篡改,加上底層const可以防止指向物件被篡改。
  • 函式引數為引用:引用傳遞(pass-by-reference)有一個很重要的作用,由於引用就是物件的一個別名,因此不需要拷貝物件,減小了開銷。這同時也導致可以通過修改引用直接修改原始物件(畢竟引用和原始物件其實是同一個東西),因此,大多數時候,推薦函式引數設定為pass-by-reference-to-const。給引用加上底層const,既可以減小拷貝開銷,又可以防止修改底層所引用的物件。

以上就是C++ const關鍵字的例項用法的詳細內容,更多關於C++ const關鍵字請關注我們其它相關文章!