- ベストアンサー
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の指す値をインクリメント、という考えで良いのでしょうか?
- みんなの回答 (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 型のポインタを受け取るので、普通の変数を渡すときには『&』演算子で アドレス(ポインタ)値を渡して、配列や、すでにポインタの変数は、その変数名がアドレス値を 意味しますのでそのまま名前を渡します。 ・以上。おわり。
その他の回答 (1)
- asuncion
- ベストアンサー率33% (2127/6289)
increase()は、引数として渡された「int型へのポインタ」が 指す領域に1を加える、という仕事をするための関数です。 increase()に正しく仕事をしてもらうためには、呼び出す側は increase()に「int型へのポインタ」を渡さなければなりません。 したがって、main()で定義した変数xのアドレス(&x)を 渡しているのです。
お礼
ありがとうございます(*^_^*)
お礼
詳しい説明までつけてくださって、ありがとうございます! 良く分かりました(^_^)