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

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

■ このスレッドは過去ログ倉庫に格納されています
0001やばいいいNGNG
二次元配列の宿題が出されました。問題は十行十列の
二次元配列aをメモリ上の連続した領域へ行方向に格納するとき、
a(5,6)が格納される場所の番地はどれか。ここで番地は
十進数表示とする。ちなみにa(1,1)の時の番地は100です。
0048デフォルトの名無しさんNGNG
>>47
うざ
0049デフォルトの名無しさんNGNG
FORTRANとCじゃ行と列の格納順が逆だ、
というマメ知識をひけらかしたくてしょうがないんだが、
…どうでもいいですか。
005049NGNG
問題よく読んでなかった。すまん。
0051デフォルトの名無しさんNGNG
>二次元配列の宿題が出されました。問題は十行十列の
>二次元配列aをメモリ上の連続した領域へ行方向に格納するとき、
>a(5,6)が格納される場所の番地はどれか。ここで番地は
>十進数表示とする。ちなみにa(1,1)の時の番地は100です。

この質問の意味がわからん。
何の意味があるんだ。
0052デフォルトの名無しさんNGNG
a(0,1)の番地がわかれば予想可能
0053デフォルトの名無しさんNGNG
この問題、よく考えると答えようが無いぞ。
問題出した先生は逝って善しなんじゃ。
&(a[0][0])からのオフセットを表示するソフトは書けるけど、
前提条件がなさすぎじゃ。
0054デフォルトの名無しさんNGNG
つーか、プログラムを組めって問題じゃないだろ。
0055デフォルトの名無しさんNGNG
駄問!
出題者は教師失格!
0056ろんNGNG
はあ、
0057ろんNGNG
と言うか190と答え出たんだ。
0058-NGNG
>>53
「〜と仮定すれば」と添えればよいのだから
答えようが無いということもない
0059ろんNGNG
>58
そんな事しなくても解けるよ。
190って答え出てるんだから。
0060デフォルトの名無しさんNGNG
あほか?
矛盾だらけだつうの。
1)なんでバイト配列で+2ずつアドレスが増加する?
2)配列とアドレスの関係は言語やOSのメモリ管理に依存するので
一概にこうだとは言えない。問題にも示されていない。
3)1,1からはじまる配列って本当なのか?実在しない感じだが??
4)なんだよこれ?>行方向に格納するとき
0061-NGNG
>>59
はぁ……

>20 :デフォルトの名無しさん :01/10/17 16:33
> うーむ
> a[0..9,0..9]なのか
> a[1..10,1..10]なのか
> それをまずはっきりさせようよ

>21 :やばいい :01/10/17 16:36
> (1,10)だと思います。

すでに仮定が入ってるんですけど.
0062デフォルトの名無しさんNGNG
>>1の学校出た人って

  int  a[10][10]
  a[10][10]=5;

とか書くんだろうか?
0063-NGNG
>4)なんだよこれ?>行方向に格納するとき
多分先生が使っているコンピュータはメモリ上でも定義した通りの二次元配列でマッピングされるコンピュータなのでしょう
0064デフォルトの名無しさんNGNG
問題は>>1が書いたって感じだな。
教師が書いたのをコピペってわけじゃなさそ。
0065デフォルトの名無しさんNGNG
>>60-62
0-origin の配列なら
> ちなみにa(1,1)の時の番地は100です。
なんて書き方しないだろ。
1-origin なのは間違いないと思う。

つか、fortran くさいな。
0066デフォルトの名無しさんNGNG
>3)1,1からはじまる配列って本当なのか?実在しない感じだが??

FORTRAN は 1 からはじまるよ。
0067デフォルトの名無しさんNGNG
”番地”なんだから、Originとは何の関係も無い
0068デフォルトの名無しさんNGNG
>4)なんだよこれ?>行方向に格納するとき
warata
006965NGNG
>>67
0-origin なら
> ちなみにa(1,1)の時の番地は100です。
って書かず
> ちなみにa(0,0)の時の番地は100です。
って書くだろって話なんだが。
0070 NGNG
>>1
答えが190って教師に聞いたやつなのか?それともここのスレで聞いた数のことなのか?

Base0かbase1かの問題よりも>>1の書いた問題がネタか?と言うほうに興味がある。

数学的な質問ならば154だとする。
0071デフォルトの名無しさん NGNG
>>62
ワラタ
0072 NGNG
>>1
前提条件がころころ変貌中。厨房
http://piza2.2ch.net/test/read.cgi/tech/982853418/
0073デフォルトの名無しさんNGNG
配列を[1]から使う教授ってきもいよね。
0074デフォルトの名無しさんNGNG
>>73
VBって[1]からじゃなかった?
0075デフォルトの名無しさんNGNG
いや、たしか(-1000)とかできたはずだ。今思えばむちゃくちゃだな。
0076デフォルトの名無しさんNGNG
>>73
1からの方が解りやすい。
0077デフォルトの名無しさんNGNG
>>74
オプションで1からと0からと選べる。
0078デフォルトの名無しさんNGNG
Dim A(-10000 to 10000) as Integer

VBは本当胸が悪くなる。
0079デフォルトの名無しさんNGNG
>>78
配列の番号の範囲が指定できるのは
Pascalとかも同じ。というかPascalを真似した?
便利。高級言語。

C/C++の配列が0から始まるのは、
ポインタ演算との兼ね合いのため。
0080ネタ決定NGNG
ネタ決定
もうあげんな
0081デフォルトの名無しさんNGNG
>>79
>C/C++の配列が0から始まるのは、
>ポインタ演算との兼ね合いのため

つーか効率最優先だからだろ?
0082デフォルトの名無しさんNGNG
処理系依存だけど、大抵の場合Cでは

char a[20][20]; の場合、
a == &a == &a[0] == &a[0][0]

だと思うけど、これらが全てバラバラとなる処理系も当然ありうるよね。
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
コンパイルエラー
■ このスレッドは過去ログ倉庫に格納されています