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

このエントリーをはてなブックマークに追加
1やばいいい
二次元配列の宿題が出されました。問題は十行十列の
二次元配列aをメモリ上の連続した領域へ行方向に格納するとき、
a(5,6)が格納される場所の番地はどれか。ここで番地は
十進数表示とする。ちなみにa(1,1)の時の番地は100です。
2やばいいい:01/10/17 11:44
答えだけじゃなく、その経緯も書けといわれました。
君の隣の席の関根君に聞きたまえ。
=========END==========
4やばいいい:01/10/17 11:51
友達いないので。
君は友達じゃなければ質問できないのか?
===========END==========
2ちゃんねらーは友達だ!
配列のベースは0?1?
要素のサイズは?
8デフォルトの名無しさん:01/10/17 16:10
最近は、難しい宿題でるんだな・・・

自分も、なんか挑戦したくなったので、マジレスで答えてみる
今回だけだぞ

まず、
x = ( 5*8*256 + 6*8 ) / (5*6) + 100(=a(1,1)の番地)
(8は1バイトのbit数の事)

そして、
もし環境が16bitなら、
番地 = x * 256

32bitなら、
番地 = x * 65536

windows95以降使ってるなら、32bitだよ
わからなかったら、とりあえず32bitにしておいてね


俺も100%は自信ない もし間違ってたら、誰か指摘して
Cの配列の話なら
http://member.nifty.ne.jp/maebashi/programmer/pointer.html
もっと宿題に答えて欲しいなら
[プログラム板] お兄ちゃんの宿題、私が答えるよ
http://piza2.2ch.net/test/read.cgi/tech/982853418/
10>8:01/10/17 16:15
えっとそんなに大きな答えにはならないと思うよ。
番地がa(1,1)で100,101だから,
(5,6)に直すと、200くらいになるんじゃないか?
11デフォルトの名無しさん:01/10/17 16:18
>>8
正解。
最短で答えるとそうなる。
素直に156だべ?
100+10*5+6
13やばいい:01/10/17 16:19
>8
200以下とはいってました。
100代とはわかるんですが・
14:01/10/17 16:21
200くらいになると思う。
15やばいい:01/10/17 16:23
バイトは関係ないらしいです。
純粋に番地が分かればいい
16デフォルトの名無しさん:01/10/17 16:28
>>1
ソースきぼんぬ
つーかよ、数えりゃすぐわかるだろ。
a(n, 1)は 100 + (n - 1) * 10 番地に格納される。(1 <= n <= 10)
a(n, m)は 100 + (n - 1) * 10 + m - 1 番地に格納される。(1 <= m <= 10)
a(5, 6)は 100 + 4 * 10 + 5 = 145番地に格納される。
でも、こんなの実装次第だ。
うーむ
a[0..9,0..9]なのか
a[1..10,1..10]なのか
それをまずはっきりさせようよ
21やばいい:01/10/17 16:36
(1,10)だと思います。
22やばいい:01/10/17 16:37
バイトで言えば、a(1,1)が100で、
a(1,2) 102になっています。
ならもうわかるだろ。
24やばいい:01/10/17 16:40
大体、200くらいになると言っていたので
190代だと思う。適当に答えを書き込めば、いいんだろうけど
その経緯も説明しろと言われたので、少しきついです。
>>18であってるのだろうが、
> バイトで言えば、a(1,1)が100で、
> a(1,2) 102になっています。
ということなら 190 かと。
26デフォルトの名無しさん:01/10/17 16:48
>>22
番地の増加分は1ではなく、2なのか?
a(n, m)は 100 + (n - 1) * 20 + (m - 1) * 2 番地から格納される。(1 <= n, m <= 10)
a(5, 6)は 100 + 4 * 20 + 5 * 2 番地から格納される。
28やばいい:01/10/17 16:52
a(1,1)の中に100と101が入ってる。
多分、100でいいんだろうと思う。
a(1,2)で102,103。
答えは190で間違いないと思う。
ただ、、経緯を書いてこいと言われた。
29経緯なんて楽勝さ:01/10/17 16:53
経緯か、、。
俺には解らん。
俺には >>1>>28 で言っている意味が分からんのだが。
31経緯なんて楽勝さ:01/10/17 16:55
よって、、、190になるって説明か・・
32やばい:01/10/17 16:56
番地の増加分が2つと言う意味で間違いがないと思う。
多分、数え上げた振りをすればよい。
a(1, 1) 100, 101
a(1, 2) 102, 103
...
a(2, 1) 120, 121
...
a(5, 1) 180, 181
...
a(5, 6) 190, 191
それにしても変な宿題・・・・

