トップページ⇒tech
117コメント30KB

二次元配列の宿題が分かりません・・・。

■ このスレッドは過去ログ倉庫に格納されています
0001やばいいいNGNG
二次元配列の宿題が出されました。問題は十行十列の
二次元配列aをメモリ上の連続した領域へ行方向に格納するとき、
a(5,6)が格納される場所の番地はどれか。ここで番地は
十進数表示とする。ちなみにa(1,1)の時の番地は100です。
0083デフォルトの名無しさんNGNG
【1次元配列】の配列という説明だけは止めて欲しい
0084デフォルトの名無しさんNGNG
所詮すべて一次元だもんな
0085デフォルトの名無しさんNGNG
構造体を

struct UNIT{
double *x
double *y
}

と、取り
UNITとx、yを malloc,reallocで増すことはできないのでしょうか。

UNIT 1
x1,x2,x3,x4,・・・・・ 可変
y1,y2,y3,y4,・・・・・ 可変

UNIT 2
x1,x2,・・・
y1,y2,・・・

・
・
・

UNITも可変

(可変とかいてあるが、増やすだけで良い)
というようにしたいのです。

コンパイラはとおるのですが、走らせるとreallocでいつもエラーでとまりま
す。

どうか宜しくお願いいたします。
0086デフォルトの名無しさんNGNG
なにこれ?何やりたいのかぜんぜんわかんないのは俺の経験不足?
0087デフォルトの名無しさんNGNG
1はプログラムの授業中に居眠りでもしていたんだろう。
1はプログラムの授業中をサボっていたのだろう。
1はプログラムの実習中にどこぞのエロWEBでも見ていたのだろう。
1はプログラムの授業中友人との話に夢中だったのだろう。
1の周りには、宿題について聞けるような友人がいないのだろう。

こんなスレ立てる奴はどうかしている。
こんな質問に答える奴もどうかしてる。
まさに「スレ立てるまでもない質問」だ。
宿題わかりません、宿題おしえてくださいスレ見るたびにうんざりする。
そんなことは友人か先生に聞け。
ああ、ごめん。優秀な友人はいないのか。
先生も相手にしてくれないからここで聞いているのか。
だったらこっちにいけバカ。
http://piza2.2ch.net/test/read.cgi/tech/1001998049/l50
0088デフォルトの名無しさんNGNG
こんなスレageる奴もどうかしている、に20ペソ。
0089デフォルトの名無しさんNGNG
>>84
その認識も実は間違いなのでは?
というのが>>82の主張だったりします。

たとえば type a[A][B] があったとして
a[x][y] のアドレスが a+(x*A+y)*sizeof(type) である 保証
ってありましたっけ?
0090デフォルトの名無しさんNGNG
ありますよ。
0091デフォルトの名無しさんNGNG
>>85
typedef struct{
double *x;
double *y;
} UNIT;

[UNIT unit1,unit2;]※1

int main(void){

UNIT unit1,unit2;※0
[static UNIT unit1,unit2;]※2
   
unit1.x = realloc(unit1.x,sizeof(double)*10);
unit1.y = realloc(unit1.y,sizeof(double)*13);

unit2.x = realloc(unit2.x,sizeof(double)*5);
unit2.y = realloc(unit2.y,sizeof(double)*3);

return 0;
}
0092デフォルトの名無しさんNGNG
※1と※2は静的な領域で、※0は動的な領域。
静的な領域はたいがい0で初期化される。

で、reallocの引数に渡すポインタが適当な値だとエラー。
0ならOKなので、※1と※2がうまく動く。
009390NGNG
a+(x*A+y)*sizeof(type)
でなく
a+(x*B+y)*sizeof(type)
だな。
009489NGNG
>>93
ああ、タイプミス。

でも、保証があるっていうのは?
K&Rに載ってるのかな?見てみます。

これって10年前から疑問に思ってたんだけど
ほったらかしてたんだよね・・・
0095デフォルトの名無しさんNGNG
>>94
type a1[A][B];
を
typedef type t[B];
t a2[A];
として考えてみれ。
009689NGNG
>>95
うん。考えた。で、試したりもしました。

struct TY { char a,b,c; };
main()
{
 struct TY ty[3][3];
 int i,j;
 for( i=0;i<3;i++ ) {
  for( j=0;j<3;j++ ) {
   printf("%d %d: %x\n",i,j,&ty[i][j] );
  }
 }
}

$ ./a.out
0 0: bffffac0
0 1: bffffac3
0 2: bffffac6
1 0: bffffac9
1 1: bffffacc
1 2: bffffacf
2 0: bffffad2
2 1: bffffad5
2 2: bffffad8

むーん。ま、こういうもんか。
でも保証されてる っていう証拠にはならないんだよなぁ。
009790NGNG
1. 配列 type a[SIZE] において
a[x] のアドレスは a+x*sizeof(type) となることが保証されています。

typedef type t[B];
t a[A];
において a[x] のアドレスは
1より a+x*sizeof(t) すなわち
a+x*(sizeof(type)*B) = a+x*B*sizeof(type)
となります。

a[x][y] は
a[x] を b と置き、
b[y] のアドレスは b+y*sizeof(type) です。
b は a[x] = a+x*B*sizeof(type) なので置き換えてみると
(a+x*B*sizeof(type)) + y*sizeof(type)
= a+(x*B+y)*sizeof(type)
となります。

途中適当な所があるけど許して。
0098デフォルトの名無しさんNGNG
type a[A][B];
int i, j;

