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

回答編集履歴

5

修正

2025/06/17 16:31

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -5,17 +5,16 @@
5
5
  見た目で値(*が付いていない)だからとかアドレス(*が付いている)だからは関係ありません。
6
6
 
7
7
  B が動くのは、パラメータとしてアドレスを渡した時、呼び出された側がそのアドレスの示す先の値を変更すれば、呼び出し側で変更した値を得られるからです。
8
- 変数 a の値を変更する為に a のアドレスを渡すのです。
8
+ **変数 a の値を変更する為に a のアドレスを渡す** のです。
9
9
 
10
10
  ![実行イメージ](https://ddjkaamml8q8x.cloudfront.net/questions/2025-06-17/fbe46180-52d1-4e58-8b24-fa552c89cb0f.png)
11
11
 
12
- A の func は "『アドレス』という値" をもつ ptr を変更して main に返したいのですから、パラメータとしては
12
+ A の func は "『アドレス』という値" をもつ ptr を変更して main に返したいのですから、パラメータとしては **変数 ptr の値を変更する為に ptr のアドレスを渡さなければなりません** 。
13
- 変数 ptr の値を変更する為に ptr のアドレスを渡さなければなりません。
14
13
 
15
14
  ![実行イメージ](https://ddjkaamml8q8x.cloudfront.net/questions/2025-06-17/aa2548e5-71c7-4b83-ac24-8965222e282e.png)
16
15
 
17
16
  値渡しとかポインタ渡しとか(時には参照渡しとか)いう言葉に惑わされないでください。
18
- ポインタは単に、"アドレス"という値の入った変数です。そのを関数のパラメータとして渡して更新するのなら、他と同じようにそのアドレスを渡す必要があります。
17
+ ポインタは単に、"アドレス"という値の入った変数です。その変数(関数のパラメータとして渡して)更新するのなら、他と同じようにそのアドレスを渡す必要があります。
19
18
 
20
19
  ---
21
20
  ```c

4

コード追加

2025/06/17 04:24

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -15,4 +15,58 @@
15
15
  ![実行イメージ](https://ddjkaamml8q8x.cloudfront.net/questions/2025-06-17/aa2548e5-71c7-4b83-ac24-8965222e282e.png)
16
16
 
17
17
  値渡しとかポインタ渡しとか(時には参照渡しとか)いう言葉に惑わされないでください。
18
- ポインタは単に、"アドレス"という値の入った変数です。その値を関数のパラメータとして渡して更新するのなら、他と同じようにそのアドレスを渡す必要があります。
18
+ ポインタは単に、"アドレス"という値の入った変数です。その値を関数のパラメータとして渡して更新するのなら、他と同じようにそのアドレスを渡す必要があります。
19
+
20
+ ---
21
+ ```c
22
+ #include <stdio.h>
23
+ #include <stdlib.h>
24
+
25
+ typedef struct {
26
+ int num; //数字を保存
27
+ char c; //アルファベットを保存
28
+ } Kouzo;
29
+
30
+ void func(Kouzo **ptr){
31
+ for(int loop=1; loop<10; loop++) {
32
+ Kouzo *p = realloc(*ptr, (loop+1) * sizeof(Kouzo)); //realloc は失敗する可能性があるので直接 *ptr を更新してはいけない
33
+ if(p == NULL) {
34
+ printf("realloc failure\n");
35
+ return;
36
+ }
37
+ *ptr = p;
38
+ p[loop].num = 10;
39
+ p[loop].c = 'A';
40
+ printf("addr in func:%p, loop:%d\n", *ptr, loop+1);
41
+ }
42
+ }
43
+
44
+ int main(void){
45
+ Kouzo *ptr = malloc(sizeof(Kouzo)); //要素1つ分の構造体を作成
46
+
47
+ ptr->num = 10;
48
+ ptr->c = 'A';
49
+
50
+ printf("addr in main bef:%p\n", ptr);
51
+
52
+ func(&ptr);
53
+
54
+ printf("addr in main aft:%p\n", ptr);
55
+
56
+ free(ptr);
57
+ }
58
+ ```
59
+ 実行結果(paiza.io)
60
+ ```
61
+ addr in main bef:0x1b7f42a0
62
+ addr in func:0x1b7f42a0, loop:2
63
+ addr in func:0x1b7f42a0, loop:3
64
+ addr in func:0x1b7f52d0, loop:4
65
+ addr in func:0x1b7f52d0, loop:5
66
+ addr in func:0x1b7f52d0, loop:6
67
+ addr in func:0x1b7f52d0, loop:7
68
+ addr in func:0x1b7f52d0, loop:8
69
+ addr in func:0x1b7f52d0, loop:9
70
+ addr in func:0x1b7f52d0, loop:10
71
+ addr in main aft:0x1b7f52d0
72
+ ```

3

修正

2025/06/17 02:55

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -7,5 +7,12 @@
7
7
  B が動くのは、パラメータとしてアドレスを渡した時、呼び出された側がそのアドレスの示す先の値を変更すれば、呼び出し側で変更した値を得られるからです。
8
8
  変数 a の値を変更する為に a のアドレスを渡すのです。
9
9
 
10
+ ![実行イメージ](https://ddjkaamml8q8x.cloudfront.net/questions/2025-06-17/fbe46180-52d1-4e58-8b24-fa552c89cb0f.png)
11
+
10
12
  A の func は "『アドレス』という値" をもつ ptr を変更して main に返したいのですから、パラメータとしては
11
- 変数 ptr の値を変更する為に ptr のアドレスを渡さなければなりません。
13
+ 変数 ptr の値を変更する為に ptr のアドレスを渡さなければなりません。
14
+
15
+ ![実行イメージ](https://ddjkaamml8q8x.cloudfront.net/questions/2025-06-17/aa2548e5-71c7-4b83-ac24-8965222e282e.png)
16
+
17
+ 値渡しとかポインタ渡しとか(時には参照渡しとか)いう言葉に惑わされないでください。
18
+ ポインタは単に、"アドレス"という値の入った変数です。その値を関数のパラメータとして渡して更新するのなら、他と同じようにそのアドレスを渡す必要があります。

2

修正

2025/06/17 02:22

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -2,5 +2,10 @@
2
2
  >それに対して、funcptrはポインタ渡しなので、funcptrでaを変更すると、呼び出し元のaも変更されます。
3
3
 
4
4
  この部分で重要な勘違いがあります。
5
+ 見た目で値(*が付いていない)だからとかアドレス(*が付いている)だからは関係ありません。
6
+
5
- B が動くのは、パラメータとしてアドレスを渡した時、呼び出された側がそのアドレスの示す先の値を変更すれば、呼び出し側で変更した値を得られるからです。変数 a の値を変更する為に a のアドレスを渡すのです。
7
+ B が動くのは、パラメータとしてアドレスを渡した時、呼び出された側がそのアドレスの示す先の値を変更すれば、呼び出し側で変更した値を得られるからです。
8
+ 変数 a の値を変更する為に a のアドレスを渡すのです。
9
+
6
- A の func は "『アドレス』という値" をもつ ptr を変更して main に返したいのですから、パラメータとしては"『アドレス』という値"をもつ ptr のアドレスを渡してやりとりをしなければなりません。
10
+ A の func は "『アドレス』という値" をもつ ptr を変更して main に返したいのですから、パラメータとしては
11
+ 変数 ptr の値を変更する為に ptr のアドレスを渡さなければなりません。

1

修正

2025/06/17 02:17

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -2,5 +2,5 @@
2
2
  >それに対して、funcptrはポインタ渡しなので、funcptrでaを変更すると、呼び出し元のaも変更されます。
3
3
 
4
4
  この部分で重要な勘違いがあります。
5
- B が動くのは、パラメータとしてアドレスを渡した時、呼び出された側がそのアドレスの示す先の値を変更すれば、呼び出し側で変更した値を得られるからです。
5
+ B が動くのは、パラメータとしてアドレスを渡した時、呼び出された側がそのアドレスの示す先の値を変更すれば、呼び出し側で変更した値を得られるからです。変数 a の値を変更する為に a のアドレスを渡すのです。
6
- A の func は "『アドレス』という値" を main に返したいのですから、パラメータとしては"『アドレス』という値"のあるアドレスを渡してやりとりをしなければなりません。
6
+ A の func は "『アドレス』という値" をもつ ptr を変更して main に返したいのですから、パラメータとしては"『アドレス』という値"をもつ ptr のアドレスを渡してやりとりをしなければなりません。