大家可能都很習慣用類似const char *這種東西了,在傳遞C-style字串時經常會用到,用意是不要更改到字串內容。不過其實在多層指標時,因應const的位置,狀況還可以更複雜。
首先必需要有的概念是,
舉例:
const TYPE
和TYPE const
是等義的。舉例:
const int a = 1; // a的值永遠為1 int const b = 2; // b的值永遠為2 const int const c = 3; // 編譯期錯誤,冗餘的cv修飾飼
第二個觀念是,cv修飾詞修飾的是它左邊的型別。
如果它本來就在最左邊,可以用上面的規則代換成
舉例:
如果它本來就在最左邊,可以用上面的規則代換成
TYPE const
。舉例:
int x = 4; int y = 5; const int * cip = &x; // 指向const的指標 int const * icp = &x; // 如前段所述,icp和cip其實是同一種型別 int * const ipc = &x; // 因為const的左邊是pointer,故它其實是const指標 *cip += y; // 失敗,因為指向的空間被修飾為const *icp += y; // 失敗,理由同上 *ipc += y; // 正確,指向的空間並沒有被修飾為const cip = &y; // 正確,指標本身並不是const icp = &y; // 正確,理由同上 ipc = &y; // 失敗,指標本身是const當然也可以合起來宣告成
int const * const icpc
,這樣指標本身不能更改,其指向的空間也不能更動。
最後一個,在指標有多層的時候,解析是由右往左展開。這個比較複雜一點,一樣還是舉例比較快:
const char * const * argv; const char * test = "Hello, world!"; const char * const temp[] = { "abc", NULL }; argv = temp; // 正確,最右邊的*沒有cv修飾,因此最上層的argv可以更改為其他指標 argv[0] = test; // 失敗,右邊第二個*有cv修飾,所以*argv的取值是不能更改的 argv[0][0] = 'd'; // 失敗,最後的char也加了const,是故陣列中的字元不能更改
以下是小應用:
int EXECVP_POSIX( const std::vector< std::string > & args ) { const char * * argv = new const char * [ args.size() + 1 ]; for( size_t i = 0; i < args.size(); ++i ) { argv[i] = args[i].c_str(); } argv[args.size()] = NULL; return execvp( argv[0], argv ); }用意是把vector<string>轉為系統函式通用的const char * const *。
> const char * argv[args.size()+1];
回覆刪除C++ 的 array bound 必須是 constant-expression (C++98 8.3.4)
那時好像是"某些編譯器"會過
回覆刪除不過VC確實不會過就是了