回答編集履歴

4

説明を修正

2019/06/28 08:32

投稿

rubato6809
rubato6809

スコア1380

test CHANGED
@@ -120,7 +120,7 @@
120
120
 
121
121
 
122
122
 
123
- 仮引数としてダブルポインタ dptr があるということは、dptr が指すメモリにもうひとつのポインタ変数が存在し、そのポインタ変数が int 型の値がある、これ基本の形です。ダブルポインタがあるということは、このような構造があることを意味します。
123
+ 仮引数としてダブルポインタ dptr があるということは、dptr が指すメモリにもうひとつのポインタ変数が存在し、そのポインタ変数が int 型の値をポイントしている、これ基本の形です。ダブルポインタがあるということは、このような構造があることを意味します。
124
124
 
125
125
 
126
126
 

3

文章を一部修正

2019/06/28 08:32

投稿

rubato6809
rubato6809

スコア1380

test CHANGED
@@ -144,7 +144,7 @@
144
144
 
145
145
  以上、配列として確保したメモリは(A)もしくは(B)の姿をしていて、そのなかにはポインタとなっているメモリは存在しないということ、
146
146
 
147
- 一方、ダブルポインタの場合は、ダブルポインタが指すメモリにもうひとつのポインタ変数(もしくはポインタ変数の配列)が存在していますので、メモリ上の姿は二次元配列と異なっている、よって同じものではない・互換性は無いのです。
147
+ 一方、ダブルポインタの場合は、ダブルポインタが指すメモリにもうひとつのポインタ変数(もしくはポインタ変数の配列)が存在していますので、メモリ上の姿は二次元配列と異なっている、よって同じものではないのです。この違いを理解しないと何時までも疑問が解消しないと思います。
148
148
 
149
149
 
150
150
 

2

図と説明を追加

2019/06/28 08:12

投稿

rubato6809
rubato6809

スコア1380

test CHANGED
@@ -48,7 +48,7 @@
48
48
 
49
49
  まず、二次元配列とダブルポインタを混同しないこと。
50
50
 
51
- そのためには、コード上の字面で理解しようとするのではなく、**メモリ上の配置を図に描いて理解する**ことをお勧めします。時間があればに描いて説明しますが
51
+ そのためには、コード上の字面で理解しようとするのではなく、**メモリ上の配置を図に描いて理解する**ことをお勧めします(後半にを追加しました)
52
52
 
53
53
  逆にお聞きしたいのだけど、どこに「二次元配列とダブルポインタは同じ」と書いてありましたか?
54
54
 
@@ -94,4 +94,58 @@
94
94
 
95
95
 
96
96
 
97
- とりあえず、そんな事です。ご不明な点はコメントください。
97
+ とりあえず、そんな事です。
98
+
99
+
100
+
101
+ ---
102
+
103
+
104
+
105
+ **メモリ上の配置を図に描いて理解する**について、拙い図を描きました。
106
+
107
+ 二次元配列として。同じものを、2つの描き方をしました。
108
+
109
+ - (A)二次元配列のイメージ
110
+
111
+ - (B)実際のメモリ上の配置
112
+
113
+
114
+
115
+ メモリ上では days[0][11] の次が days[1][0] である=連続していることを示しています。
116
+
117
+ 次に、関数の引数として ``` int **dptr ``` がある場合、
118
+
119
+ - (C)配置の基本
120
+
121
+
122
+
123
+ 仮引数としてダブルポインタ dptr があるということは、dptr が指すメモリにもうひとつのポインタ変数が存在し、そのポインタ変数が int 型の値がある、これは基本の形ですね。ダブルポインタがあるということは、このような構造があることを意味します。
124
+
125
+
126
+
127
+ 実際は、この基本形だけではなく、
128
+
129
+ - ポインタが配列になっている
130
+
131
+ - int 型のデータが配列になっている
132
+
133
+
134
+
135
+ 場合もあります。なぜなら、**ポインタが指す場所のメモリは連続しているので、配列とみなせる**からです。そんな場合を示したのが次の図です。
136
+
137
+ - (D)配列をポイントする場合
138
+
139
+
140
+
141
+ この場合、図の右側に { 31, 28, ... 31 } と、{ 31, 29, ... 31 } という2つの配列が描かれています(描いたつもりですw)が、この2つの配列はメモリ上で連続している保障がありません。二次元配列では days[0][11] の次が days[1][0] だったような保障は無い、ということ。
142
+
143
+
144
+
145
+ 以上、配列として確保したメモリは(A)もしくは(B)の姿をしていて、そのなかにはポインタとなっているメモリは存在しないということ、
146
+
147
+ 一方、ダブルポインタの場合は、ダブルポインタが指すメモリにもうひとつのポインタ変数(もしくはポインタ変数の配列)が存在していますので、メモリ上の姿は二次元配列と異なっている、よって同じものではない・互換性は無いのです。
148
+
149
+
150
+
151
+ ![メモリ配置の様子](90304152edf296bb4641cfccf2c60d1b.jpeg)

1

一部修正

2019/06/28 08:05

投稿

rubato6809
rubato6809

スコア1380

test CHANGED
@@ -90,7 +90,7 @@
90
90
 
91
91
  と、どちらも同じ格好の ``` **days ``` なのがオカシイのです(この書き方自体が誤りですが)。質問者の呼び出し方だとさしずめ
92
92
 
93
- ``` arr = **days; ``` のような代入になるでしょう。コンパイラがこれを受け付けたとすれば、arr に days[0][0] の値が代入されたかもしれせん。つまり ``` arr = 31; ``` という代入です。それは質問者が期待した動作でしょうか?もう少し簡単なで確認してみると良いと思いますれも時間があれば例を示しますが
93
+ ``` arr = **days; ``` のような代入になるでしょう。arr には常に days[0][0] の値が代入されま。つまり ``` arr = 31; ``` という代入です。それは質問者が期待した動作でしょうか?この辺り、もう少し簡単な一次元配列で確認してみると良いと思いますの段落、少修正しした)
94
94
 
95
95
 
96
96