Java勉強中なんですが、参考書を読んでいて「多次元配列は、実際には配列の配列である。つまり、2次元配列(array[][])がある場合、実際にはこれをarray[0]、array[1]、array[2]、といった1次元配列に配列として扱う事ができる。」と書いてあり、例題で、

double array[][] = new double[5][];

array[0] = new double[500];
array[0] = new double[400];
array[0] = new double[300];
array[0] = new double[200];
array[0] = new double[100];

と書いてありました。これについてのこれ以上の説明はなく、理解できなくて困っています。ご教授宜しくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

usjさん、こんんちは。


初心者の方には、「配列の配列」といわれても分かりづらいかもしれませんね。
こんな例えはどうでしょう。小学校には当然小学生がいますね。ここで「小学生」という型があります。小学生が数人~数十人で「学級」と固まり(型)となります。つまり「学級」とは「小学生」の1次元配列といえます。
次に「学級」が複数集まって「学年」という固まり(型)となります。つまり、「学年」とは「学級」の1次元配列であり、「小学生」の2次元配列と言えます。
同様に考えると「小学校」という固まり(型)は「学年」の1次元配列であり、「学級」の2次元配列であり、「小学生」の3次元配列と言えます。
この考え方でいくと「小学校」は「小学生」の3次元配列ですが、その中間の固まり「学級」、「学年」を1種の型と考えられます。
ここで、1つの「学級」が他の「学級」と「小学生」の人数は「常に同数」とは限りませんね。同様に1つの「学年」が他の「学年」と「学級」の数が一致するとは限りませんね。
Javaの配列に対する概念-「配列の配列」は、まさしくこのことです。つまり、「小学生」3次元配列「小学校」を考える場合、その中間を成す1次元配列「学級」、2次元配列「学年」も型と考えましょう。しかも、それぞれの構成要素数はバラバラになることがありますよ。といった具合です。
 では、多次元配列が「配列の配列」ではないとどうなるのでしょうか。「小学校」が「小学生」の3次元配列であることは一緒です。しかし、その中間「学級」、「学年」は、人間が考える分にはかまわないが、プログラミング言語としては分けて考えませんよ。しかも、それぞれを更生する数、(すべての「学年」の「学級」の数、すべての「学級」の「小学生」の数)は常に一致しますよ、ということです。ある「学年」は2「学級」で済むのに、他の「学年」が5「学級」必要だから、すべての「学年」で「学級」は5つ用意しないさいといっているようなもので、2「学級」ですんだ「学年」は3つ無駄にしていますね。逆に5つ用意しても、新入生が多すぎて6つ以上必要になったら、対応できませんね。これは、ちょっと不便ですね。
 ただ、1「学年」の「学級」の数、1「学級」の「小学生」の数が常に一致するのは、管理する先生方は管理はしやすいでしょうね。そうなんです。逆に、Javaの多次元配列を扱うときは、構成する要素の数が一致するとは限らないことに注意が必要なんです。
まだ勉強したてでは、まだ分からないかもしれませんが、ちょっと複雑なプログラムを構築すると出会う場面ですので、留意してください。

理解を深めてもらえましたでしょうか。
    • good
    • 0

実際に図を書いたほうが分かりやすいのではないでしょうか?



通常の1次元配列はこんな感じです。

a[0] a[1] a[2] a[3]
□  □  □  □

で、2次元配列はこんな感じです。

    a[][0] a[][1] a[][2]
a[0][] □    □   □  ← ※
a[1][] □    □   □

※の行だけを見ると、a[0]という配列の1つに対して、a[0][1]~a[0][2]という配列が存在するという形になっています。

これが2次元配列は、ary[0]…といった1次元配列の配列として扱うことができるという意味になります。

これでどうでしょうか?
    • good
    • 0

入力ミスか、本の印刷ミスかわかりませんが、こうですよね?


 array[0] = new double[500];
 array[1] = new double[400];
 array[2] = new double[300];
 array[3] = new double[200];
 array[4] = new double[100];

「2次元配列(array[][])がある場合、実際にはこれをarray[0]、array[1]、array[2]、といった1次元配列に配列として扱う事ができる。」