&a[i][j] ≡ a[i] + j ≡ (a + i) + j
ここでa + iの型は「type *」
aの型は「type[B] *」なので、

(unsigned long)(a + i)
≡ (unsigned long)a + sizeof(type[B]) * i
≡ (unsigned long)a + sizeof(type) * B * i

(unsigned long)((a + i) + j)
≡ (unsigned long)(a + i) + sizeof(type) * j
≡ (unsigned long)a + sizeof(type) * B * i + sizeof(type) * j
≡ (unsigned long)a + sizeof(type) * (B * i + j)

規格(ANSI ISO IEC 9899-1999)では6.5.2.1だ。
...(上のような規則の説明があって)、
It follows from this that arrays are stored in row-major
order (last subscript varies fastest).
0099デフォルトの名無しさんNGNG
>>89
結局は規格でどう定められているか、という問題でしょ。
この手の話題は Followup-To: fj.comp.lang.c だね。
イヤというほど詳細なフォローが貰えると思うよ。
010089NGNG
>>99
>規格でどう定められているか
まあ、そこです。
でもfjには投稿できないんだよな〜
0101デフォルトの名無しさんNGNG
これ、どこかで「保証されてる」って見たような気がするんだけど、
どこだったかな・・・。
0102デフォルトの名無しさんNGNG
二次元配列の中身(数値)がメモリー上にどのように配置されてようが、一次元ではないか?
参照しやすいように並べていればどんな方法でもいいんでない?
あればの話だけど。
0103デフォルトの名無しさんNGNG
まげ
0104デフォルトの名無しさんNGNG
>>102
自前でページングやメモリインターリーブしてもなあ。。。
010598NGNG
>>99-101
だから規格で保証されているというに…
ANSI ISO IEC 9899-1999規格の6.5.2.1節だってば。
0106デフォルトの名無しさんNGNG
>>102
row-majorでなきゃ、
 char lines[NLINES][LINELEN];
 ...
 foo(lines[i]);
なんて書けなくなっちゃうだろうが。

それにでかい配列だと、a[i][j]のiとjのどっち
を動かすかで性能も大違いだろう。
0107デフォルトの名無しさんNGNG
>>105
見たいんだけど、ansi.orgとか行っても見当たらない・・
見るとこ間違えてる?
0108デフォルトの名無しさんNGNG
>>107
ttp://www.iso.ch/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=29237&ICS1=35&ICS2=60&ICS3=
0109デフォルトの名無しさんNGNG
>>108
買うんですか?
こういう規格って広く一般に浸透させなければ意味ない
ということで今ならWeb上で参照できるものと思ってました・・・
だれか原文丸コピーしてくれないかなぁ
0110デフォルトの名無しさんNGNG
規格は原則有料。規格化団体の唯一の収入源だから。
正式規格が決まる直前のドラフトならダウンロードできる。
(http://anubis.dkuug.dk/JTC1/SC22/open/n2620/)

6.5.2.1 Array subscripting

Constraints

One of the expressions shall have type ``pointer to
object type'', the other expression shall have integer type,
and the result has type ``type''.

Semantics

A postfix expression followed by an expression in
square brackets [] is a subscripted designation of an
element of an array object. The definition of the subscript
operator [] is that E1[E2] is identical to (*((E1)+(E2))).
Because of the conversion rules that apply to the binary +
operator, if E1 is an array object (equivalently, a pointer
to the initial element of an array object) and E2 is an
integer, E1[E2] designates the E2-th element of E1 (counting
from zero).

Successive subscript operators designate an element of
a multidimensional array object. If E is an n-dimensional
array (n>=2) with dimensions i,j, ... ,k, then E (used as
other than an lvalue) is converted to a pointer to an
(n-1)-dimensional array with dimensions j, ... ,k. If the
unary * operator is applied to this pointer explicitly, or
implicitly as a result of subscripting, the result is the
pointed-to (n-1)-dimensional array, which itself is
converted into a pointer if used as other than an lvalue.
It follows from this that arrays are stored in row-major
order (last subscript varies fastest).

EXAMPLE Consider the array object defined by the
declaration

int x[3][5];

Here x is a 3 by 5 array of ints; more precisely, x is an array
of three element objects, each of which is an array of five
ints. In the expression x[i], which is equivalent to
(*((x)+(i))), x is first converted to a pointer to the
initial array of five ints. Then i is adjusted according to
the type of x, which conceptually entails multiplying i by
the size of the object to which the pointer points, namely
an array of five int objects. The results are added and
indirection is applied to yield an array of five ints. When
used in the expression x[i][j], that array is in turn
converted to a pointer to the first of the ints, so x[i][j]
yields an int.

Forward references: additive operators (6.5.6), address and
indirection operators (6.5.3.2), array declarators
(6.7.5.2).
0111デフォルトの名無しさんNGNG
http://www.murkworks.net/~bketcham/n869.txt
の方が新しいとおもわれ
0112デフォルトの名無しさんNGNG
>>110-111
ありがとう!
これで長年の疑問も氷解しました。

これが最後のageです
0113デフォルトの名無しさんNGNG
>1
死ね死ね死ね死ね死ね死ね死ね死ね死ね
0114>113NGNG
露骨な殺人予告はやめてください
0115 NGNG
っていうか実行してみればわかるだろうて・・・。

printf("%p",&a[5][6] - &a[0][0]);
0116デフォルトの名無しさんNGNG
printf("%d", &6[5[a]] - &0[0[a]]);
0117デフォルトの名無しさんNGNG
>>116
コンパイルエラー
■ このスレッドは過去ログ倉庫に格納されています