Page List

Search on the blog

2011年2月5日土曜日

ポインタの参照渡し

今日は、ポインタとアドレスの違いについて。

まず、両者の違いについて。
ポインタ(以下では、アドレスとの違いを明確にするため”ポインタ変数”と呼ぶ)はあくまでも、アドレスを指し示す入れ物である。
ポインタ変数自体はアドレスではなく、intやcharと同じ変数である。
これに対してアドレスは、固定番地である。メモリの物理的な位置である。

ちょっと突っ込んで考えると、ポインタ変数にもアドレスが存在するし(アドレスを指し示す変数のアドレスというイメージ)。
よってポインタ変数を関数に参照渡ししたい場合は、ポインタ変数のアドレスを渡す必要がある。

具体的な例を見てみよう。
main()でchar型のポインタ変数を宣言し、setStr()という関数にポインタ変数を渡して、文字列を取得する。
まずは、ダメな例から。
  1. void setStr(char *a) {  
  2.    a = new char [8];  
  3.    strcpy(a, "Hello");  
  4. }  
  5.   
  6. int main() {  
  7.    char *a = NULL;  
  8.   
  9.    setStr(a);  
  10.    cout << a << endl;  
  11.    return 0;  
  12. }  
上の書き方では、setStr()を抜けた後もaはNULLのままです。
setStr()に渡したのは、ポインタ変数です。
setStr()では、仮引数aのコピーを作り、関数内だけで有効なaに対して処理をします。よって、setStr()をreturnするときには、aに対する変更はmainに反映されません。

次に、良い例。
下の書き方では、ポインタ変数のアドレスを渡しています。
  1. void setStr(char **a) {  
  2.     *a = new char [8];  
  3.     strcpy(*a, "Hello");  
  4. }  
  5.   
  6. int main() {  
  7.     char *a = NULL;  
  8.   
  9.     setStr(&a);  
  10.     cout << a << endl;  
  11.     return 0;  
  12. }  
これだと、期待した結果が得られます。
くどいようですが、動的メモリの確保をする場合は「ポインタ変数とアドレスは異なるものだ」としっかり理解しておくことが大切です。

0 件のコメント:

コメントを投稿