○日本語で説明すると・・・
普通array[0]といったら、配列ではない「ひとつの値」や「ひとつのObject」だけれど、array[0]に配列Object(配列arrとする)が保存されるときがあり、これが二次元配列です。
言い換えれば、arr[]はarrの配列であると表現するとき、array[0][]はarray[0]の配列である。すなわち、『1次元配列の配列として扱うことができる』

○式で説明すると・・・
普通の配列arrを作ります。
double arr[] = new double[5];
この普通の配列が、arr1,arr2,arr3と沢山出来てしまうので、これも配列として保存したいと考えます。イメージとしてはこんな風にしたいのです。
 //間違った宣言
 double array[] = {arr1,arr2,arr3};
これが二次元配列です。でも注意書きに書いたように、これは間違った宣言です。
そこで、Java的に正しい宣言を次のように書きます。
double[][] array = new double[5][];
 double[] arr1 = new double[10];
 double[] arr2 = new double[10];
 double[] arr3 = new double[10];
 double[] arr4 = new double[10];
 double[] arr5 = new double[10];
array[0] = arr1;//arr1はarray[0]の配列
array[1] = arr2;
array[2] = arr3;
array[3] = arr4;
array[4] = arr5;

コンナふうにダラダラ書くとわけがわからなくなるので、単純化したのが
はじめの式になります。
double[][] array = new double[5][];
 array[0] = new double[500];
 array[1] = new double[400];
 array[2] = new double[300];
 array[3] = new double[200];
 array[4] = new double[100];

あまり説明できてるような気がしませんが・・・
    • good
    • 0

このQ&Aに関連する人気のQ&A

Java 参考書」に関するQ&A: submitとは?

Java 配列」に関するQ&A: 定数配列の書き方

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QCなどで要素の数が固定できない配列はどうやって実現しますか?

配列について質問します。

BASIC系では配列は動的配列で要素の数が自由に変えられます。
ですが、C等では宣言時に配列の要素の数を決めておかねばならなかったと思います。
もし、C等で要素の数がわからないけど、配列を使いたい場合、どうすればいいのでしょうか?
どのように実現するのでしょうか?
配列と同じ使い勝手なら配列でなくともかまいません。

今はVBAでプログラムを組んでいるので、動的配列を使えばすむのですが、いずれ他の言語に移植したいので、できるだけ使わないようにしたいと思っています。

よろしくお願いいたします。

Aベストアンサー

malloc等のメモリ確保はNo.1さんの回答のリンクが詳しいですね。
C言語でプログラムを組む場合は、大抵はこれらメモリ操作関数のお世話になります。

これに加えて、C++やJavaのライブラリでは、動的配列クラスというものが使えます。
C++だとvectorやlist、JavaだとVectorやArrayListあたりですね。
他にも、言語や環境に依存したライブラリ、フレームワークで
様々な動的配列の機構が用意されていたりします。

簡単にまとめると、
・malloc、free、realloc等を使う方法 → ReDim
・動的配列クラス → Collection
のようなものだと考えてください。

Q&= ~0x0c; &= ~0x03; |=1;

JavaScriptで分からないコードがあるので教えてください。


■変数設定
var hoge = 0;


■変数格納
・キーを押した時の条件分岐
  ~なら hoge |= 1;
  または hoge |= 2;
  または hoge |= 3;
  または hoge |= 8;

・キーを離した時の条件分岐
  ~なら hoge &= ~0x0c;
  または hoge &= ~0x03;


■変数使用
・swithch文の条件分岐に利用
  (hoge&0x03)
  (hoge&0x0c)


■質問
・どういう意味でしょうか?
・文字コード?
・ビット演算?

Aベストアンサー

ビット演算してるわね

x = x + a

x += a
って書くことができるの

つまり
hoge |= 1

hoge = hoge | 1
のことね

~はNOTのこと

0x
はアスキーコードの16進数表記ねきっと

0x0c は改ページを意味していて
0x03 は文章の最後を意味している
と思われるわ
全文がないので推測だけど

QC#かJavaで、配列の中から別の配列を探し出す

お世話になります。

C#かJava(CやC++は入れない)で、特定の配列の中に、該当する
配列があるかどうかを調べるメソッドがあれば、教えてください。

