TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2008年1月4日 星期五

pointer和cv修飾詞

大家可能都很習慣用類似const char *這種東西了,在傳遞C-style字串時經常會用到,用意是不要更改到字串內容。不過其實在多層指標時,因應const的位置,狀況還可以更複雜。
首先必需要有的概念是,const TYPETYPE 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 *。
Edited: 2008/07/22
修正code。
事實上如這篇所述,POSIX的prototype是怪怪的。

2 則留言:

  1. > const char * argv[args.size()+1];

    C++ 的 array bound 必須是 constant-expression (C++98 8.3.4)

    回覆刪除
  2. 那時好像是"某些編譯器"會過
    不過VC確實不會過就是了

    回覆刪除