PCharの扱いに関して


OLD  2010-08-13 20:22:21  No: 38976

PCharの扱いに関して質問です。

const
 Name = 'Name';
begin
 Proc('Name');

procedure Proc(Name :PChar);
begin
     ・
     ・
     ・
end;

上記PCharをStringと同じように扱っています。

procedure Proc(Name :String);
begin
     ・
     ・
     ・
end;

Stringを使用しようと思ったのですが、PCharを使用しているコードは問題ありませんか?

PCharのヘルプを見ると、注意点などがのっていて、Helpの理解があいまいなところがあるので扱うのが心配です。Stringを使用した場合とPCharを使用した場合の違いや注意点などありましたら教えてください。


igy  2010-08-13 22:45:02  No: 38977

>Stringを使用しようと思ったのですが、PCharを使用しているコードは問題ありませんか?

正しくコードを書いていれば、問題ないのではないかと思います。
# procedure Proc(Name :PChar);
# のコードが提示されていないので、問題あるかどうかは、判りませんが。

>PCharのヘルプを見ると、注意点などがのっていて、Helpの理解があいまいなところがあるので

具体的には、どの部分が“理解があいまい”なのですか?


OLD  2010-08-14 01:12:03  No: 38978

すいません、自分で調べてるうちになんとなくですが、理解できました。

表題とずれてしまうかもしれませんがPChar関係で一つ質問です。
StringをPCharにキャストしたときPChar(Str)このStrは255文字を超えていても大丈夫なのですが、これはどうしてでしょう?
キャストするときにも文字数を気にしなくてよいのでしょうか?


KHE00221  2010-08-14 03:22:41  No: 38979

StrPasの中身を見れば納得できるんじゃないか?


KHE00221  2010-08-14 03:32:50  No: 38980

PChar から String は勝手に変換してくれるので

Proc を使う側は問題にならないけど

Proc 内部で String と PAnsiChar は互換性がありません
と出る可能性はある


通りすがり  2010-08-19 02:46:52  No: 38981

Delphi2009とか最近のDelphiのStringはよく分かりません。

const で指定した物や、コード中で直接設定した文字列は PChar型に渡した場合、勝手に変換されます。

例にあるような

procedure Proc(Name :PChar);

という手続きの場合

Proc('Name') と書くこともできます。

Const
  Name = 'Name';
---
begin
  Proc(Name)
end;

は、Constしてるだけですので上と等価です。

また、PChar はポインターなので、長さは関係ないです。
PCharの示す先に何かがあって「不都合が起こらない限り」アクセスできます。
ただし、文字列として扱われる場合 #0 があれば、そこで終わります。

また、delphiのstringは255文字で終わりません。
かつての255文字制限の String は ShortString として残っています。

var
    s:string;
    p:PChar;
begin
    s:= 'ABCDE'#0'FGHIJKLMN';
    p:= PChar(s);
    s:= StrPas(p);
    Memo1.Lines.Add(s);
end;

出力
 ABCDE

---
var
 p:PChar;
 s:string;
begin
  s:='ABCDE';  // 勝手にメモリが確保される。

  p:=@s[1];   // PChar は Stringのアドレスを参照している
  inc(p);     // 1つ進める
  p^:='X';    // p は s を参照しているので s の2番目が変わる
  Memo1.Lines.Add(s);

  //上と等価
  p:= PChar(s);
  inc(p);
  p^:='Z';
  Memo1.Lines.Add(s);
end;

出力
 AXCDE
 AZCDE

Stringなどを参照することなく、PCharだけで文字列を扱おうとすれば、StrAllocまたはGetMemしなければ、文字列として使えません。

stringをPCharにキャストした場合、そのアドレスが参照されているだけで、自身以外のメモリは確保されません。
その辺が String と違う所です。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加