1. 程式人生 > >C和C++中經const修飾的常量、常變數和普通變數的區別

C和C++中經const修飾的常量、常變數和普通變數的區別

1.在C89標準下的const

const 修飾的型別是一個常變數,不能作為陣列的下標。常變數不能作為左值。

如:

const int a = 10;
int b = a;
//其編譯的過程和一般變數編譯的過程相同
//並不會把引用符號的地方替換為對應的資料

2.C++99

(1)常量:在c++中,const int a = 10是一個真真正正的常量。
(2)常變數:退化為常變數的情況,初始化為一個不明確的值。
(3)常變數和普通變數生成的符號的作用域不一樣。

int a = 10;
const int b = a;//在編譯階段不會進行運算

對比下面兩段程式碼,都是執行列印操作,但在本質上它們是有區別的。

//常變數
int a = 10;
const int b = a;
cout << b << endl;
mov eax,dword ptr[ebp-8]
push eax
//常量
const int b = 20;
cout << b << endl;
//cout其實也是函式呼叫,呼叫會壓引數。
//彙編程式碼
push 20

測試常量和普通變數所生成符號的作用域:

#include<iostream>
using namespace std;

int a = 10;//普通全域性變數
const int d = 20;//常量
int main()
{
    return
0; }

1.g++ test.cpp -c 生成test.o檔案
2.使用readelf -s test.o命令檢視編譯之後生成的符號表。
這裡寫圖片描述

由圖可見,普通變數生成的符號為GLOBAL,而經過const修飾的常量生成的符號是LOCAL。所以普通變數和常量作用域是不相同的。

3.要訪問另外一個檔案中定義的常量的方法。
在定義處新增extern關鍵字,使其程式設計後生成的符號為GLOBAL,這樣連結器就可以對其進行處理。

//簡單的測試一下,方法同上
#include<iostream>
using namespace std;
extern const int
a = 10; int mian() { return 0; } //g++ test.cpp -c -o test.o //readelf -s test.o

這裡寫圖片描述
可以看到,經過extern修飾的常量,進過編譯生成的符號表中其作用域變為GLOBAL