• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:char型の二次元配列の意味が分からないのです・・・。)

char型の二次元配列の意味が分からないのです・・・。

このQ&Aのポイント
  • char型の二次元配列について分からない点があります。char型は文字1文字を表す型ですが、char[5][10]という二次元配列ではどんな文字列が入れられるのかが分かりません。
  • また、初期化でなぜ二文字の文字列を順々に並べるのかも理解できません。さらに、printfでnamae[1]と指定する理由もありません。二次元配列だからnamae[1][0]と指定するのではないのかと思います。
  • 質問者は現在混乱しており、この疑問点についてご存知の方からの説明を求めています。

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

2次元配列は「1次元配列の1次元配列」だと考えてください。 char[5][10]は char[10]の配列が5つの配列です。 char namae[5][10] = { "a1", ←これはnamae[0]にあるchar[10]の配列に入る "a2", ←これはnamae[1]にあるchar[10]の配列に入る "a3", ←これはnamae[2]にあるchar[10]の配列に入る "a4" ←これはnamae[3]にあるchar[10]の配列に入る  }; 配列を使わなければ char namae0[10] = "a1" ; char namae1[10] = "a2" ; char namae2[10] = "a3" ; char namae3[10] = "a4" ; char namae4[10] = "" ; /* 配列の大きさに満たない部分は0で初期化 */ という事です。namaeのあとの数字が配列の一つ目の添字に対応します。 >どうして初期化で"a1"という二文字を順々と並べるのか 2文字なのはたまたまで、9文字まで(\0が必要なので、10-1文字分)使えます。 並んでいるのは、上のように初期化するためです。 >printfでどうしてnamae[1]なのか printfの%sに対応するのは「文字列」、つまり、charの配列か charへのポインタです。 char[][]は「charの配列の配列」なので、対応していません。 namae[1]は「charの配列」なので、%sで対応できます。 上の例にある namae1 だったら%sで表示できるのはわかるのではないでしょうか。 >二次元配列だからnamae[1][0] これは、上の例でいえば namae1[0]です。つまり、ただのcharになります。文字列にはなりません。

rabitwo
質問者

お礼

ご回答ありがとうございます。 分かりやすくてだいぶ分かってきました!! #include <stdio.h> main() { char a[5][10] = { "abcde", "fghij", "" }; printf("a[0][1]=%c\n",a[0][1]); printf("a[0]=%s\n",a[0]); printf("a[2]=%s\n",a[2]); printf("a[2][0]=%d\n",a[2][0]); } こう書いてみたら、1番目のprintfで一文字だけ取り出せるし、2番目では文字列が出るし、3番目では文字列が入ってないし、4番目では数字の0がでます(^_^) ただ、不思議なのはint型の配列だとint[5][10]とあったときint[10]の配列が5つって考えますか? 5行、10列の数値を入れるセルがあるって考えちゃうんです。

その他の回答 (3)

回答No.4

回答はすでに出ていますが……。 実は、ポイントになるのは、「Cには2次元配列は存在しない」という事実です。(規格上はそうです) じゃ、char namae[5][10] という表現は何かと言いますと、 char name[10] という「型」の、さらに、配列 です。 もちろん、name[1][1] は、name[][1] という要素の、[1] 番目 ということですから、事実上2次元配列のように扱えます。 この事実は、後々、いろんなところでいろいろな悪さをします。 たとえば、Cでは、初期化の際、「配列の要素数は省略できる」という決まりがあります。 たとえば、 char name[] = "abcdefg"; など。 ただし、上記の場合、 char name[][10] = {"....", "....", "..."}; とはできますが、 chae name[][] = ... というのはできません。 [10] のほうは、(配列の要素数ではなくて)型の一部だからです。 これは、2次元配列のつもりで、malloc() なんかを使おうとした際にも、いろいろと、面倒を起こすことがあります。

rabitwo
質問者

お礼