例えば…

int[] a={0,0,0,1,2,3,4,5,6,7};
int[] b={3,4,5};

ならば、『5』が返ってくるなどです。

力技では、aの配列を順にみていき、bの一番目と同じなら、
お互いの配列の次の要素を比較…などとやっていくのですが、
これらの方法を、標準のメソッドがあれば…と思い、
質問させていただきました。

以上、よろしくお願いいたします。

Aベストアンサー

Javaだけの話です。(以下、indexはbの添字)
int型配列aに含まれるint型配列bの要素の先頭の添字だけ欲しい場合
Arrays.binarySearch(a,b[index]);
int型配列aに含まれるint型配列bの要素の全添字欲しい場合
Arrays.binarySearch(a,from,to,b[index]);//from,toは配列aの走査対象要素

配列がオブジェクト型でもいいなら、Listを実装したクラス(ArrayListなど)に放り込みます。

オブジェクト型配列aに含まれるオブジェクト型配列bの要素があるか否か
listA.contains(b[index]);
オブジェクト型配列aに含まれるオブジェクト型配列bの要素の先頭の添字だけ欲しい場合
listA.indexOf(b[index]);
オブジェクト型配列aに含まれるオブジェクト型配列bの要素の最後の添字だけ欲しい場合
listA.lastIndexOf(b[index]);

最初に見つかる添字だけ欲しいなら標準ライブラリで取得できますが、
全添字が欲しいとなると途端に泥臭くなります。

Javaだけの話です。(以下、indexはbの添字)
int型配列aに含まれるint型配列bの要素の先頭の添字だけ欲しい場合
Arrays.binarySearch(a,b[index]);
int型配列aに含まれるint型配列bの要素の全添字欲しい場合
Arrays.binarySearch(a,from,to,b[index]);//from,toは配列aの走査対象要素

配列がオブジェクト型でもいいなら、Listを実装したクラス(ArrayListなど)に放り込みます。

オブジェクト型配列aに含まれるオブジェクト型配列bの要素があるか否か
listA.contains(b[index]);
オブジェクト型配列aに含まれるオ...続きを読む

