重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

(1)2次元配列の動的確保について
1次元配列の動的確保は理解できたのですが、次のプログラムの
文(ⅰ)~(ⅱ)の意味を理解できていないので教えてください。

int **a, j, k, nrows=3, ncolumns=4 ;
a = (int **)malloc(nrows * sizeof(int *));
a[0] = (int *)malloc(nrows * ncolumns * sizeof(int)); …(ⅰ)
//先頭アドレスに…

for(j = 1; j < nrows; j++)
a[j] = a[0] + j * ncolumns; …(ⅱ)
  //この行が特にわかりません。

(2)配列の添え字について
この書き方はどういう意味になりますか?
out[X_SIZE * (i) + (j)]

分かる方、回答お願いします。

A 回答 (3件)

(1)について


二次元配列のように見えて、実のところポインタの1次元配列を使って2次元配列のようにソース上で書き表す方法と思われます。

a = (int **)malloc(nrows * sizeof(int *))で、
intのポインタを入れる領域を行の分(3つ)準備し、その領域の先頭ポインタを a に入れます。
これで
int *a[3];
としたのと同じものができました。

次に
(int *)malloc(nrows * ncolumns * sizeof(int)) で、
[ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7][ 8][ 9][10][11]
の様に int の領域を取ります。
これは1次元配列と同じなのですが、
[ 0][ 1][ 2][ 3]
[ 4][ 5][ 6][ 7]
[ 8][ 9][10][11]
の様に2次元配列に見立てて、
for(j = 1; j < nrows; j++)
  a[j] = a[0] + j * ncolumns; …()
で0,4,8を指すポインタをa[0],a[1]、a[2]に入れます。
(a[0]はすでに入っていますけどね)

すると、
a[1][2]で[6]の場所を、
a[0][3]で[3]の場所を指すことができます。

なぜこうなるのかはK&Rにバッチリ書いてあるので、調べてください。

必要であれば、明日追加の解説を書きます。

(2)について
1次元配列を2次元配列のように使う書き方です。
out[n][X_SIZE];
の様に宣言した配列を、
out[i][j]のようにアクセスするのと同じ効果があります。
もちろん、i<n,j<X_SIZEの範囲です。
これを応用すると、1次元配列を何次元のものにも見立てることができます。
その逆も可能です。
    • good
    • 0
この回答へのお礼

回答を頂きありがとうございます。
この解説なら納得です!
ありがとうございました。またよろしくお願いします!

お礼日時:2006/11/25 01:52

ちょっと間違えました。


該当部分を以下のように差し替えてください。
-------ここから下全部--------

次に
malloc(nrows * ncolumns * sizeof(int)) で、
[ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7][ 8][ 9][10][11]
の様に int の領域を取ります。
これは1次元配列と同じなのですが、
[ 0][ 1][ 2][ 3]
[ 4][ 5][ 6][ 7]
[ 8][ 9][10][11]
の様に2次元配列に見立てて、
a[0]=(int *)malloc(nrows * ncolumns * sizeof(int))
for(j = 1; j < nrows; j++)
  a[j] = a[0] + j * ncolumns;
で0,4,8を指すポインタをa[0],a[1]、a[2]に入れます。
    • good
    • 0

まず、(i)の上にある行で、行数(=3)分のポインタ領域を指す


ポインタ a の領域を確保します。

次に(i)で、int型3行4列分全体の領域を指すポインタを a[0] に
格納します。イメージとしては、縦方向に3個、横方向に4個、
計12個の長方形を思い浮かべるとよいでしょう。
行番号、列番号とも、ここではゼロ始まりです。
つまり、0行0列~2行3列の12個です。

次のforループでは、1行目と2行目分の領域を指すポインタである
a[1] と a[2] を設定しています。
a[1] は a[0] から横方向の数である4個分だけ
ずれることになりますので、j(このときは1) * ncolums(=4) を加えています。
a[2] は a[1] からさらに4個分だけずれます。
a[0] からは8個分ずれますので、j(このときは2) * ncolumns を加えています。


out[X_SIZE * i + j]
は、out[X_SIZE]を基点として、i行j列分だけ離れた領域のことです。
    • good
    • 0
この回答へのお礼

回答を頂きありがとうございます。
out[X_SIZE * i + j]で2次元配列の働きをするのですね!

お礼日時:2006/11/25 01:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!