線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:971
推到 Plurk!
推到 Facebook!

關於常字串的疑惑(BCB和VC的結果不同)

答題得分者是:justdo
fusung
中階會員


發表:26
回覆:169
積分:99
註冊:2003-11-25

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-01-20 15:03:45 IP:61.222.xxx.xxx 未訂閱
以下是我從書上(http://delphi.ktop.com.tw/topic.php?TOPIC_ID=63691) p.167看到的:
引言:一個字元指標指到一常字串(string literal),在C 中字串內的資料是固定不變的,不能在程式執行中被改變,因此以下的方式是錯誤的: char *foo = "fish"; foo[0] = 'F'; //錯誤
  • (疑惑1) 於是我分別在BCB 6.0和VC 6.0下做測試,發現結果竟然不同: BCB 6.0 原始碼如下:
     
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    char *foo = "fish";
    Form1->Caption = foo;
    Sleep(1000);
    foo[0] = 'F';                    // 為什麼BCB會接受??
    Form1->Caption = foo;
    }
    
    而VC 6.0的原始碼如下:
    int main(void)
    {
            char *foo = "fish";
            cout << foo << endl;
            foo[0] = 'F';          //VC會出現錯誤 0xC0000005: Access Violation
            cout << foo << endl;
            system("pause");
            return 0;
    }
    
    請問為什麼會發生這樣的情況呢? 是不是BCB認為這是合法的?
  • (疑惑2) 此外既然書上寫到:字元指標指到一個常字串為何不乾脆在宣告的時候加一個const更明確呢? 我的意思是:
     
    const char *foo = "fish";
    foo[0] ='F';                    //這樣一來不管BCB或VC  都可以偵測到錯誤  
    
  • (疑惑3) 之後書上又舉了另一個例子
     
    char foo[] = "fish";
    foo[0] = 'F';                   //BCB或VC  都可以正常compile         
    
    請問既然"fish"是字串(string literal),應該不管誰(字元指標或字元陣列)都撼動不 了它才對啊!!還是說string literal 不應該翻做字串(因為由上述例子發現它是可變動的)。
麻煩各位先進幫助我找建立正確的觀念
------


The first step toward proving things for yourself is to understand how others have done it before!

tsengsw
一般會員


發表:0
回覆:2
積分:0
註冊:2005-01-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-01-21 09:23:59 IP:210.202.xxx.xxx 未訂閱
剛剛用了 BCC32.exe 及 CL.exe 作 compile 的動作, 都可以正常執行...
tsengsw
一般會員


發表:0
回覆:2
積分:0
註冊:2005-01-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-01-21 09:34:06 IP:210.202.xxx.xxx 未訂閱
補充一下,code 如下:
#include     using namespace std;    int main(void)
{
        char *foo = "fish";
        cout << foo << endl;
        foo[0] = 'F';          //VC會出現錯誤 0xC0000005: Access Violation
        cout << foo << endl;
        //system("pause");
        return 0;
}
justdo
高階會員


發表:2
回覆:359
積分:222
註冊:2004-08-17

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-01-21 09:46:29 IP:221.169.xxx.xxx 未訂閱
有關1,2兩點,我測試的確是這樣,大概是BCB實作的問題 有關3 char foo[] = "fish"; 會真的配置5bytes的空間給予foo這個變數,其型態為char* 所以你可以合法地修改其值
fusung
中階會員


發表:26
回覆:169
積分:99
註冊:2003-11-25

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-01-21 12:41:59 IP:220.130.xxx.xxx 未訂閱
引言: 有關1,2兩點,我測試的確是這樣,大概是BCB實作的問題 有關3 char foo[] = "fish"; 會真的配置5bytes的空間給予foo這個變數,其型態為char* 所以你可以合法地修改其值
justdo, 你好: 謝謝你的回答,讓我有以下的領悟 【領悟 class="code"> char foo[] = "fish"; 等同於
char foo[5] = "fish"; 
其意義如同你所說的"會真的配置5bytes的空間給予foo這個變數" 相當於初始化foo這個矩陣的每個element,依序存 入"f" ,"i", "s" ,"h" 和 "\0", 所以"fish"的資料是否為const則不是重點(事實上"fish"它是,而在這是扮演初 始化foo的角色),重點是foo是一個非const的字元陣列,所以就可以變動之。 【領悟2】 假設"fish"是const這句話是對的,則如果用以下的方式
 
char *foo = "fish";
foo指向一個const字串,所以foo並未真實擁有自己的一份資料("fish"), 而"fish"是const,所以不能透過foo間接變動之。 在此順便回應tsengsw的回覆,compile是會過(這是我原提問用辭不夠精準), 可是會發生 class="code"> const char *foo = "fish"; 另外,如果是用
 char *foo = "fish";
 
則BCB會認定programmer想要"fish"為非const字串,所以就可以透過 foo[0]間接變動其內容。而VC 則保有"fish" const的特性,在執行 時才會查覺foo[0]企圖變更一個 const,因此發生run-time error。 以上是我的一些想法,如果有觀念錯誤,請不吝指教 //============= //努力學習中... //=============
------


The first step toward proving things for yourself is to understand how others have done it before!

系統時間:2024-05-19 19:46:42
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!