情報処理Ⅱ 2006年11月8日(金) 授業の進め方 構造体 プリプロセッサ 指令 その他の型 ライブラリ関数 「配列」と「ポインタ」は違うの? 「変数」と「オブジェクト」は違うの? 2年以降で さらに学習・習熟 ファイル入出力 識別子 算術型 制御文 演算子 配列・文字列 ポインタ 関数 変数の 有効範囲 再帰呼び出し プログラムの作成・ コンパイル・実行 2 本日学ぶこと 配列(array),多次元配列,文字列 次に学ぶこと:ポインタ(pointer) 配列を使ってできること 平均や分散を求める 行列の積を求める "Wakayama" という文字列を1文字ずつ分解する 3 配列とは? 配列は,同一の型のオブジェクトを1個以上連続して 記憶域(メモリ)に配置し利用するための機構である. 同一の型のオブジェクト: a[0]はint,a[1]はchar,とい うのはNG. 1個以上: 1個でもいい.0個はNG. 連続して: 隙間がない.a[10]の次はa[11],その次は a[12],…となる. 4 配列の宣言(1) int a[3]; と宣言すると,3個のint型オブジェクトを確保 する. a[0], a[1], a[2]が左辺値として使用できる. 宣言の形にも関わらず,a[3]は使用できない.代入したとき の動作は不定. 「配列は0から始まる」と覚える. a a[0] a[1] a[2] 変数名: 参照可能だが 代入は不可. オブジェクト: 代入と参照が 可能. 5 余談:オブジェクトとは 実体,object Cでは,「メモリに格納されている実体」のこと 「オブジェクト」という言葉が出てきたら, 値がメモリの中にどのような形で格納されるかを イメージすること! 「オブジェクト指向」とは完全に無関係 a a[0] a[1] a[2] 変数はオブジェクトではない… メモリに割り付けられない 配列領域はオブジェクト… メモリに割り付けられる 6 配列の宣言(2) 配列のサイズは? × 整数以外,負の数,0 × 変数や関数呼び出しを含む値 ○ 正の整数値に評価される定数式(定数のみからなる式) 一括の宣言 int a[3], b[5]; のように,一つの宣言文で複数の配列 を宣言できる. 7 配列の初期化 int x = 0; と同様に,配列も初期化できる? int a[3] = {100, 200, 300}; と書けばよい. int a[3]; a[0] = 100; a[1] = 200; a[2] = 300; と同じ. 他の宣言例 ○ ○ ○ ? × int int int int int a[3] a[3] a[3] a[3] a[3] = = = = = {100, 200, 300,}; 初期値が明示されて {100, 200}; いない要素には,0が {0}; 代入される. {}; {100, 200, 300, 400}; 8 要素数を明示しない宣言 int a[ ] = {100, 200, 300}; は int a[3] = {100, 200, 300}; と同じ. 要素数はコンパイル時に決まる.(実行時ではない.) 要素数を決め打ちする必要がなく,将来変更する可能性のあ るとき,この書法が積極的に用いられる. × int a[ ]; 9 配列の要素数の求め方 aが配列変数のとき,sizeof(a) / sizeof(a[0]) で その要素数が求められる. 算術型に限らず,どんな型に対する配列型でも成立する. aがポインタ変数の場合や,mallocなどにより動的に確保し た配列領域には,利用できない. a[0] a[1] a[2] … a[9] sizeof(a) sizeof(a[0]) 10 合計・平均・最大・最小 問題 キーボードから10個の整数を読み取り,その合計・平均・最大 値・最小値を表示するプログラムを作りなさい.整数を読み取 るには,ライブラリ関数の scanf を使いなさい. 11 scanf フォーマットに従って入力を読み込むライブラリ関数 使用例 参考:printfは,フォーマットに従って出力するライブラリ関 数 if (scanf("%d", &a) == 1) { 処理 } 不適切な使用例 while (scanf("%d", &a) != EOF) … 12 scanfの留意点 格納したい変数の型は,パターンに合わせる 格納したい変数の直前に「&」をつける 単項演算子の一つ.次回の授業で説明する. 関数の戻り値(関数を呼び出すことによって得られる値)で成 否を判断する %d ⇒ int,%f ⇒ double,%ld ⇒ longなど 読み込めた個数を返す.失敗すれば,0または負 読み込みに失敗したら,入力が進まない. 「入力が進む」⇒ストリーム 「while (scanf("%d", &a) != EOF)」と書いていて, 入力が人手でかつミスタイプをすると,無限ループに陥る 13 合計・平均・最大・最小 求め方(1) 概略 「キーボードから整数を読み取り」⇒scanf 「表示する」⇒printf 配列を使用する(使用しなくても書ける) 個々の整数と,合計・最大値・最小値はint型, 平均はdouble型とする 14 合計・平均・最大・最小 求め方(2) 求め方の詳細 forループを用いて,10個の整数を配列に格納する.途中で 読み込みに失敗したら,「input error」と出力して終了する. forループを用いて合計を求め,変数sumに格納する. 「(double)sum / 個数」により平均を求め,変数avgに格 納する. 最小値,最大値を格納する変数をそれぞれmin,maxとし,初 期値(暫定的な最小値,最大値)をいずれもa[0]とする. a[1]~a[9]のそれぞれについて,現時点でのminと比較し, 配列中の値のほうが小さければ,それを最小値とする.最大値 についても同様に処理する. 人間の目なら10個の中の最大・最小を一瞬で見つけられるが, コンピュータは2つの値の比較を繰り返して,求めなければならない. 15 多次元配列の宣言 多次元配列: 配列の配列 int a[2][2]; と宣言すると, sizeof(int)が4のとき, sizeof(a)は16 sizeof(a[0])は8 sizeof(a[0][0])は4 a 参照可能だが 代入は不可. a[0] a[1] a[0][0] a[0][1] a[1][0] a[1][1] オブジェクト: 代入と参照が 可能. 16 多次元配列の初期化(1) int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; a a[0] 1 a[1] 2 3 4 a[2] 5 6 7 8 9 a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] a[2][0] a[2][1] a[2][2] 17 多次元配列の初期化(2) 他の初期化例 int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int b[3][3] = {1, 2, 3, 4}; int c[3][3] = {{1, 2}, {3, 4}}; int d[2][2][2] = {{1, 2}, {3, 4}}; int e[2][2][2] = {{{1, 2}, {3, 4}}}; int f[ ][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; 最も左だけ 省略可能 初期値が明示されて いない要素には,0が 代入される. 18 多次元配列の使い道 行列 n行m列の実行列なら,double a[n][m]; •ただしnとmは定数とすること. •j行i列の値は,a[j][i] ゲームなどで用いられる,2次元の盤やフィールド 19 文字列 文字列は,末尾に '\0' のつくchar配列である. 「ヌル文字」または 「ナル文字」という '\0' は 0 と同一.文字を意識するときに使用する. 'a' の書式を文字定数という.ただし,int型の値である. "a" の書式を文字列リテラルという. 文字列リテラルを直接書き換えることはできないが,配列変数 の初期化で代入し,そこを書き換えることは可能. 文字: 'a' 文字列: "a" 'a' '\0' 20 配列変数に文字列を格納するには char a[ ] = "Wakayama"; は, char a[9] = {'w', 'a', 'k', 'a', 'y', 'a', 'm', 'a', '\0'}; と同じ. sizeof(a)/sizeof(a[0]) は8ではなく9. char a[9] = "Wakayama"; も同じ. char a[8] = "Wakayama"; は, char a[8] = {'w', 'a', 'k', 'a', 'y', 'a', 'm', 'a'}; と同じ. '\0' がないため,文字列ではない. 21 文字列をずらす 入力: 出力: "Wakayama" Wakayama akayamaW kayamaWa ayamaWak yamaWaka amaWakay maWakaya aWakayam Wakayama 22 文字列をずらすには (旧) word 'W' 'a' 'k' 'a' 'y' 'a' 'm' 'a' '\0' 'k' 'a' 'y' 'a' 'm' 'a' 'W' '\0' c = 'W' (新) word 'a' 23 まとめ 「型 変数名[要素数];」と宣言すると,変数名[0] ~ 変 数名[要素数-1] が利用できる. 配列宣言と同時に,{ … } を用いて初期化も可能. 配列とforループを組み合わせて,配列の各要素に対して 一律の処理をすることができる. 多次元配列を用いると,2次元,3次元,…に自然に情報を格 納できる. 文字列は,末尾に '\0' のつく文字配列である.文字列を 配列に格納すれば,書き換えられる. 24 第1回レポート課題のヒント まずは打ち込んでコンパイル・実行する. 問2,問5,問4,問3の順に検討するとよい.ただしレポート では,設問順に解答を書く. 問3の「どんな事実」は,「数学的な性質」を明示できていれ ばよい. 問5は,出力そのものをレポートにつけてはならない. プログラムを読むときには,「何を対象として」「何を使って」「何 をするか」を常に確認すること. 「簡潔な日本語で表現する」能力は,プログラムの読解や,自 分の作ったプログラムを他人に説明するときに,大いに役立つ. 見たことのない英単語は,辞書で引くか,インターネットで検 索してみる. 25
© Copyright 2025 ExpyDoc