ありがとうございます!! そうなんです。もうほぼ解決したのでそろそろ閉じようと思ってました(^_^; char namae[5][10]というのはnamae[10]という型の配列なのですね。namae[10]が型なので、namae[5][10]の[10]の部分は要素数を表しているのではなく、省略できない。 char namae[]="abcde"; とかはよく使うので、混同しそうですね。配列の要素数と型の違いがわかってよかったです。頭がすっきりしました!! malloc()はメモリの確保に使うんでしたっけ。まだ1,2回しか記述したことがありません(汗)。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

> ただ、不思議なのはint型の配列だとint[5][10]とあったときint[10]の配列が5つって考えますか? 5行、10列の数値を入れるセルがあるって考えちゃうんです。 これは、どう解釈するか、の違いです。 今回のは、「charの配列を『文字列』として解釈する」というCの仕様の関係で二次元配列にしたもので、仮に、string型という文字列専用の型があれば string[5]とするべきものでした。 また、char [5][10]も、「5行10列のchar型整数を入れるセルがある」と解釈することもできます。 実際、 8bitの画像データでそのように使い、 image[y][x]=100; 等とするケースもあります。 逆に int [5][10]でも、「10科目のテストの点を5人分」という場合は、int[10]の配列が5個、と考えた方がわかりやすいです。

rabitwo
質問者

お礼

ありがとうございます!! charの配列を文字列として見れば、char a[5][10]は10文字のが5個。整数を入れるものだと考えれば5行10列あるとも見れるのですね。 int型の配列でも行列以外の見方があるとわかってよかったです。これからもCの勉強がんばります(^_^)

回答No.2

> char namae[5][10] これは char [10]の配列が5つ集まった配列になります。 つまり"a1","a2",……という文字列は、それぞれ、char [10]の配列空間に代入されていることになります。 配列の名前は配列の先頭データを指すポインタと同じなので、二次元配列は一次元配列のポインタの配列と同義になります。 仮に char b1[10], b2[10], b3[10], b4[10], b5[10]; char *c[5]; とあったとき、 b1 = "a1"; b2 = "a2"; b3 = "a3"; b4 = "a4"; b5 = "a5"; c = {b1, b2, b3, b4, b5}; とするのと同じです。 そこで >printf("%s\n",namae[1]); としたとき、name[1]は、文字配列"a2"の先頭アドレスを指していることになるのです。 >二次元配列だからnamae[1][0]とかで指定するのではないのかと思うのですが。 文字列内の個々の文字要素にアクセスするときはそうなります。 例えば、 name[1][0]とすれば、それは'a'ですし、 name[1][1]とすれば、それは'2'になります。 name[1][2]なら、そこには文字列の末端を示す'\0'が入っています。

rabitwo
質問者

お礼

ご回答ありがとうございます!! char namae[5][10]をchar[10]の配列が5つ集まった配列と考えるのはNo.1さまと同じですね。char型の二次元配列はそう理解すると良いのですね。 ポインタ配列を使った説明、なんとか理解できます。c[0]はb1[0]のアドレスを格納しているのですよね。そこにあるデータがa1で。 ただ、それと >>printf("%s\n",namae[1]); >としたとき、name[1]は、文字配列"a2"の先頭アドレスを指していることになるのです。 とのつながりが明確には理解できないのですが、char型の二次元配列はchar namae[5][10]だとすれば、 namae[0]がnamae[0][10]のアドレスだという理解でいいのですか? まるで普通のchar a[5]のaがアドレスであるのと同じということでしょうか。

rabitwo
質問者

補足

すごいです!! 例えば、char a[5][10]のa[5]って5個のアドレスが配列になってるのですね!! 少なくともa[0]はa[0][10]のアドレスでした(^O^) #include <stdio.h> main() { int i; char *pt; char a[5][10] = { "abcde", "fghijk" }; pt = a[0]; for(i=0; i<=4; i++){ printf("%c", (*pt+i)); } puts(""); puts(a[1]); }

関連するQ&A

専門家に質問してみよう