全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2135
推到 Plurk!
推到 Facebook!

string轉pchar問題

尚未結案
poemkevin
初階會員


發表:26
回覆:77
積分:30
註冊:2002-10-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-13 11:10:08 IP:210.202.xxx.xxx 未訂閱
問個笨問題:string轉pchar問題 procedure TForm1.Button1Click(Sender: TObject); var s:string; p:pchar; begin s:='abcd'; //p:=s; //p:=pchar(s); s[1]:='f'; p:='xyzs'; s[2]:=p[0]; p[1]:=s[3]; //這段會產生 Access Violation showmessage(p); //應為xczs showmessage(s); //fxcd end; 插入替代字元時, string與pchar不是都是字元, 為何string[1]可以插入字元 而用pchar時不能用, 改為p[1]:=pchar('q')也不行 發表人 - poemkevin 於 2004/09/13 11:51:44
ha0009
版主


發表:16
回覆:507
積分:639
註冊:2002-03-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-13 11:51:04 IP:219.80.xxx.xxx 未訂閱
你好:
    所有指標變數都需在使用前先建立需要的記憶體,你可以如下面的方式使用    var
  p : PChar;
  idx : integer;
begin
  GetMem (p, 5);
  StrCopy(P, 'ABCDE');
  memo1.Lines.Add(p);
  FreeMem (P);
end;
poemkevin
初階會員


發表:26
回覆:77
積分:30
註冊:2002-10-19

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-13 13:17:17 IP:210.202.xxx.xxx 未訂閱
引言: 你好: 所有指標變數都需在使用前先建立需要的記憶體,你可以如下面的方式使用 var p : PChar; idx : integer; begin GetMem (p, 5); StrCopy(P, 'ABCDE'); memo1.Lines.Add(p); FreeMem (P); end;
ha0009大大: 謝謝你的回應 可是小弟問的主題並不是這解答 可能是小弟解釋問題的方式不好 s:sting; p:pchar; s:="abcd"; p:=pchar(s); s[1]:="f"; p[0]:='f"; 照理它們的儲存位址都相同, 應可以存取 但s[1]可以將字元f插入到字串第一個位址做替代, 則s的內容就變為fbcd, 但p[0]原為a, 若把字元f插入替代這個a, 則它不允許存取, 小弟想向各位大大, 請教的是為什麼會有這樣的問題產生, 若小弟想要以這樣的方法去運用, 要怎麼去修改 =========================== 沉思, 再沉思! 學習, 再學習! 生活隨喜, 簡單自在^^ ===========================
ha0009
版主


發表:16
回覆:507
積分:639
註冊:2002-03-16

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-09-13 13:27:51 IP:219.80.xxx.xxx 未訂閱
你好:
    Sorry 會錯意了
>    < src="http://sourceprovide.deepen.com.tw/K_Top/bp.gif">
        
poemkevin
初階會員


發表:26
回覆:77
積分:30
註冊:2002-10-19

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-09-13 16:04:27 IP:210.202.xxx.xxx 未訂閱
引言:
你好:
    Sorry 會錯意了
>    < src="http://sourceprovide.deepen.com.tw/K_Top/bp.gif">
這樣的方式 p[2]與s[1]是相同的 等於一旦變動p變數, 連s變數都會跟著變動 但是小弟是希望 s:='abcd'; s[1]:='f'; p:='xyzs'; s[2]:=p[0]; p[1]:=s[3]; //這段會產生 Access Violation showmessage(p); //應為xczs showmessage(s); //fxcd 希望p[0..3]這變數不是只能唯讀而也能寫入替代字元 或許因為pchar是指標式字串,所以雖可以讀p[0],p[1],p[2],p[3], 但卻沒辦法寫入吧 若要寫入則要寫入整個變數字串例如p:='xczs';才可以吧 查指標的資料為下 A PChar is a pointer to a null-terminated string of characters of the type Char. Each of the three character types also has a built-in pointer type: A PChar is a pointer to a null-terminated string of 8-bit characters. A PAnsiChar is a pointer to a null-terminated string of 8-bit characters. A PWideChar is a pointer to a null-terminated string of 16-bit characters. PChars are, with short strings, one of the original Object Pascal string types. They were created primarily as a C language and Windows API compatibility type. 發表人 - poemkevin 於 2004/09/13 16:29:01
ha0009
版主


發表:16
回覆:507
積分:639
註冊:2002-03-16

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-09-13 16:56:48 IP:219.80.xxx.xxx 未訂閱
你好:
    你這個問題就是我第一次回答的答案呀? 光宣告一個指標變數
,Delphi 並不會幫你配置記憶體,該說他也不知道要配給你多少記
憶體。        你會說,那為什麼我可以 showmessage(p); 不會出錯,只是不
能更改 p 的內容。請你將藍色的程式碼執行一遍,你會發現將常數
字串 'bbbbb' 帶給 p 時,p 的位址已經變更為區域常數字串所在的
位置,這並非是你自行配置的記憶區塊,而是系統預先配置的。當然
不允許你去改變它的值呀。你可以試試我第一次跟你提的例子,先宣
告一塊記憶體,再試試是否可行。    
  s:='abcd';
  s[1]:='f';
  p:='xyzs';
  s[2]:=p[0];
  p[1]:=s[3]; //這段會產生 Access Violation
 showmessage(p); //應為xczs 
  showmessage(s); //fxcd        var
  p : PChar;