Qjavaについて教えてください。java初心者です。int arr[] = new int[

javaについて教えてください。

java初心者です。

int arr[] = new int[] { 3, 1, 4, 1, 5, 9, 2, 6 };はどういうことなんでしょうか?
教えてください。

Aベストアンサー

int[] arr = new int[8];
arr[0] = 3;
arr[1] = 1;
arr[2] = 4;
arr[3] = 1;
arr[4] = 5;
arr[5] = 9;
arr[6] = 2;
arr[7] = 6;

https://ideone.com/OMAI0E

QC言語の2次元配列 容量が大きすぎる場合の対処方法

私はC言語をもちいて2次元配列を作ろうとしています。

しかし、配列数が double c[10000][10000];
と大きいものにすると、エラーになってしまいます。

もちろん小さい double c[10][10];
のような配列では問題ありません。

malloc関数とかも調べたのですがなかなかいい文献が見つからずに
困っています。
どうかいいご意見があればよろしくお願いします。

Aベストアンサー

No.5です。
>今はa[],b[]に10000個の配列があります。これをc[a][b]に格納するためにどうするか、例文を書いていただいてもよろしいでしょうか?

例文ではありませんが、感じだけ書きましたので参考にしてください。
パラメタの順序や型は正しくないと思いますので、各関数はよく調べて使ってください。あくまで、こんな感じ、ということです。
-------------------
#include <stdio.h>
#include <io.h>

double read_c(FILE *fp, int x, int y) {
 double c;
 fseek(fp,(x*10000+y)*8L, SEEK_SET);
 fread(&c, 1,8, fp);
 return c;
}

void write_c(FILE *fp, double *c, int x, int y) {
 fseek(fp,(x*10000+y)*8L, SEEK_SET);
 fwrite(c, 1,8, fp);
}

int main(void)
{
 FILE *fp;
 double c,s;
 int x,y;
 int a[10000],b[10000];
 
 fp = fopen("c.dat","w+b");// double c[10000][10000]; の意味
 
 for(x=0; x<10000; x++) {
  for(y=0; y<10000; y++) {
   c=a[x]*b[y];
   write_c(fp, &c, x,y);// c[x][y]=a[x]*b[y]; の意味
  }
 }
 
 for(x=0; x<10000; x++) {
  s=0;
  for(y=0; y<10000; y++) {
   s += read_c(fp, x,y);// s += c[x][y]; の意味
  }
  b[x] = s / 10000;
 }
 
 fclose(fp);
 return 0;
}

No.5です。
>今はa[],b[]に10000個の配列があります。これをc[a][b]に格納するためにどうするか、例文を書いていただいてもよろしいでしょうか?

例文ではありませんが、感じだけ書きましたので参考にしてください。
パラメタの順序や型は正しくないと思いますので、各関数はよく調べて使ってください。あくまで、こんな感じ、ということです。
-------------------
#include <stdio.h>
#include <io.h>

double read_c(FILE *fp, int x, int y) {
 double c;
 fseek(fp,(x*10000+y)*8L, SEEK_SET);...続きを読む

QString a = "a"; と String b = new String ("b"); の違い

String a = "a";
String b = new String ("b");

お伺いしたいのですが、
b は String のインスタンスを作ってると思いますが、
a はどんなことをしてるのでしょうか?

Aベストアンサー

お二人の回答を具体的に言うと、こういうことです。
String a1 = "a";
String a2 = "a";
String b1 = new String ("b");
String b2 = new String ("b");

a1のために、aという文字列のインスタンスが作られますが、
a2に代入されるのは、a1に使われたインスタンスが再利用されます。
これは、
if(a1 == a2) System.out.print("a1と同じインスタンス");
の結果でもわかります。

一方、b1とb2は、bという文字列オブジェクトを引数に、新しいインスタンスを生成する指示がありますので、b1とb2と、その初期化に使った無名のStringインスタンスの3つがメモリ上に存在することになります。
if(b1 != b2) System.out.print("b1とは違うインスタンス");
の結果でもわかると思います。

したがって、
String b = new String ("b"); というのは、Integerに例えると
Integer i = new Integer(new Integer(1)); という処理を
していることになり、ひとつ無駄なインスタンス生成となります。

お二人の回答を具体的に言うと、こういうことです。
String a1 = "a";
String a2 = "a";
String b1 = new String ("b");
String b2 = new String ("b");

a1のために、aという文字列のインスタンスが作られますが、
a2に代入されるのは、a1に使われたインスタンスが再利用されます。
これは、
if(a1 == a2) System.out.print("a1と同じインスタンス");
の結果でもわかります。

一方、b1とb2は、bという文字列オブジェクトを引数に、新しいインスタンスを生成する指示がありますので、b1とb2と、その...続きを読む

Qc言語の配列の先頭アドレスが偶数アドレスとなる理由について

c言語の配列の先頭アドレスが偶数アドレスとなる理由について

下記のように実行結果をで見ると、配列Sの先頭アドレスと配列Cの先頭アドレス共に偶数アドレスなる理由を教えて頂きたい。

/*list0105*/
#include <stdio.h>
main()
{

char na=1;
char nb=1;
char c[2] ={1,2};
char s[3] = {1,2,3};
char nc=1;
char nd=1;

printf("%p\n",&na);
printf("%p\n",&nb);
printf("%p %p \n", &c[0],&c[1] );
printf("%p %p %p \n", &s[0],&s[1] ,&s[2] );
printf("%p\n",&nc);
printf("%p\n",&nd);


}

実行結果
0xbffff8cf
0xbffff8ce
0xbffff8cc 0xbffff8cd ← c配列
0xbffff8b0 0xbffff8b1 0xbffff8b2 ← S配列
0xbffff8af
0xbffff8ae

c言語の配列の先頭アドレスが偶数アドレスとなる理由について

下記のように実行結果をで見ると、配列Sの先頭アドレスと配列Cの先頭アドレス共に偶数アドレスなる理由を教えて頂きたい。

/*list0105*/
#include <stdio.h>
main()
{

char na=1;
char nb=1;
char c[2] ={1,2};
char s[3] = {1,2,3};
char nc=1;
char nd=1;

printf("%p\n",&na);
printf("%p\n",&nb);
printf("%p %p \n", &c[0],&c[1] );
printf("%p %p %p \n", &s[0],&s[1] ,&s[2] );
pr...続きを読む

Aベストアンサー

メモリの配置はコンパイラとコンパイルオプションに依存します。
デフォルトだと、32ビットのメモリ処理単位=4バイトとか8バイトが多いかと。
理由は32ビットCPUが4バイト単位でメモリにアクセスするのでアクセス効率を優先したためです。

例えば、
0xbffff8cc 0xbffff8cd ← c配列
0xbffff8ce 0xbffff8cf 0xbffff8d0 ← S配列
だとしたら、S配列の内容全てを参照するためにCPUは0xbffff8ccと0xbffff8d0の合計8バイトにアクセスする必要が出てきます。無駄ですよね。

Q[[prototype]] =__proto__?

[[prototype]] と __proto__ は、同じ意味でしょうか?

Aベストアンサー

__proto__は非標準で実装依存なので、その点で同じではありません。

例えば、Firefoxの場合、下記ページに
__proto__ - JavaScript | MDN
https://developer.mozilla.org/ja/docs/JavaScript/Reference/Global_Objects/Object/proto
> An Object's __proto__ property references the same object as its internal [[Prototype]]
とあるので、Firefoxに関しては同じと見なせると思います。

もっとも、__proto__を実装しているブラウザはたいてい[[Prototype]]を意図して実装していると思われますし
現実的には同じものだと考えてしまっても理解する上で特に問題は無いかと思います。

QC言語でunsigned char配列を連結する方法ってありますか?

C言語でunsigned char配列を連結する方法ってありますか?

例えば
unsigned char test[]={0x00,0x02,0x03};
unsigned char test2[]={0x05,0x06};
という配列があったとして

test[]という配列のあとにtest2の配列を追加することは可能でしょうか?
{0x00,0x02,0x03,0x05,0x06}という配列になればOKです。

よろしくお願いします。

Aベストアンサー

testの領域は3バイトのため、それ以上の配列を追加することは出来ません。
もし、testのサイズが5バイト以上あれば、test2を追加することは、できます。
その場合は、memcpy(&test[3],test2,2); とすれば、
testの4バイト目からあとに、test2の2バイトが追加されます。
新たに配列を作成して良いなら、
unsigned char test3[5];として
memcpy(test3,test,3);
memcpy(&test3[3],test2,2);
とすれば、test3はtestとtest2を連結したものとなります。

Q[クラス名].[メソッド名].[メソッド名]という書き方。

javaを勉強している者です。

少しピンと来ない書き方があるのですがそれはタイトルの通りの書き方で、具体的には

Main.getMailStore().isNewMail()

という書き方です。MailというのがクラスでgetMailStore()というのがそのクラスで宣言されているメソッドで下記のように実装されています。(MailStoreというのはインターフェースとして別のファイルで宣言されています。)

private static MailStore _mailStore;

public static MailStore getMailStore(){
return _mailStore;
}

(MailStoreというインターフェースの中にisNewMailというメソッドは宣言されています。)

public interface MailStore{
public boolean isNewMail(String uid);
}

これらだと、最初のMain.getMailStore().isNewMail()というのは、
「まず、MainクラスのgetMailStoreメソッドを呼び出して、そこでreturnされてくるMailStore型のクラスの中の、isNewMailメソッドを呼び出している」というのを一回で書いてしまっている書き方ということで合っているでしょうか?少しピンと来ないので・・(特にreturnされるメソッド(getMailStore)にそのまま.[メソッド]という書き方をのっけるあたりが)

よろしくお願いします。

javaを勉強している者です。

少しピンと来ない書き方があるのですがそれはタイトルの通りの書き方で、具体的には

Main.getMailStore().isNewMail()

という書き方です。MailというのがクラスでgetMailStore()というのがそのクラスで宣言されているメソッドで下記のように実装されています。(MailStoreというのはインターフェースとして別のファイルで宣言されています。)

private static MailStore _mailStore;

public static MailStore getMailStore(){
return _mailStore;
}

(MailSt...続きを読む

Aベストアンサー

あってます。


人気Q&Aランキング

おすすめ情報