質問するログイン新規登録

回答編集履歴

1

追補

2015/09/02 14:10

投稿

退会済みユーザー
answer CHANGED
@@ -36,4 +36,67 @@
36
36
  for(i=0;i<5;i++)
37
37
  printf("0x%x\n", cNum+i);
38
38
  ```
39
- 配列に入っているデータを順次関数に渡す場合などでは、こういった表現方法も使えます。
39
+ 配列に入っているデータを順次関数に渡す場合などでは、こういった表現方法も使えます。
40
+ ---
41
+
42
+ [追加]
43
+ 関数定義の int* も 変数定義の int* もそうですが、これらは「int型のポインタ」を収める変数定義です。
44
+
45
+ ポインタというのは「"値を収めたメモリ領域(=変数に割り当てられたメモリ領域)" の番地」を表すものです。
46
+ そのポインタ変数を * で修飾すると、ポインタの示すメモリに格納された値を表します。
47
+
48
+ この逆のパターンが、アドレス修飾子 & です。
49
+ 例えば int型の変数:num のポインタが欲しい場合は &num と書きます。得られるのは変数に割り当てられたメモリアドレスです。
50
+
51
+ これらをコードで示すと、以下のような感じです。
52
+ ※ポインタ経由で、 num1 = num2; と同じ結果を得る処理を行います。
53
+
54
+ ```C
55
+ int num1, num2;
56
+ int* pNum;
57
+
58
+ num1 = 999; // num1 に 999 を代入
59
+ pNum = &num; // num1のポインタを pNum に代入
60
+ num2 = *pNum; // pNum(num1のメモリアドレス) に格納された値 (= num1の値)を num2に代入
61
+
62
+ printf("%d %d %d", num1, *pNum, num2);
63
+ ```
64
+
65
+
66
+ 関数へのポインタ渡しについては、例えば以下のような感じです。
67
+
68
+ test1関数は引数がポインタ渡しなので、test1関数を呼び出す際は 変数:numのポインタを取得して渡しています。
69
+ test2関数も引数がポインタ渡しです。test2関数を呼び出す際もポインタを渡すことになります。test1関数では既にポインタで値を受け取っていて変数:pNumの中身はnumのポインタです。test2関数を呼び出す時は、変数:pNumに収められたnumのポインタをそのまま渡します。
70
+
71
+ もし、test1関数の中で *pNum のように、* で修飾するとポインタの中身ということで、intの値(変数:numに代入した値)を表すことになります。しかし、test2関数はポインタを必要とするので修飾の必要はありません。
72
+ ※これは & で修飾した場合の逆パターンです。
73
+
74
+ 実行結果としては、test2関数内の printf関数によって変数:numに代入した値が出力されます。
75
+
76
+ ```C
77
+ void test2(int* pNum){
78
+ printf("%d", *pNum);
79
+ };
80
+
81
+ void test1(int* pNum){
82
+ test2(pNum);
83
+ };
84
+
85
+ int num;
86
+
87
+ num = 123;
88
+ test1(&num);
89
+ ```
90
+
91
+ 質問の関数でも同様のポインタ渡しが行われます。
92
+ https://teratail.com/questions/15327 でも書いたのですが、デバッガで動きを追いかけることをした方がいいですよ。
93
+
94
+ 質問の実装も、sort2関数に以下のように渡すことも合わせて考えれば、多少理解の助けになるでしょうか。
95
+ ```C
96
+ int *pNA, *pNB;
97
+
98
+ pNA = &na;
99
+ pNB = &nb;
100
+
101
+ sort2(pNA,pNB);
102
+ ```