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

回答編集履歴

4

説明を修正

2019/06/28 08:32

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -59,7 +59,7 @@
59
59
  次に、関数の引数として ``` int **dptr ``` がある場合、
60
60
  - (C)配置の基本
61
61
 
62
- 仮引数としてダブルポインタ dptr があるということは、dptr が指すメモリにもうひとつのポインタ変数が存在し、そのポインタ変数が int 型の値がある、これ基本の形です。ダブルポインタがあるということは、このような構造があることを意味します。
62
+ 仮引数としてダブルポインタ dptr があるということは、dptr が指すメモリにもうひとつのポインタ変数が存在し、そのポインタ変数が int 型の値をポイントしている、これ基本の形です。ダブルポインタがあるということは、このような構造があることを意味します。
63
63
 
64
64
  実際は、この基本形だけではなく、
65
65
  - ポインタが配列になっている

3

文章を一部修正

2019/06/28 08:32

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -71,6 +71,6 @@
71
71
  この場合、図の右側に { 31, 28, ... 31 } と、{ 31, 29, ... 31 } という2つの配列が描かれています(描いたつもりですw)が、この2つの配列はメモリ上で連続している保障がありません。二次元配列では days[0][11] の次が days[1][0] だったような保障は無い、ということ。
72
72
 
73
73
  以上、配列として確保したメモリは(A)もしくは(B)の姿をしていて、そのなかにはポインタとなっているメモリは存在しないということ、
74
- 一方、ダブルポインタの場合は、ダブルポインタが指すメモリにもうひとつのポインタ変数(もしくはポインタ変数の配列)が存在していますので、メモリ上の姿は二次元配列と異なっている、よって同じものではない・互換性は無いのです。
74
+ 一方、ダブルポインタの場合は、ダブルポインタが指すメモリにもうひとつのポインタ変数(もしくはポインタ変数の配列)が存在していますので、メモリ上の姿は二次元配列と異なっている、よって同じものではないのです。この違いを理解しないと何時までも疑問が解消しないと思います。
75
75
 
76
76
  ![メモリ配置の様子](90304152edf296bb4641cfccf2c60d1b.jpeg)

2

図と説明を追加

2019/06/28 08:12

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -23,7 +23,7 @@
23
23
  - 特に、アドレス(ポインタ)を引数で渡す際の注意
24
24
 
25
25
  まず、二次元配列とダブルポインタを混同しないこと。
26
- そのためには、コード上の字面で理解しようとするのではなく、**メモリ上の配置を図に描いて理解する**ことをお勧めします。時間があれば図描いて説明しますが
26
+ そのためには、コード上の字面で理解しようとするのではなく、**メモリ上の配置を図に描いて理解する**ことをお勧めします(後半図を追加しました)
27
27
  逆にお聞きしたいのだけど、どこに「二次元配列とダブルポインタは同じ」と書いてありましたか?
28
28
 
29
29
  次に、関数の引数には仮引数と実引数があります。ご存じでしたか?
@@ -46,4 +46,31 @@
46
46
  と、どちらも同じ格好の ``` **days ``` なのがオカシイのです(この書き方自体が誤りですが)。質問者の呼び出し方だとさしずめ
47
47
  ``` arr = **days; ``` のような代入になるでしょう。arr には常に days[0][0] の値が代入されます。つまり ``` arr = 31; ``` という代入です。それは質問者が期待した動作でしょうか?この辺り、もう少し簡単な一次元配列で確認してみると良いと思います(この段落、少し修正しました)。
48
48
 
49
- とりあえず、そんな事です。ご不明な点はコメントください。
49
+ とりあえず、そんな事です。
50
+
51
+ ---
52
+
53
+ **メモリ上の配置を図に描いて理解する**について、拙い図を描きました。
54
+ 二次元配列として。同じものを、2つの描き方をしました。
55
+ - (A)二次元配列のイメージ
56
+ - (B)実際のメモリ上の配置
57
+
58
+ メモリ上では days[0][11] の次が days[1][0] である=連続していることを示しています。
59
+ 次に、関数の引数として ``` int **dptr ``` がある場合、
60
+ - (C)配置の基本
61
+
62
+ 仮引数としてダブルポインタ dptr があるということは、dptr が指すメモリにもうひとつのポインタ変数が存在し、そのポインタ変数が int 型の値がある、これは基本の形ですね。ダブルポインタがあるということは、このような構造があることを意味します。
63
+
64
+ 実際は、この基本形だけではなく、
65
+ - ポインタが配列になっている
66
+ - int 型のデータが配列になっている
67
+
68
+ 場合もあります。なぜなら、**ポインタが指す場所のメモリは連続しているので、配列とみなせる**からです。そんな場合を示したのが次の図です。
69
+ - (D)配列をポイントする場合
70
+
71
+ この場合、図の右側に { 31, 28, ... 31 } と、{ 31, 29, ... 31 } という2つの配列が描かれています(描いたつもりですw)が、この2つの配列はメモリ上で連続している保障がありません。二次元配列では days[0][11] の次が days[1][0] だったような保障は無い、ということ。
72
+
73
+ 以上、配列として確保したメモリは(A)もしくは(B)の姿をしていて、そのなかにはポインタとなっているメモリは存在しないということ、
74
+ 一方、ダブルポインタの場合は、ダブルポインタが指すメモリにもうひとつのポインタ変数(もしくはポインタ変数の配列)が存在していますので、メモリ上の姿は二次元配列と異なっている、よって同じものではない・互換性は無いのです。
75
+
76
+ ![メモリ配置の様子](90304152edf296bb4641cfccf2c60d1b.jpeg)

1

一部修正

2019/06/28 08:05

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -44,6 +44,6 @@
44
44
  pathday = day_of_month(..., **days); // 関数呼出し
45
45
  ```
46
46
  と、どちらも同じ格好の ``` **days ``` なのがオカシイのです(この書き方自体が誤りですが)。質問者の呼び出し方だとさしずめ
47
- ``` arr = **days; ``` のような代入になるでしょう。コンパイラがこれを受け付けたとすれば、arr に days[0][0] の値が代入されたかもしれせん。つまり ``` arr = 31; ``` という代入です。それは質問者が期待した動作でしょうか?もう少し簡単なで確認してみると良いと思いますれも時間があれば例を示しますが
47
+ ``` arr = **days; ``` のような代入になるでしょう。arr には常に days[0][0] の値が代入されま。つまり ``` arr = 31; ``` という代入です。それは質問者が期待した動作でしょうか?この辺り、もう少し簡単な一次元配列で確認してみると良いと思いますの段落、少修正しした)
48
48
 
49
49
  とりあえず、そんな事です。ご不明な点はコメントください。