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

作如下測試,發現在D7與2005結果不同

答題得分者是:syntax
h@visli
資深會員


發表:103
回覆:429
積分:431
註冊:2004-02-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-07-01 14:06:16 IP:222.248.xxx.xxx 未訂閱
小弟作如下測試,發現在D7與2005結果不同,請高人指點    
procedure TestEx;
var
  S: String;
  CC, CS1, CS2: PChar;
begin
  CC := 'This is a Test';
  S := Trim(CC);
  CS1 := PChar(S);
  CS2 := PChar(Trim(CC));
  ShowMessage(CS1   ' '   CS2);
end;
------
------------------------
博采眾家之長,奉獻綿薄之力
------------------------
pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-07-04 08:26:41 IP:210.69.xxx.xxx 未訂閱
剛剛測試一下 Delphi 7 測試結果 This is a Test This is a Test Delphi 2005 測試結果 This is a Test T 經過單步追蹤, 發現問題在 CS2 := PChar(Trim(CC)); Delphi 2005 的 CS2 結果是 T 而已, 可能是 Delphi7 或 Delphi2005 的 bug , 可能是處理方式有所不同 PChar represents a pointer to a Char (that is, in its current implementation, to an AnsiChar). These character pointers are used to manipulate null-terminated strings. CC := 'This is a Test'; 這種寫法合適嗎 ? 一邊是字串, 一邊是指標 (雖然系統或許會您處理某些轉換)
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
SnoopyChen
一般會員


發表:1
回覆:17
積分:18
註冊:2003-07-24

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-07-06 23:33:56 IP:59.120.xxx.xxx 未訂閱
這行有問題: CS2 := PChar(Trim(CC)); Trim(CC)會產生一個臨時的字串變數, 接著將CS2指向第一個字元的位置, 但編譯器不保證何時會釋放這個臨時變數所佔用空間, 所以CS2所指的位置 可能隨後會做為其他用途。 因此保險的做法應是將指標指到一個明確的字串變數去, 如: S := Trim(CC); CS1 := PChar(S); 在使用這個指標(CS1)的生命周期時不應異動這個字串變數(S)。
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-08-01 01:21:14 IP:61.64.xxx.xxx 未訂閱
引言: 小弟作如下測試,發現在D7與2005結果不同,請高人指點
procedure TestEx;
var
  S: String;
  CC, CS1, CS2: PChar;
begin
  CC := 'This is a Test';
  S := Trim(CC);
  CS1 := PChar(S);
  CS2 := PChar(Trim(CC));
  ShowMessage(CS1   ' '   CS2);
end;
SnoopyChen 的觀念是錯誤的 Trim(CC)會產生一個臨時的字串變數? 不對 Trim(CC) 會配置一個空間給所產生的結果,且是 Lifetime-managed ,所以會自行宣告與釋放 而如果不是 lifetime-managed 的變數型態,你必需自己釋放他 整個程式並沒有錯 只是要注意,初始值所使用的記憶體位址,與程式載入記憶體後動態產生的位址將會是不同的區域 所以 CC 在一區域 CS1與S在另一個區域 而 CS2 又在另一個區域 這是我想說的,順便一題而已,其他相關,請自行去看 Help ,有很詳盡的說明,建議可以由 PAnsiChar 作為開始閱讀的關鍵字 至於這個問題的答案,也在 Help 裡面 這一行是答案 On the Win32 platform, AnsiString, sometimes called the long string, is the preferred type for most purposes. WideString is the preferred string type on the .NET platform. 因為 2005 以 WideChar 為預設使用的單位 (D7 就以 PChar 為預設) Trim(CC); 傳出來的是 PWideChar 你硬將之指定到 PChar 當然只有第一個字 「T」 囉,這就是答案 如果你還不懂,我說詳細一點 簡單的說 CC 宣告成 PChar 但是在傳入 Trim 前,轉換成 PWideChar 當然傳出來的會是 PWideChar,因為 Trim 內並不會做型態上的轉換所以傳出來的 String 也會是 PWideChar,因為 String 只是個型態的通稱,Delphi 會依據資料在編譯時給予正確的型別,在兩種型態間會自動處理,所以你根本沒有感覺到,也不會發現,CC 已經轉換成 PWideChar,並以該型態傳出 這樣你懂了嗎? 硬將之指定到 PChar 將會先讀到低位元 "T" 然後高位元 '\0" 結果誤認為結束,當然後面就沒有了,因為 PChar 沒有高低位元分別 PWideChar 才有,但是,貼心的 Delphi 也幫你處理掉這方面的細節,所以你只要用 W[1], W[2] 一樣是存取第一個字、第二個字, [x],x 索引不用自己處理雙位元索引要 1的部分 例 C1: String; W1: WideString; PC1: PChar; PW1:PWideChar; C1 := "This is a Test"; --> 其 Memory Dump --> $54 (T) $68 (h) $69 (i) $73 (s) ..... W1 := "This is a Test"; --> 其 Memory Dump --> $54 $00 (T) $68 $00 (h) $69 $00 (i) $73 $00 (s) ..... C1[1] --> "T" C1[2] --> "h" C1[3] --> "i" ... W1[1] --> "T" W1[2] --> "h" W1[3] --> "i" ... 若 PC1 := C1 PW1 := W1 則 PC1[1] --> "T" PC1[2] --> "h" PC1[3] --> "i" ... PW1[1] --> "T" PW1[2] --> "h" PW1[3] --> "i" ... 而若 PC1 := W1 則 PC1[1] --> "T" PC1[2] --> $00 PC1[3] --> "h" ... --------------------------^^^ 會被視為字串已結束 就是這樣 太貼心,很多細節你都不知道,結果就是,當你程式複雜起來,或是不用「呆呆」的方式來寫作,就會有問題出現,而新手只會「呆呆」的寫法,除了 Delphi 所提供的標準方法以外,完全不會用,也不會用到指標,當然就不會出現這樣的疑問(我不會形容,所以用「呆呆」) 所以這樣的問題,其實是好的,你要是弄得懂,表示你的程式功力更上一層樓,起碼,問題出在哪,你有能力去找出來 最後貼上正確的 Code
    procedure TForm1.Button1Click(Sender: TObject);
var
  S,S2: String;
  CC, CS1, CS2: PChar;
  W1: PWideChar;
begin      CC := 'This is a Test';
  S := Trim(CC);
  CS1 := PChar(S);
  CS2 := PChar(Trim(CC));
  W1 := PWideChar(Trim(CC));
  ShowMessage(CS1   ' '   W1);    end;
最後再補充一點, CC,CS1,CS2,W1 都是指標,如果用來呼叫 Windows API 後,都不可以再使用,除非重新指定其值,因為 Windows API 有時會將傳入的變數加以釋放,如此該變數所參照的位置將不再合法,而這個程式因為都是由 lifetime-managed 的方式產稱變數,在指定到指標上,所以不用特別去釋放之,但某些狀況可要注意,必需自行釋放 發表人 - syntax 於 2005/08/01 02:01:50 發表人 - syntax 於 2005/08/01 02:03:17
系統時間:2024-04-26 21:15:32
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!