100 102 104 106 108 110 112 114 116 118
120 122 124 126 128 130 132 134 136 138
140 142 144 146 148 150 152 154 156 158
160 162 164 166 168 170 172 174 176 178
180 182 184 186 188 190 192 194 196 198
200 202 204 206 208 210 212 214 216 218
220 222 224 226 228 230 232 234 236 238
240 242 244 246 248 250 252 254 256 258
260 262 264 266 268 270 272 274 276 278
>>34
なんで 9x9 の表?
>>1
つぅかネタでしょ?なんで質問に>>22の条件を含めなかったんだろ?
37age:01/10/17 18:23
経緯か、、、
190で間違いないけど経緯が分からんな。
39やばいい:01/10/17 18:31
ねたじゃなくて、マジスレ
40やばいい:01/10/17 18:36
もっと書きやすい経緯のあらわし方が、、あれば。。。
41やばいい:01/10/17 18:38
皆さん、ありがとうございました、
感謝しています。後は自分で考えます。
42やばいい:01/10/17 18:39
とりあえず答えが190だと言うことはわかりました。
あとはそれをどう説明するか、、考えてみます。
レポートとして出すのです。
それではめでたく終了。
44おいおい:01/10/17 19:08
なんで190になるんだ?
経緯も分からんぞ。。「
>>44
スレ読め。
46おいおい:01/10/17 19:46
まったく分からん。
>>47
うざ
49デフォルトの名無しさん:01/10/17 20:01
FORTRANとCじゃ行と列の格納順が逆だ、
というマメ知識をひけらかしたくてしょうがないんだが、
…どうでもいいですか。
5049:01/10/17 20:06
問題よく読んでなかった。すまん。
51デフォルトの名無しさん:01/10/17 20:11
>二次元配列の宿題が出されました。問題は十行十列の
>二次元配列aをメモリ上の連続した領域へ行方向に格納するとき、
>a(5,6)が格納される場所の番地はどれか。ここで番地は
>十進数表示とする。ちなみにa(1,1)の時の番地は100です。

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

すでに仮定が入ってるんですけど.
62デフォルトの名無しさん:01/10/17 21:33
>>1の学校出た人って

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

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

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

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

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

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

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

C/C++の配列が0から始まるのは、
ポインタ演算との兼ね合いのため。
80ネタ決定:01/10/17 23:58
ネタ決定
もうあげんな
>>79
>C/C++の配列が0から始まるのは、
>ポインタ演算との兼ね合いのため

つーか効率最優先だからだろ?
82デフォルトの名無しさん:01/10/18 22:47
処理系依存だけど、大抵の場合Cでは

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

だと思うけど、これらが全てバラバラとなる処理系も当然ありうるよね。
【1次元配列】の配列という説明だけは止めて欲しい
84デフォルトの名無しさん:01/10/18 23:10
所詮すべて一次元だもんな
構造体を

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でいつもエラーでとまりま
す。

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

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

たとえば type a[A][B] があったとして
a[x][y] のアドレスが a+(x*A+y)*sizeof(type) である 保証
ってありましたっけ?
ありますよ。
91デフォルトの名無しさん:01/10/19 00:20
>>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;
}
92デフォルトの名無しさん:01/10/19 00:22
※1と※2は静的な領域で、※0は動的な領域。
静的な領域はたいがい0で初期化される。

で、reallocの引数に渡すポインタが適当な値だとエラー。
0ならOKなので、※1と※2がうまく動く。
9390:01/10/19 00:22
a+(x*A+y)*sizeof(type)
でなく
a+(x*B+y)*sizeof(type)
だな。
9489:01/10/19 00:52
>>93
ああ、タイプミス。

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

これって10年前から疑問に思ってたんだけど
ほったらかしてたんだよね・・・
>>94
type a1[A][B];

typedef type t[B];
t a2[A];
として考えてみれ。
9689:01/10/19 01:33
>>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

むーん。ま、こういうもんか。
でも保証されてる っていう証拠にはならないんだよなぁ。
9790:01/10/19 01:56
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)
となります。

途中適当な所があるけど許して。
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).
>>89
結局は規格でどう定められているか、という問題でしょ。
この手の話題は Followup-To: fj.comp.lang.c だね。
イヤというほど詳細なフォローが貰えると思うよ。
10089:01/10/19 14:41
>>99
>規格でどう定められているか
まあ、そこです。
でもfjには投稿できないんだよな〜
これ、どこかで「保証されてる」って見たような気がするんだけど、
どこだったかな・・・。
二次元配列の中身(数値)がメモリー上にどのように配置されてようが、一次元ではないか?
参照しやすいように並べていればどんな方法でもいいんでない?
あればの話だけど。
103デフォルトの名無しさん:01/10/19 23:33
まげ
>>102
自前でページングやメモリインターリーブしてもなあ。。。
10598:01/10/20 00:30
>>99-101
だから規格で保証されているというに…
ANSI ISO IEC 9899-1999規格の6.5.2.1節だってば。
>>102
row-majorでなきゃ、
 char lines[NLINES][LINELEN];
 ...
 foo(lines[i]);
なんて書けなくなっちゃうだろうが。

それにでかい配列だと、a[i][j]のiとjのどっち
を動かすかで性能も大違いだろう。
107デフォルトの名無しさん:01/10/20 01:24
>>105
見たいんだけど、ansi.orgとか行っても見当たらない・・
見るとこ間違えてる?
109デフォルトの名無しさん:01/10/20 02:17
>>108
買うんですか?
こういう規格って広く一般に浸透させなければ意味ない
ということで今ならWeb上で参照できるものと思ってました・・・
だれか原文丸コピーしてくれないかなぁ
規格は原則有料。規格化団体の唯一の収入源だから。
正式規格が決まる直前のドラフトならダウンロードできる。
(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).
http://www.murkworks.net/~bketcham/n869.txt
の方が新しいとおもわれ
112デフォルトの名無しさん:01/10/20 03:27
>>110-111
ありがとう!
これで長年の疑問も氷解しました。

これが最後のageです
113デフォルトの名無しさん:01/11/23 00:28
>1
死ね死ね死ね死ね死ね死ね死ね死ね死ね
114>113:01/11/23 00:52
露骨な殺人予告はやめてください
115 :01/11/23 01:24
っていうか実行してみればわかるだろうて・・・。

printf("%p",&a[5][6] - &a[0][0]);
printf("%d", &6[5[a]] - &0[0[a]]);
>>116
コンパイルエラー