1行1列、2行2列、、、、n行n列
というように動的に行列を増やす。
配列は別確保しない。(本当に1つの配列をふやしていく)
配列に入れた内容は、初期化しない。
例
r[1][1],r[2][2].....r[n][n]
ということをしたいのですが、
どのようにすればよいでしょうか。
どうか宜しくお願いいたします。
TAKE1
>1行1列、2行2列、、、、n行n列
>というように動的に行列を増やす。
>
>配列は別確保しない。(本当に1つの配列をふやしていく)
>
>配列に入れた内容は、初期化しない。
>
>例
>r[1][1],r[2][2].....r[n][n]
配列の添字は0から始まることをお忘れなく。
2次元配列の動的確保ならできるのですよね。「配列は別確保しな
い」というのはmalloc()&memcpy()をするなということでしょうか?
もしそうならrealloc()はどうですか? 場合によってはmalloc()&
memcpy()と同じ動作をするのかもしれませんが(良く知りません)。
#C++なら、vector<>。
--
ようか
mailto:yo...@kun.ne.jp
>
> #C++なら、vector<>。
これなら、2次元配列の動的確保+配列に入力した値の保証を
してくれるのでしょうか。
malloc,mallocで2次元配列。realloc,reallocで動的に増やす。
は、考えました。
しかし、配列に入力した値の保証が無いらしいのです。
私も、完全にmallocをマスターしていません。
(ポインタで行き詰まっている。)
今一番困っているのは、mallocやポインタなどを初心者でもわかりやすく
かつ、スキルアップにつながる本が
どれか分からない。
どの本を見ても、わかりにくい、または、説明が少なく内容が浅い。
C++、Cの
おすすめ本は何かありますか。
宜しくお願いいたします。
>malloc,mallocで2次元配列。realloc,reallocで動的に増やす。
>は、考えました。
2次元配列が一つの連続した領域(↓)でなく、
┏━┯━┯━┯ ┓
┠─┼─┼─┼・・・┨
┠─┼─┼─┼ ┨
・・・
┗━┷━┷━┷ ┛
(1次元配列への)ポインタの配列(↓)でよいなら、
┏━┓
┃ ╂─→┏━┯━┯・・・┓
┠─┨ ┗━┷━┷ ┛
┃ ╂─→┏━┯━┯・・・┓
┠─┨ ┗━┷━┷ ┛
・・・
┗━┛
配列の作成は、
TYPE **
create_array(int n)
{
TYPE **p;
int i;
p = malloc(n * sizeof(TYPE *));
for (i = 0; i < n; i++) {
p[i] = malloc(n * sizeof(TYPE));
}
return p;
}
大きさの変更は、
TYPE **
resize_array(TYPE **array, int old_size, int new_size)
{
int i;
/* 小さくする場合は、不要になった部分を解放 */
for (i = new_size; i < old_size; i++) {
free(array[i]);
}
array = realloc(array, new_size * sizeof(TYPE *));
/* 元の領域の拡張 */
for (i = 0; i < old_size; i++) {
array[i] = realloc(array[i], new_size * sizeof(TYPE));
}
/* 追加する領域 */
for (; i < new_size; i++) {
array[i] = malloc(new_size * sizeof(TYPE));
}
return array;
}
で出来ます。
#簡単のため、エラーチェックは省略しています
>しかし、配列に入力した値の保証が無いらしいのです。
realloc() は元の領域の内容をコピーします。領域が大きくなる場合、
大きくなった部分の内容は不定です。
realloc() が返してくる領域のアドレスは、元の領域と無関係です。元
の領域を指しているポインターは、すべて変更する必要があります。
--
片山@PFU
>
> 2次元配列が一つの連続した領域(↓)でなく、
>
> ┏━┯━┯━┯ ┓
> ┠─┼─┼─┼・・・┨
> ┠─┼─┼─┼ ┨
> ・・・
> ┗━┷━┷━┷ ┛
>
> (1次元配列への)ポインタの配列(↓)でよいなら、
>
> ┏━┓
> ┃ ╂─→┏━┯━┯・・・┓
> ┠─┨ ┗━┷━┷ ┛
> ┃ ╂─→┏━┯━┯・・・┓
> ┠─┨ ┗━┷━┷ ┛
> ・・・
> ┗━┛
上記での違いが分かりませんが
p[ ][ ]で呼び出せるのであれば構わないです。
(ポインタのポインタは、単純に2次元配列とかんがえていたので
深く考えて使っていませんでした。
何か不都合があるのでしょうか?)
>
> realloc() が返してくる領域のアドレスは、元の領域と無関係です。元
> の領域を指しているポインターは、すべて変更する必要があります。
これが問題かと。
これってポインタ名を変えなくてはならないって事でしょうか。
どうか宜しくお願いいたします。
1次元配列ならしてくれます。realloc()を使うよりはよっぽど使いや
すいと思います。
2次元配列はvector<>を組み合わせて実現します。このあたりは
malloc()でするのと同じです。
vector<>を使うためにC++を、他の部分はCで、というのであれば
realloc()を使って全部Cにした方が良かろうかと思います。
--
ようか
mailto:yo...@kun.ne.jp
本物と擬似の違いはありますが使い方は同じなので、領域確保の段階
で問題なければ特に不都合はないと思います(ただし『使うだけ』な
ら。ポインタのポインタと2次元配列の違いはまた別の話かと)。
>> realloc() が返してくる領域のアドレスは、元の領域と無関係です。元
>> の領域を指しているポインターは、すべて変更する必要があります。
>
>これが問題かと。
>これってポインタ名を変えなくてはならないって事でしょうか。
realloc()を使ってもデータは保存されるので大丈夫です(ただし領域
縮小の時はあぶれた分が捨てられます)。ポインタ名は変える必要はあ
りません。realloc()に渡したポインタは基本的にゴミになっていると
思って良いです。
buf = malloc(50);
buf = realloc(buf, 100);
--
ようか
mailto:yo...@kun.ne.jp
>
> 本物と擬似の違いはありますが使い方は同じなので、領域確保の段階
> で問題なければ特に不都合はないと思います(ただし『使うだけ』な
> ら。ポインタのポインタと2次元配列の違いはまた別の話かと)。
>
ポインタのポインタではなくて、mallocのmallocですね。
言いたかったのは。(^^;
いままで、Cでしかプログラムを組んだことがなかったのです。
しかし、C++に変わろうかと思っているのですが、
最初の段階で挫折しそうになっているのです。
(C++は、CたすJAVA割る2みたいな感じに思えるのです。
JAVAも最初の時点で挫折しました。
クラスとか、なんか訳わからん、てな感じで苦しんでおります。)
いままでに、教えていただいた方法で
1度プログラムを組んでみます。
ようかさん、片山さん、ありがとうございました。
TAKE1 さんの <9k6i96$r69$1...@news.stnet.ad.jp> より...
>2次元配列の動的確保の方法で困っています。
>
>1行1列、2行2列、、、、n行n列
>というように動的に行列を増やす。
>
>配列は別確保しない。(本当に1つの配列をふやしていく)
>
>配列に入れた内容は、初期化しない。
>
>例
>r[1][1],r[2][2].....r[n][n]
>
>ということをしたいのですが、
>どのようにすればよいでしょうか。
2次元配列 a[y,x] の要素に図のような順序で番号を付けます。
x 0 1 2 3 4
y
+---+---+---+---+---+
0 | 0| 1| 4| 9| 16| …
+---+-↓+-↓+-↓+-↓+
1 | 3← 2| 5| 10| 17|
+---+---+-↓+-↓+-↓+
2 | 8← 7← 6| 11| 18|
+---+---+---+-↓+-↓+
3 | 15←14←13←12| 19|
+---+---+---+---+-↓+
4 | 24←23←22←21←20|
+---+---+---+---+---+
:
番号 i は
x <= y のとき i = ( y + 1 ) * ( y + 1 ) - x - 1
x >= y のとき i = x * x + y
で計算できますので、1次元配列 b[i] に置き換えれば
明示的にデータをコピーすることなく
C言語の realloc() 関数(メモリ割り当てサイズの変更)で
(擬似)2次元配列 a[y,x] が拡張できます。
x の最大値と y の最大値に差があると無駄な領域が必要ですが…。
--
(^v^) (.. )(o^< >^o) ふと思いついて
(( ))//^ ))(( ))(( ))
= //林 //林 //林 //林 ================================^
mid...@mtg.biglobe.ne.jp やねのすずめ // \
http://www5a.biglobe.ne.jp/~espoir/ (ホームページ)// \
TAKE1 さんの <9k6i96$r69$1...@news.stnet.ad.jp> より...
>1行1列、2行2列、、、、n行n列
>というように動的に行列を増やす。
>
>配列は別確保しない。(本当に1つの配列をふやしていく)
>
>配列に入れた内容は、初期化しない。
>
>例
>r[1][1],r[2][2].....r[n][n]
>
>ということをしたいのですが、
添字を付け直し、1次元配列として扱って
C言語の realloc() 関数(メモリ割り当てサイズの変更)を使うのは
同じですが、
x, y を2進法で表して
... x2 x1 x0, ... y2 y1 y0
となるとき、
i = ... y2 x2 y1 x1 y0 x0
を新しい添字とすれば良いですね。
つまり、下図のように番号をつけるわけです:
0 1 4 5 ...
2 3 6 7 ...
8 9 12 13 ...
10 11 14 15 ...
: : : :
この方法は、3次元以上でも応用できます。
また、3進法でも10進法でもできます。
そのかわり、配列のサイズが 4 (=2^2) のべき乗になったりします。
# 半導体メモリ的
処理はシフト演算の繰返しでしょう。
# ハードウェア化すると速いかも(線の入れ換えですむので)
--
(^v^) (.. )(o^< >^o)
(( ))//^ ))(( ))(( ))
= //林 //林 //林 //林 ================================^
http://www5a.biglobe.ne.jp/~espoir/ やねのすずめ // \