C++中的const正常情況下是看成編譯期的常量,編譯器並不為const分配空間,只是在編譯的時候將期值儲存在名字表中,並在適當的時候摺合在代碼中.所以,以下代碼:
#include using namespace std;int main(){ const int a = 1; const int b = 2; int array[ a + b ] = {0}; for (int i = 0; i < sizeof array / sizeof *array; i++) { cout << array << endl; } return 0;}
在可以通過編譯,並且正常運行.但稍加修改後,放在C編譯器中,便會出現錯誤:
#include int main(){ int i; const int a = 1; const int b = 2; int array[ a + b ] = {0}; for (i = 0; i < sizeof array / sizeof *array; i++) {printf("%d",array); } return 0;}
錯誤訊息:
c:\test1\te.c(8): error C2057: 應輸入常數運算式
c:\test1\te.c(8): error C2466: 不能分配常數大小為 0 的數組
出現這種情況的原因是:
在C中,const是一個不能被改變的普通變數,既然是變數,就要佔用儲存空間,所以編譯器不知道編譯時間的值.而且,數組定義時的下標必須為常量.
在C語言中:
const int size;
這個語句是正確的,因為它被C編譯器看作一個聲明,指明在別的地方分配儲存空間.但在C++中這樣寫是不正確的.C++中const預設是內部串連,如果想在C++中達到以上的效果,必須要用extern關鍵字.
C++中,const預設使用內部串連.而C中使用外部串連.
內串連:編譯器只對正被編譯的檔案建立儲存空間,別的檔案可以使用相同的表示符
或全域變數.C/C++中內串連使用static關鍵字指定.
外串連:所有被編譯過的檔案建立一片單獨儲存空間.一旦空間被建立,連接器必須解
決對這片儲存空間的引用.全域變數和函數使用外部串連.通過extern關鍵
字聲明,可以從其他檔案訪問相應的變數和函數.
/************************C++代碼******************************/ //header.h const int test = 1;
//test1.cpp #include #include "header.h" using namespace std; int main() { cout << "in test1 :" << test << endl; return 0; } //test2.cpp #include #include "header.h" using namespace std; void print() { cout << "in test2:" << test << endl; }
以上代碼編譯串連完全不會出問題,但如果把header.h改為:
extern const int test = 1;
在串連的時候,便會出現以下錯誤資訊:
test2 error LNK2005: "int const test" (?test@@3HB) 已經在 test1.obj 中定義
因為extern關鍵字告訴C++編譯器test會在其他地方引用,所以,C++編譯器就會為test建立儲存空間,不再是簡單的儲存在名字表裡面.所以,當兩個檔案同時包含header.h的時候,會發生名字上的衝突.
此種情況和C中const含義相似:
//header.h const int test = 1; //test1.c #include #include "header.h" int main() { printf("in test1:%d\n",test); return 0; } //test2.c #include #include "header.h" void print() { printf("in test2:%d\n",test); }
錯誤訊息:
test3 fatal error LNK1169: 找到一個或多個多重定義的符號
test3 error LNK2005: _test 已經在 test1.obj 中定義
C++中,是否為const分配空間要看具體情況.
如果加上關鍵字extern或者取const變數地址,則編譯器就要為const分配儲存空間.
C++中定義常量的時候不再採用define,因為define只做簡單的宏替換,並不提供類型檢查.