• 締切済み

【C言語】別関数でポインタの値を変えたのに変わらない。

【C言語】別関数でポインタの値を変えたのに変わらない。 メイン関数のポインタの値を、別関数で書き換えるプログラムを作りました。 以下がそのプログラムになります。 そのままだと、ダブルポインタを操作する必要があるので分かり辛いです。なので、ダブルポインタをシングルポインタにしてからポインタの書き換えを行うようにしました。その結果、きちんとポインタの書き換えが出来なくなってしまいました。 なぜ出来なくなってしまったのでしょうか。 2つのプログラムの違いは、 >  *pp = &dummy; が >  p = *pp;      // ダブルポインタをシングルポインタにした >  p = &dummy; に変わっただけです。 【参考】http://www.kouno.jp/home/c_faq/c4.html#8 -----------------正しいプログラム---------------- // 以下プログラムは、正しく動作する // 実行結果は、 //   p = 5 // と表示される void func( int **pp ); int main (void){   int *p;   int a = 0;   p = &a;   func( &p );   printf("p = %d\n", *p);   return 0; } void func( int **pp ){   static int dummy = 5;   *pp = &dummy; } ---------------------------------------------- -----------------間違いプログラム---------------- // 以下プログラムは、正しく動作しない // 実行結果は、 //   p = 0 // と表示される void func( int **pp ); int main (void){   int *p;   int a = 0;   p = &a;   func( &p );   printf("p = %d\n", *p);   return 0; } void func( int **pp ){   static int dummy = 5;   int *p;   p = *pp;      // ダブルポインタをシングルポインタにした   p = &dummy; } ----------------------------------------

みんなの回答

  • R32C
  • ベストアンサー率39% (115/290)
回答No.5

参照URLの回答に答えがありますよね。 call by value であることをこのFAQで 示しているだけのことです。 call by value C言語の値渡し について調べてみましょう。 まぁ >p = &dummy; ではなく *p = dummy ; で、5が表示されると思うけどC FAQの本題ではないですね。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.4

>  p = *pp;      // ダブルポインタをシングルポインタにした >  p = &dummy; これを「何か変だ」と気付かないのが、わからない理由でしょうね。 これではpの中身をいじっているだけで、ppには何の影響も及ぼしません。 元コード以上に簡潔に記述する手段はありませんし、そもそも「ポインタの中身」を見る/操作する場合は*(変数名)で記述するのが当然なので元コードがわかりづらいとも思えません。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.3

*pp を書き換えていないから。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

int *p は (int *)型の変数 p だと考えてみてください。 p = *pp ; も p = &dummy ; も 変数pに(int *)型の値を代入しているだけです。 ローカル変数に代入しただけでは関数外に何も影響しないのはわかりますね? 「シングルポインタ」にしたというのは void func0( int *pp ){   static int dummy = 5;   *pp = dummy; } ならわかっているではないかと思います。 これは、呼び出し側で int型のアドレスを渡して、関数側でアドレスから実体を求めて(*pp)それにint型の値を代入することで、呼び出し側のint型の内容を変更するものです。 これが、double型が対象なら void func0( double *pp ){   static double dummy = 5.0;   *pp = dummy; } となるのもわかると思います。 「正しいプログラム」の方では、対象が(int *)型になったものなのです。 呼び出し側で (int *)型のアドレスを渡して、関数側でアドレスから実体を求めて(*pp)それに(int *)型の値を代入することで、呼び出し側の(int *)型の内容を変更するものです。 変数dummyのアドレスを渡すのが目的なので、 *PP = &dummy ;とはなりますが、それ以外のところは int → doubleの変更と同様に int → int * の変更でよいのです。

  • SaKaKashi
  • ベストアンサー率24% (755/3136)
回答No.1

なぜ変更したのですか?理由は? >p = &dummy; ではなく *p = &dummy ; ではいかが。