C 和 C 中全域性const變數的區別

2022-02-06 23:44:07 字數 2132 閱讀 4222

為研究在目前的c標準和c++標準中全域性const變數的區別,做了以下的測試:

(編譯器:gcc-4.7.2 ; 環境:32位ubuntu)

makefile:

makec:

g++ -x c test1.cpp test2.cpp -o test

./test

makecpp:

g++ -x c++ test1.cpp test2.cpp -o test

./test

測試0: 

test1.cpp

const int m;

int x;

#define print(x) printf(#x" = %d\n",x)

#include

int main()

test2.cpp

const int m = 2;

當執行make makec時編譯通過,輸出為:

m = 0

x = 0

當執行make makecpp時編譯不通過,報錯:

test1.cpp:1:11: error: uninitialized const 『m』 [-fpermissive]

結論:c中預設const全域性變數與其他的普通全域性變數都是預設初始化為0。

c++中預設const全域性變數是需要在定義的時候初始化的,否則編譯不通過。

測試1:

test1.cpp

extern const int m;

int x;

#define print(x) printf(#x" = %d\n",x)

#include

int main()

test2.cpp

const int m = 2;

當執行make makec時編譯通過,輸出為:

m = 2

x = 0

當執行make makecpp時編譯不通過,報錯:

test1.cpp:(.text+0xa): undefined reference to `m'

結論:c中預設const全域性變數是外部連線的。

c++中預設const全域性變數是內部鏈結的,即具有檔案作用域,檔案外不可見。

測試2:

test1.cpp

extern const int m;

int x;

#define print(x) printf(#x" = %d\n",x)

#include

int main()

test2.cpp

static const int m = 2;

當執行make makec時編譯不通過,報錯:

test1.cpp:(.text+0xa): undefined reference to `m'

當執行make makecpp時編譯不通過,報錯:

test1.cpp:(.text+0xa): undefined reference to `m'

結論:c++從c中繼承了static說明檔案作用域的特性。在這裡,static並不決定變數的儲存區(全域性變數都是儲存在全域性靜態資料區),而是決定了其檔案作用域,告知編譯器該變數是內部鏈結的。因為在c++中const預設是內部鏈結的,所以c++中定義全域性const int m = 2就相當於c中定義static const int m = 2

綜合結論:

在c中用const說明的全域性變數與普通的全域性變數,除了前者不能主動改變其值外,編譯器對其的處理方法都是一樣的,都是儲存在靜態全域性資料區,都是預設外部鏈結,都是預設初始化其記憶體塊為0。

在c++中用const說明的全域性變數與普通的全域性變數有很大的不同,除了前者不能改變其值外,const說明的全域性變數是預設內部鏈結的,而且沒有預設初始化,要求程式設計師在定義的同時給出初始化的值。這樣的特性其實更加嚴謹,因為內部鏈結(相當於c中的static)可以防止重名,而常量的定義同時初始化在邏輯上也更合理。

C 靜態變數 全域性變數 const

全域性陣列 不能被delete 作用域 區分名字的不同意義的上下文。c 中大多數作用域是用花括號界定的,名字從其宣告點到宣告所在作用域結束處都是可見的。include int main int sum 0 for int val 1 val 10 val sum return 1 名字main在花括...

C 中Const常量和ReadOnly的區別總結

複習基礎知識的時候,看到了readonly這裡,被書裡說的感覺忘了和const有什麼區別了,索性今天就總結一下,以便於後續的學習。一 常量const 1.宣告時必須初始化值 2.宣告後值不能改變 3.編譯時決定 4.通常是簡單型別或由簡單型別組成的表示式做初始化語句,也可以是null引用,但是不能是...

const 和全域性變數

c 中,全域性變數的儲存都是靜態儲存。但是鏈結性質可以有外部鏈結和內部鏈結。預設情況下是外部鏈結,如果在定義前加上 static 則變為內部鏈結。如果 int val1 5 加上static 則編譯失敗。但是如果是用const 呢。變成 const int val1 5 會如何呢,答案是,也編譯失敗...