回答編集履歴

3

[3] を [2] に修正

2020/03/11 09:59

投稿

rubato6809
rubato6809

スコア1382

test CHANGED
@@ -112,7 +112,7 @@
112
112
 
113
113
  追記です。
114
114
 
115
- 前者の func(str[3][15]); ではなく、後者の func(str); という呼出したというので重篤ではなかったとホッとしています。
115
+ 前者の func(str[3][15]); ではなく、後者の func(str); という呼出しだったというので重篤ではなかったとホッとしています。
116
116
 
117
117
 
118
118
 
@@ -130,7 +130,7 @@
130
130
 
131
131
  2. そのポインタ配列の2番目のポインタを読む。私の図(D)で言えば「int型データのアドレス」の[1] でインデックスされたポインタを読む、ということ。それが str[1] です。
132
132
 
133
- 3. さらに、そのポインタが指す配列の[2]ですから3番目の要素が str[1][2] です。これは (str[1])[3] という意味です。
133
+ 3. さらに、そのポインタが指す配列の[2]ですから3番目の要素が str[1][2] です。これは (str[1])[2] という意味です。
134
134
 
135
135
 
136
136
 

2

字句修正

2020/03/11 09:59

投稿

rubato6809
rubato6809

スコア1382

test CHANGED
@@ -112,7 +112,7 @@
112
112
 
113
113
  追記です。
114
114
 
115
- 前者の func(str[3][15]); ではなく、後者の func(str); という呼出したとうのであれば重篤ではなかったとホッとしています。
115
+ 前者の func(str[3][15]); ではなく、後者の func(str); という呼出したとうので重篤ではなかったとホッとしています。
116
116
 
117
117
 
118
118
 
@@ -120,7 +120,7 @@
120
120
 
121
121
 
122
122
 
123
- 誤解してます。同じなのは ``` str[1][2] ``` というコードの字面であって、データ構造が違うため**要素へのアクセスの仕方は違う**のです。
123
+ 誤解してます。同じなのは ``` str[1][2] ``` というコードの字面であって、データ構造が違うのだから**要素へのアクセスの仕方は違う**のです。
124
124
 
125
125
 
126
126
 

1

追記

2020/03/11 09:52

投稿

rubato6809
rubato6809

スコア1382

test CHANGED
@@ -103,3 +103,59 @@
103
103
  これは **str 配列の先頭アドレス**をfunc() に渡したという意味になります。
104
104
 
105
105
  さらには、この2つ以外の可能性も考えられます。そして、どう書いたのか、それによっては、もっと重篤な誤解をしている可能性があります。さあて、どうなんでしょうか?
106
+
107
+
108
+
109
+ ---
110
+
111
+
112
+
113
+ 追記です。
114
+
115
+ 前者の func(str[3][15]); ではなく、後者の func(str); という呼出したとうのであれば重篤ではなかったとホッとしています。
116
+
117
+
118
+
119
+ > ポインタ配列でも二次元配列でもデータ構造が違うだけで要素へのアクセスの仕方などは同じ(e.g. str[1][2])なのにどうしてエラーがでるのでしょうか。
120
+
121
+
122
+
123
+ 誤解してます。同じなのは ``` str[1][2] ``` というコードの字面であって、データ構造が違うため**要素へのアクセスの仕方は違う**のです。
124
+
125
+
126
+
127
+ void func(char *str[]) と引数を受け取った関数が str[1][2] をアクセスする時、
128
+
129
+ 1. str ポインタが指す所にはポインタ配列があるはずだ。
130
+
131
+ 2. そのポインタ配列の2番目のポインタを読む。私の図(D)で言えば「int型データのアドレス」の[1] でインデックスされたポインタを読む、ということ。それが str[1] です。
132
+
133
+ 3. さらに、そのポインタが指す配列の[2]ですから3番目の要素が str[1][2] です。これは (str[1])[3] という意味です。
134
+
135
+
136
+
137
+ つまり、ポインタ配列を経由して目的の要素をアクセスするのが char *str[] における str[1][2] です。
138
+
139
+ ところが char str[3][15]; という配列にはポインタ配列はありません。あるのは実データです。
140
+
141
+
142
+
143
+ 関数を func(str); と呼び出す時、関数 func に渡されるのは配列 str の先頭アドレスです。私の図(B)に書いた「先頭アドレス」が渡されるという事。繰り返しますが、そのメモリにあるのはポインタ配列ではありません。よって関数は配列の中の要素をアクセスできません(無理にアクセスすれば高い確率で不正なメモリアクセスを起こし異常終了する。場合によっては実際に起こりうる)。
144
+
145
+
146
+
147
+ 一方、配列の先頭アドレスを受け取った場合、str[1][2] をアクセスするのは、**先頭アドレス+(15 * 1 + 2)と計算するアドレスのメモリ**をアクセスするということです。この計算にポインタ配列は不要です。
148
+
149
+
150
+
151
+ 配列 char str[3][15]; を関数に渡したいなら、関数側は
152
+
153
+ ```C
154
+
155
+ void func(char str[][15])
156
+
157
+ {
158
+
159
+ ```
160
+
161
+ と受け取ってください。これで良いことは太字で強調したアドレスの計算式から読み取っていただきたい。