PCharの扱いに関して


OLD  2010-08-13 11:22:21  No: 38976  IP: 192.*.*.*

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 13:45:02  No: 38977  IP: 192.*.*.*

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

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

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

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

編集 削除
OLD  2010-08-13 16:12:03  No: 38978  IP: 192.*.*.*

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

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

編集 削除
KHE00221  2010-08-13 18:22:41  No: 38979  IP: 192.*.*.*

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

編集 削除
KHE00221  2010-08-13 18:32:50  No: 38980  IP: 192.*.*.*

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

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

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

編集 削除
通りすがり  2010-08-18 17:46:52  No: 38981  IP: 192.*.*.*

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 と違う所です。

編集 削除