begin
  memo1.Lines.Add('為初始化的變數狀態');
  memo1.Lines.Add(format ('配置的記憶體位置 [%0.8x]; 指標變數位址%0.8x', [Longint (p), longint (@p)]));
  p := 'bbbbb';
  memo1.Lines.Add('已初始化的變數狀態');
  memo1.Lines.Add(format ('配置的記憶體位置 [%0.8x]; 指標變數位址%0.8x', [Longint (p), longint (@p)]));
end;        以上說明如有錯誤還請先進們指正
poemkevin
初階會員


發表:26
回覆:77
積分:30
註冊:2002-10-19

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-09-14 08:44:55 IP:210.202.xxx.xxx 未訂閱
引言:
你好:
    你這個問題就是我第一次回答的答案呀? 光宣告一個指標變數
,Delphi 並不會幫你配置記憶體,該說他也不知道要配給你多少記
憶體。        你會說,那為什麼我可以 showmessage(p); 不會出錯,只是不
能更改 p 的內容。請你將藍色的程式碼執行一遍,你會發現將常數
字串 'bbbbb' 帶給 p 時,p 的位址已經變更為區域常數字串所在的
位置,這並非是你自行配置的記憶區塊,而是系統預先配置的。當然
不允許你去改變它的值呀。你可以試試我第一次跟你提的例子,先宣
告一塊記憶體,再試試是否可行。    
  s:='abcd';
  s[1]:='f';
  p:='xyzs';
  s[2]:=p[0];
  p[1]:=s[3]; //這段會產生 Access Violation
 showmessage(p); //應為xczs 
  showmessage(s); //fxcd        var
  p : PChar;
begin
  memo1.Lines.Add('為初始化的變數狀態');
  memo1.Lines.Add(format ('配置的記憶體位置 [%0.8x]; 指標變數位址%0.8x', [Longint (p), longint (@p)]));
  p := 'bbbbb';
  memo1.Lines.Add('已初始化的變數狀態');
  memo1.Lines.Add(format ('配置的記憶體位置 [%0.8x]; 指標變數位址%0.8x', [Longint (p), longint (@p)]));
end;        以上說明如有錯誤還請先進們指正
謝謝ha0009您的回應, 大概是小弟腦筋一直轉不過來吧! 上述的程式都有run過, 雖會應用, 但還是有點不明白它為何會這樣? 再請教一下, 是否pchar變數一旦宣告好記憶體位置 例如五個字元就不容許個別更改 例如p='abcde'; 則p[0]='a';p[1]='b';p[2]='c';p[3]='d';p[4]='e'; 只能被讀取, 不允許修改, 要修只能再重新再讓整體變數再做一次變動, 例如又修改改p='xyz'; 而不允許做這樣的修改p[0]='x';p[1]='y';p[2]='z'; 只是為何字串變數string卻允許這樣的修改, 而pchar宣告的卻不行, 它們二個不是都同樣有在記憶體宣告位置嗎 =========================== 沉思, 再沉思! 學習, 再學習! 生活隨喜, 簡單自在^^ ===========================
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-09-14 11:14:22 IP:218.170.xxx.xxx 未訂閱
我覺得是pchar,string不能直接轉換等值的原因,請參考    http://delphi.ktop.com.tw/topic.php?topic_id=43759
ha0009
版主


發表:16
回覆:507
積分:639
註冊:2002-03-16

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-09-14 12:00:28 IP:219.80.xxx.xxx 未訂閱
是否pchar變數一旦宣告好記憶體位置
    配置記憶體的指令有 New, GetMem, ReallocMem
    釋放記憶體則以 Dispose 與 FreeMem
    詳細用法請參考 Delphi Help        p='abcde';
只能被讀取, 不允許修改, 要修只能再重新再讓整體變數再做一次變動,        常數本來就不允許修改,你那串 'abcde' 就是一個區域型的常數項。
    p := @s[1]
    如果你像上面的例字,就可以透過 p 直接修改 s 的內容,但那也不是 p
    所擁有的空間,而是系統為 s 所配置的空間,因此你並不用負擔義放資源
    的責任。        只要是指標的運算,在運算前都需要自行配置記憶體空間。系統並不會也
不知道要幫你配多少空間。這不單是 PChar 型態,PByte, PBoolean 等, 甚
至連物件宣告你也是要透過 Create 來配置所需的記憶體。
poemkevin
初階會員


發表:26
回覆:77
積分:30
註冊:2002-10-19

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-09-14 12:28:52 IP:210.202.xxx.xxx 未訂閱
謝謝兩位大大的回應 shinhrn貼的另一篇文章中的syntax大大的解釋 及ha0009這二天來的回應指導 終於明白了它了, 很感謝^^ =========================== 沉思, 再沉思! 學習, 再學習! 生活隨喜, 簡單自在^^ ===========================
系統時間:2024-05-18 15:32:44
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!