1 / 15

07: 配列

07: 配列. Linux にログインし、以下の講義ページを開いておく こと http://www-it.sci.waseda.ac.jp/teachers/w483692/CPR1 /. 復習:メモリと変数. メモリの一部に名前を付けて、数値を格納する機能= 変数 位置は自動的に決定される 表現できる値は型で規定 メモリ上でのサイズは型依存 初期値を与えない場合は 不定. int year = 2014; double value; char ch = 'C';. 変数名. 初期化 しない場合 、 値として何が入っているかはわからない. year.

Download Presentation

07: 配列

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C プログラミング入門 基幹2 (月4) 07: 配列 Linux にログインし、以下の講義ページを開いておくこと http://www-it.sci.waseda.ac.jp/teachers/w483692/CPR1/

  2. 復習:メモリと変数 • メモリの一部に名前を付けて、数値を格納する機能=変数 • 位置は自動的に決定される • 表現できる値は型で規定 • メモリ上でのサイズは型依存 • 初期値を与えない場合は不定 int year = 2014; double value; char ch = 'C'; 変数名 初期化しない場合、値として何が入っているかはわからない year value ch 2014 ?? 'C' それぞれの位置は自動で決まるので、並んでいるとは限らない C プログラミング入門 基幹2 (月4)

  3. 配列変数 • 複数個の値を連続して格納する変数 • 1つ1つを要素(element) という • 要素はインデックス(index) という整数で区別 • 最初の要素のインデックスは 0 各要素をインデックスで区別 scores 配列変数名 scores[0] scores[1] scores[2] scores[3] 4人のスコアを配列変数で格納した場合 100 95 55 43 score4 score2 score1 score3 4人のスコアを4つの変数で格納した場合 100 95 55 43 C プログラミング入門 基幹2 (月4)

  4. 配列変数の定義 (array) • 構文 • 型名 変数名[要素数]; • 普通の変数名と同じ名前は使用できない • インデックスは 0 から始まる • 要素数 n の配列の最後の要素のインデックスは n-1 日本語では 0 オリジンという。英語では zero-based などと呼ぶ score[4] はない { int score[4]; scores[0] scores[2] ?? ?? ?? ?? scores[1] scores[3] C プログラミング入門 基幹2 (月4)

  5. 配列の初期化 • 初期化には特別な構文を用いる • 指定する初期値が足りない場合は残りはすべて 0 となる 4つの要素の初期値は不定 a { int a[4]; int b[4] = { 100, 50, 20, 1 }; int c[4] = { 100, 50 }; int d[4] = { 0 }; int e[] = { 100, 50, 20, 1 }; int f[4] = { 1, 2, 3, 4, 5 }; c 100 0 ? ? 50 0 ? 0 0 ? 0 0 すべてゼロにする場合 d 要素数を省略すると初期化の要素数となる 足りない分はすべて0となる エラー C プログラミング入門 基幹2 (月4)

  6. 配列変数のアクセス • 配列変数の各要素へは通常の変数と同じようにアクセスできる • 配列全体への代入はできない { int a[4] = { 100, 50, 20, 1 }; int sum; a[0] = 99; printf("%d", a[0]); sum = a[0]+a[1]+a[2]+a[3]; a = { 100, 50, 20, 1 }; 要素への代入 要素の値を読む 計算式に要素の値を使う エラー。配列に値を一度に設定する代入演算子はない C プログラミング入門 基幹2 (月4)

  7. 配列変数とループ • 配列の利点として、ループでアクセスできる • ループ変数にインデックスを対応させる { int tri[10], i; for(i = 0; i < 10; ++i) { tri[i] = i*(i+1)/2; } 格納される値 tri[0] == 0 tri[1] == 1 tri[2] == 3 tri[3] == 6 tri[4] == 10 tri[5] == 15 ... i=3 この数列を三角数という C プログラミング入門 基幹2 (月4)

  8. 範囲外アクセスの注意 • 配列のアクセスではインデックスの範囲はチェックされない • 範囲外の値を読んだり、書きこんだりすることは理由がない限り避ける • 場合によってはシステムが検知してセグメンテーションフォルト (segmentation fault; SEGV)例外が発生してプログラムが強制終了する a[-1]としてアクセスできるがなにが入っているかは不明 a[4]としてアクセスした場合、意味のある値としては読めない a[0] a[3] pi 100 95 55 43 3.14 このようなアクセスを意図的に行う場合もある C プログラミング入門 基幹2 (月4)

  9. 配列変数の要素数 • 配列変数の要素数には限界がある • 環境依存。せいぜい数千~数万要素程度 • 巨大な領域を取るには動的メモリを用いる • 配列サイズを変更できない • プログラムの実行中に変更が必要な場合は、より高度なデータ構造を使う必要がある • 配列のコピーを行う構文はない • コピーを行う標準ライブラリ関数を用いる 今後説明 秋期の講義で扱う 今後説明 C プログラミング入門 基幹2 (月4)

  10. 配列の要素数とリテラル • C89 では要素数はリテラルでのみ指定可能 • 変数で指定することは禁止されている • GCC は独自拡張で許容している • C99 以降は可能 要素数とループの式を変数 n で統一できる { int n = 10; int tri[n], i; for(i = 0; i < n; ++i) { tri[i] = i*(i+1)/2; } -pedantic オプションで無効化できる 実用上、変数を使って困ることは少ないので、この講義でも場合によっては使うことがある C プログラミング入門 基幹2 (月4)

  11. 多次元配列 • インデックスを複数使う配列 全部で 6 (=3×2) 要素 { int A[3][2] = {{1,2},{3,4},{5,6}}; int B[3][2] = {{ 0 }}; 各要素がさらに 2 要素に分かれている 全体として 3 要素 全ての要素を 0 で初期化する場合 A[0][0] A[1][0] A[2][0] 行列で考えた場合のイメージ 1 2 3 4 5 6 A[1][1] A[2][1] A[0][1] メモリ上では初期化と同じ順に並ぶ C プログラミング入門 基幹2 (月4)

  12. 多次元配列のアクセス • 宣言と同じ書式でアクセスする A[2,1]と書いても、これ自体はコンパイルエラーとならない。なぜなら、 "2,1" はカンマ演算子の式とみなされるためである(前回参照)。しかし、結果として、 A[1]と同じ意味になるが、この式の評価は意図したものではないので(次回以降説明)結局、別の意味でエラーとなる。ただし、この場合、エラーメッセージの意味がわかりづらくなる。 { int A[3][2]; A[0][0] = 1; A[2][1] = 6; A[0][0] A[1][0] A[2][0] 行列で考えた場合のイメージ 1 ? ? ? ? 6 A[1][1] A[2][1] A[0][1] C プログラミング入門 基幹2 (月4)

  13. 例題: マルバツゲーム(Tic-tac-toe) • 3 × 3 の盤面を配列で表現 • 値の意味を右の表の通りと決める { int board[3][3] = {{0}}; inti, j; board[0][2] = 1; // O board[1][1] = 2; // X // 盤面の表示 // ...どう書く? 全要素をゼロで初期化 board[0][2] 出力 ..O .X. ... board[1][1] C プログラミング入門 基幹2 (月4)

  14. 例題: マルバツゲーム(Tic-tac-toe) // 盤面の表示 for(i= 0; i < 3; ++i) { for(j = 0; j < 3; ++j) { if(board[i][j] == 0) { printf("."); } else if(board[i][j] == 1) { printf("O"); } else if(board[i][j] == 2) { printf("X"); } } printf("\n"); } board[0][2] 出力 ..O .X. ... board[1][1] 行ごとの改行 C プログラミング入門 基幹2 (月4)

  15. 例題: マルバツゲーム / コードの工夫 // 盤面の表示 for(i= 0; i < 3; ++i) { for(j = 0; j < 3; ++j) { intx = board[i][j]; if(x == 0) { printf("."); } else if(x == 1) { printf("O"); } else if(x == 2){ printf("X"); } } printf("\n"); } あらかじめ変数に入れておく board[0][2] 比較の式が読みやすくなる このような分岐コードは、 swich-case を用いることもできる。講義では説明しない。 board[1][1] C プログラミング入門 基幹2 (月4)

More Related