• ベストアンサー

C 関数とポインタ

ポインタと関数がよく分かりません。 (日本語がおかしくてすみません(^_^;)) たとえば↓のようなプログラムで、 #include <stdio.h> void increase(int *i); int main(void) { int x = 3; increase(&x); printf("%d\n", x); return 0; } void increase(int *i) { (*i)++; } 結果は4になりますが、increase(&x)が&xとなっていて、 関数はvoid increase(int *i)でint *iになっているのですが、 これはvoid increase(int *i)はint型の「ポインタ」なので、 increase(&x)も&xと「アドレス」を渡さなければいけないということですか?? そして、void increase(int *i)内では、アドレス&xの指す値をインクリメント、という考えで良いのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★最初に考え方はあっています。 ・increase 関数は、変数のアドレス(ポインタ)を受け取ってから、その変数の内容を  インクリメントしています。アドレス(ポインタ)の参照は『*』演算子で行えるため  『*i』としています。でもカッコがないと先に『*i』の内容(値)を評価してから、  アドレス(ポインタ)値をインクリメントしてしまいます。注意! ・これは、インクリメントよりも『*』演算子の方が優先順位が高いからです。  『*i++』⇒*i の値を評価した後にポインタをインクリメント。でも評価した値は捨てられる。  『(*i)++』⇒*i の値に対してインクリメントする。  そのほか、  『*(i++)』⇒*i の値を評価してから i のポインタをインクリメントする。  『*(++i)』⇒i のポインタをインクリメントしてから *i の値を評価する。  ※『*i++』と『*(i++)』は同じことです。  という処理になります。 ・increase 関数で変数のアドレス(ポインタ)で受け取るように指定されているため、  呼び出し元では x 変数のアドレスを『&』演算子で求めて渡しています。  もし、x が普通の変数ではなくて配列の場合にはそのまま x を渡せばよい。  これは配列変数の名前(識別名)が配列のアドレスを表しているため『&』演算子を  使う必要がないためである。    int x[] = { 1, 2, 3 };    increase( x ); ←『&』をつけなくて良い  printf( "%d\n", x[0] ); ←配列の先頭である x[0] だけ値がインクリメントされる  表示は、  x[0]⇒2  x[1]⇒2  x[2]⇒3  となります。 まとめ: ・increase 関数は int 型のポインタを受け取るので、普通の変数を渡すときには『&』演算子で  アドレス(ポインタ)値を渡して、配列や、すでにポインタの変数は、その変数名がアドレス値を  意味しますのでそのまま名前を渡します。 ・以上。おわり。

apple_cube
質問者

お礼

詳しい説明までつけてくださって、ありがとうございます! 良く分かりました(^_^)

その他の回答 (1)

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

increase()は、引数として渡された「int型へのポインタ」が 指す領域に1を加える、という仕事をするための関数です。 increase()に正しく仕事をしてもらうためには、呼び出す側は increase()に「int型へのポインタ」を渡さなければなりません。 したがって、main()で定義した変数xのアドレス(&x)を 渡しているのです。

apple_cube
質問者

お礼

ありがとうございます(*^_^*)

関連するQ&A