<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    注銷

    注銷

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      112 隨筆 :: 7 文章 :: 18 評論 :: 0 Trackbacks
    從語句 char* p="test" 說起
    ?
    陳皓
    ?
    ?
    我相信,使用 C/C++ 多年的人對下面這個字符串賦值語句都不會陌生吧。
    ?
    ????????????? char* p = “anything”;
    ?
    同時,我也相信,各位在使用這種語句后吃過很多苦頭也不少吧?只要你想利用指針 p 來改變字符串的內(nèi)容,你的程序都會到一個讓你顏面盡失一個內(nèi)存非法操作。比如,下面的這些語句:
    ?
    ????????????? p[0] = ‘s’;
    ????????????? strcpy(p, “haoel”);
    ?
    原因就在于, char* p = “hello world”; 這個聲明,聲明了一個指針,而這個指針指向的是全局的 const 內(nèi)存區(qū) const 內(nèi)存區(qū)當(dāng)然不會讓你想改就改的。所以,如果你一定要寫這塊內(nèi)存的話,那就是一個非常嚴(yán)重的內(nèi)存錯誤。另,之所以加粗“全局 const 內(nèi)存區(qū)”,是強(qiáng)調(diào)一下,如果你不信的話,你可以試試下面這段代碼,看看 p1 p2 的地址是不是一樣的。
    ?
    ????????????? char* p1 = “anything”;
    ????????????? char* p2 = “anything”;
    ????????????? printf(“ p1=%x, p2=%x \n”, p1, p2);
    ?
    我想這應(yīng)該是一個眾所周知的問題吧。取而代之的,應(yīng)該是使用數(shù)組來做聲明。如: char str[] = “hello world”; 如果現(xiàn)在還有哪本書中的 C 的示例采用了這種方式,那么你就可以把那本書撕了,如果這本書是 C++ 的書話,那么你應(yīng)該把這個作者和這個出版社告上法庭,因為你不應(yīng)該容忍這種學(xué)術(shù)騙子。如果你的部門的開發(fā)人員還有人寫出這種代碼的話,如果他是 C 程序員,我想你可以在打過他的屁股后告訴他下不為例,如果他是一個 C++ 程序員的話,我想你可以懷疑他是否有資格做一個 C++ 程序員了。
    ?
    ?????? 至于你問我為什么要對學(xué) C++ 的人那么苛刻,那是因為學(xué)過 C++ 的人都知道 C++ 中的 const 關(guān)鍵字的有著什么樣的權(quán)力,你也應(yīng)該知道 C++ const 有著無比的照顧和關(guān)愛,幾乎所有關(guān)于 C++ 的書都會提到 const 這東西。所以,如果作為一個 C++ 的程序員來說,如果你不知道的話,那就太說不過去了。
    ?
    ?????? 我們知道,雙引號引起來的字符串是 const 的,所以,在 C++ 的世界中,你應(yīng)該進(jìn)行如下的聲明才比較穩(wěn)妥:
    ?????????????
    ????????????? const char *p = “anything”;
    ?
    這樣,當(dāng)你修改這個字符串的內(nèi)容時,編譯器會給你一個錯誤而導(dǎo)致你的程序編譯不通過,從而不會產(chǎn)生運行時的內(nèi)存錯誤。
    ?
    ?????? 可問題是,像 C++ 這種對類型要求很嚴(yán)格的語言來說,為什么它在編譯諸如 char *p=”anything” 程序的時候不出錯,甚至連個警告都沒有( g++ vc++7 )?難道這是他的一個 bug ?我想,這應(yīng)該是對古老的 C 的一個向下兼容。因為,在 C 的世界中,這種用法太多了。
    ?
    C++ 中,比如:函數(shù)的參數(shù)和異常的捕獲都存在這種問題,如下所示:(因編譯器而定,在 gcc 3.4.3 版中,下例中的異常示例不能被捕獲,但 VC++6 中卻可以被捕獲)
    ?
    ?????? func( char* p) { }?? // 以這種方式調(diào)用函數(shù) func(“abc”);
    ??????
    ?????? try { thow “exception”; } catch (char* p) { }
    ?
    ?????? 這些東西,無疑會對大家是一個誤導(dǎo)。甚至讓人無所畏懼地走入其中,并自以為走入了正途。這樣看來,這種向下兼容的 C++ 標(biāo)準(zhǔn),就顯得有點誤人不淺了
    ?
    ?????? 不過好在, C++ 標(biāo)準(zhǔn)委員會早已意識到了這一點。這個 C++ feature 被定義為了“ Deprecated Feature ”,即“不被建議使用的特性”。意思就是,在將來,這種特性將被從 C++ 中移出,于是,你目前的這種程序?qū)o法在新的 C++ 編譯器上編譯通過。對于程序的可移植性來說,我們今天所寫的代碼尤其要注意這些“ Deprecated Feature ”。
    ?
    ?????? 據(jù)我所知,目前 C++ 中被列為“ Deprecated Feature ”如下所示(可能不準(zhǔn)確,請大家指正)
    ?
    一、?????????? 隱晦的字符串的 const 轉(zhuǎn)換。

    char *p = “test”;
    w_char *pw = “test”;
    char p[] = “test”;
    ?????? 把一個 const 的字符串類型轉(zhuǎn)成 non-const 的。包括指針和數(shù)組。
    ?
    二、?????????? 隱晦的類型聲明。

    func() {}?? // 函數(shù)的隱晦返回類型是 int
    static num;??? // 變量的隱晦類型是 int
    ?????? 這種 feature C89 中還可以使用,但在 C99 C++ 中都被去除了。( gcc 3.4 版本對于這種聲明會給出編譯錯誤,而 VC++6.0 會認(rèn)為這是合法的程序)
    ?
    三、?????????? 布爾變量的累加操作。
    bool isConn = false;
    isConn++; ???????? // 這個操作會把 isConn 變?yōu)?/span> true
    就目前而言,幾乎所有的編譯器都認(rèn)可這種操作,但這種用法也是不被建議的,終有一天會被取消。
    ?
    四、?????????? 更改父類成員的存取權(quán)限。
    ?
    class B
    {
    ??? protected:
    ??????? int i;
    };
    ?
    class D : public B
    {
    ???? public:
    ??????? int i;
    };
    ?
    ?????? 對于這種語法,一般來說,編譯器會把了類中的那個重復(fù)的變量認(rèn)為成兩份。
    也就是說,父類的和子類的各是各的。這個 feature 對于所有的編譯器來說應(yīng)該都是可以編譯通過的(連個 Warning 都沒有)。但這個 feature 也是要被廢除的。
    ?
    五、?????????? 文件中域的 static 聲明
    ?
    static int i;
    static void func()
    ?
    ?????? 據(jù)說,這種舊的在 C 中的為了實現(xiàn)其作用域在本文件中的 feature 在未來的 C++ 中也要被取消。
    ?
    ?
    文章到這里應(yīng)該結(jié)束了,在結(jié)束之前,讓我再給大家共享一個有趣的關(guān)于 const 的例子(在網(wǎng)上看到的)
    ?
    ??? const int a = 1;
    ??? int *p = const_cast<int*>(&a);
    ??? *p = 2;
    ?
    ??? cout << “value a=”<< a << endl;
    ??? cout << “value *p=” <<*p << endl;
    ??? cout << “address a=” <<&a << endl;
    ??? cout << “address p=” <<p << endl;
    這段代碼輸出的結(jié)果如下:
    ?
    value a=1
    value *p=2
    address a=0xbff1d48c
    address p=0xbff1d48c
    ?
    地址都是一樣的,可值為什么不一樣呢?呵呵。這個問題看起來有點“學(xué)術(shù)味”過濃,不過是個好例子,可以讓你知道 C++ 的一些用法和一些原理。有以下幾個方面大家可以考慮一下:
    1) const int a = 1 是不是和宏有點像,會不會被編譯器優(yōu)化了?
    2) 去修改一個 const 的值,本來應(yīng)該是不對的。這可能會是向舊的 C 兼容。是否會讓編譯器產(chǎn)生未知行為?
    ?
    所以,這個示例也告訴我們,我們應(yīng)該遵循 C++ 中的 const non-const 的語義,任何想要破壞這個語義的事情都會給我們帶來未知的結(jié)果。
    posted on 2006-11-19 10:50 注銷..... 閱讀(431) 評論(0)  編輯  收藏 所屬分類: c++
    主站蜘蛛池模板: 亚洲成av人片天堂网| 一二三区免费视频| 久久水蜜桃亚洲av无码精品麻豆 | 亚洲午夜精品一区二区麻豆| 亚洲V无码一区二区三区四区观看 亚洲αv久久久噜噜噜噜噜 | 久草视频免费在线| 免费人成视频在线| 特级无码毛片免费视频尤物| selaoban在线视频免费精品| 久久亚洲色WWW成人欧美| 亚洲不卡中文字幕| 亚洲黄色网址大全| 亚洲男人的天堂在线播放| 亚洲日韩中文无码久久| 亚洲欧洲一区二区三区| 免费少妇a级毛片| 在线a毛片免费视频观看| 国产福利在线免费| 免费国产成人高清在线观看网站 | 久久亚洲精品成人无码网站| 亚洲成AV人片在WWW色猫咪 | 污视频在线观看免费| 你懂得的在线观看免费视频| 国产乱子伦精品免费视频| 日韩精品无码永久免费网站| 理论片在线观看免费| 欧洲亚洲综合一区二区三区 | 无码人妻丰满熟妇区免费| 国内精品一级毛片免费看| a级毛片在线免费| 国产猛男猛女超爽免费视频| 波多野结衣免费一区视频| 暖暖免费日本在线中文| 97人妻精品全国免费视频 | 亚洲精品无码永久在线观看你懂的 | 国产成人无码综合亚洲日韩| 国产V亚洲V天堂无码久久久| 亚洲AV无码不卡在线播放| 亚洲日韩区在线电影| 亚洲理论片中文字幕电影| 亚洲一区二区三区久久久久|