Presentation is loading. Please wait.

Presentation is loading. Please wait.

情報処理Ⅱ 2007年11月5日(月).

Similar presentations


Presentation on theme: "情報処理Ⅱ 2007年11月5日(月)."— Presentation transcript:

1 情報処理Ⅱ 2007年11月5日(月)

2 授業の進め方 構造体 その他の型 2年以降で さらに学習・習熟 プリプロセッサ 指令 ライブラリ関数 ファイル入出力
「配列」と「ポインタ」は違うの? 「変数」と「オブジェクト」は違うの? 配列・文字列 ポインタ 関数 変数の 有効範囲 識別子 算術型 再帰呼び出し 制御文 演算子 プログラムの作成・ コンパイル・実行

3 本日学ぶこと 配列(array),多次元配列,文字列 配列を使ってできること 次に学ぶこと:ポインタ(pointer) 平均や分散を求める
行列の積を求める "Wakayama" という文字列を1文字ずつ分解する

4 配列とは? 配列は,同一の型のオブジェクトを1個以上連続して 記憶域(メモリ)に配置し利用するための機構である.
同一の型のオブジェクト: a[0]はint,a[1]はchar,というのはNG. 1個以上: 1個でもいい.0個はNG. 連続して: 隙間がない.a[10]の次はa[11],その次はa[12],…となる. 入p.237 リp.276

5 配列の宣言(1) int a[3]; と宣言すると,3個のint型オブジェクトを確保する. a a[0] a[1] a[2]
「配列は0から始まる」と覚える. 配列変数名: 参照可能だが 代入は不可. a オブジェクト: 代入と参照が 可能. a[0] a[1] a[2] 入p.237 リp.277

6 オブジェクトとは 実体,object Cでは,「メモリに格納されている実体」のこと 「オブジェクト指向」とは完全に無関係 a a[0]
「オブジェクト」という言葉が出てきたら, 値がメモリの中にどのような形で格納されるかを イメージすること! 「オブジェクト指向」とは完全に無関係 a 配列変数はオブジェクトではない… メモリに割り付けられない 緑の箱は「配列変数」を表す仮想的なもので,実体ではない.すなわちメモリ上に 一定のバイト数で割り当てられるものではない. 赤の箱は「オブジェクト」であり,メモリ上に,型に応じたバイト数で割り当てられる. 緑の箱と赤の箱を結ぶ矢印も仮想的なものであるが,次回授業で説明する「ポインタ」の 伏線となっている. a[0] a[1] a[2] 配列領域はオブジェクト… メモリに割り付けられる 入p リp.61

7 配列の宣言(2) 配列の個数(要素数,サイズ)は? 一括の宣言 × 整数以外,負の数,0 × 変数や関数呼び出しを含む値
○ 正の整数値に評価される定数式(定数のみからなる式) 一括の宣言 int a[3], b[5]; のように,一つの宣言文で複数の配列を宣言できる. リpp

8 配列の初期化 int x = 0; と同様に,配列も初期化できる? int a[3] = {100, 200, 300}; と書けばよい.
int a[3]; a[0] = 100; a[1] = 200; a[2] = 300; と同じ. 他の宣言例 ○ int a[3] = {100, 200, 300,}; ○ int a[3] = {100, 200}; ○ int a[3] = {0}; ? int a[3] = {}; × int a[3] = {100, 200, 300, 400}; 初期値が明示されていない要素には,0が代入される. リpp

9 個数を明示しない宣言 int a[ ] = {100, 200, 300}; は int a[3] = {100, 200, 300}; と同じ. 要素数はコンパイル時に決まる.(実行時ではない.) 要素数を決め打ちする必要がなく,将来変更する可能性のあるとき,この書法が積極的に用いられる. × int a[ ]; リp.194

10 配列のサイズの求め方 aが配列変数のとき,sizeof(a) / sizeof(a[0]) でそのサイズ(要素数)が求められる. a[0]
算術型に限らず,どんな配列変数でも成立する. aがポインタ変数の場合や,mallocなどにより動的に確保した配列領域には,利用できない. a[0] a[1] a[2] a[9] ここでは緑色の箱を出さない(出せない). 緑色の箱は実体を伴わない(メモリ上に割り当てられるわけではない)ので. sizeof(a)は,「変数aの配列領域が,メモリ上で何バイトを占めるか」である. この値に,「変数aの一つの要素は,メモリ上で何バイトを占めるか」で割れば, 配列のサイズが求められるということである. int a[10]; と宣言していたら,sizeof(a)/sizeof(int) でもよい. sizeof(a) sizeof(a[0]) リp.282

11 合計・平均・最大・最小 問題 キーボードから10個の整数を読み取り,その合計・平均・最大値・最小値を表示するプログラムを作りなさい.整数を読み取るには,ライブラリ関数の scanf を使いなさい. 個人的には「キーボード」も「表示する」も使いたくないのですが, これらの用語の使われ方も理解しておくべきであろうと考え,取り入れています. なぜ使いたくないかについては,「キーボードから読み取る」のも「表示する」のも, このプログラムそのものではなく,それより外の,実行環境がすることだからです.

12 scanf フォーマットに従って入力を読み込むライブラリ関数 使用例 不適切な使用例
参考:printfは,フォーマットに従って出力するライブラリ関数 使用例 if (scanf("%d", &a) == 1) { 処理 } 不適切な使用例 while (scanf("%d", &a) != EOF) … リpp

13 scanfの留意点 格納したい変数の型は,パターンに合わせる 格納したい変数の直前に「&」をつける
%d ⇒ int, %f ⇒ double, %ld ⇒ longなど 格納したい変数の直前に「&」をつける 単項演算子の一つ.次回の授業で説明する. 関数の戻り値(関数を呼び出すことによって得られる値)で成否を判断する 読み込めた個数を返す.失敗すれば,0または負 読み込みに失敗したら,入力が進まない. 「入力が進む」 ⇒ ストリーム 「while (scanf("%d", &a) != EOF)」と書いていて,数字・空白以外の入力があると,無限ループに陥る リpp

14 合計・平均・最大・最小 求め方(1) 概略 「キーボードから整数を読み取り」⇒scanf 「表示する」⇒printf 配列を使用する
合計・平均・最大・最小 求め方(1) 概略 「キーボードから整数を読み取り」⇒scanf 「表示する」⇒printf 配列を使用する 個々の整数と,合計・最大値・最小値はint型, 平均はdouble型とする 配列を使用しなくても,書ける. 入pp , pp int10.c

15 合計・平均・最大・最小 求め方(2) 求め方の詳細
合計・平均・最大・最小 求め方(2) 求め方の詳細 forを用いて,10個の整数を配列に格納する.途中で読み込みに失敗したら,「input error」と出力して終了する. forを用いて合計を求め,変数sumに格納する. 「(double)sum / 個数」により平均を求め,変数avgに格納する. 最小値,最大値を格納する変数をそれぞれmin,maxとし,初期値(暫定的な最小値,最大値)をいずれもa[0]とする. a[1]~a[9]のそれぞれについて,現時点でのminと比較し,配列中の値のほうが小さければ,それを最小値とする.最大値についても同様に処理する. 人間の目なら10個の中の最大・最小を一瞬で見つけられるが, コンピュータは2つの値の比較を繰り返して,求めなければならない.

16 多次元配列の宣言 多次元配列: 配列の配列 int a[2][2]; と宣言すると, a a[0] a[1] a[0][0] a[0][1]
sizeof(int)が4のとき, sizeof(a)は16 sizeof(a[0])は8 sizeof(a[0][0])は4 多次元配列: 配列の配列 int a[2][2]; と宣言すると, a 参照可能だが 代入は不可. a[0] a[1] オブジェクト: 代入と参照が 可能. a[0][0] a[0][1] a[1][0] a[1][1] リpp

17 多次元配列の初期化(1) int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; a a[0]
リp.279

18 多次元配列の初期化(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が 代入される. リpp multiarray.c

19 多次元配列の使い道 行列 ゲームなどで用いられる,2次元の盤やフィールド n行m列の実行列なら,double a[n][m];
j行i列の値は,a[j][i] ゲームなどで用いられる,2次元の盤やフィールド a[0][0] a[0][1] a[0][m-1] a[1][0] a[n-1][0] a[n-1][m-1] 「ゲーム」は,いわゆるテレビゲーム(ビデオゲーム)に限定しない. 将棋や囲碁でも,計算機上で実現する際には,2次元配列で表現するのが自然である.

20 文字列 文字列は,末尾に '\0' のつくchar配列である. 'a' の書式を文字定数という.ただし,int型の値である.
「ナル文字」または「ヌル文字」という 文字列は,末尾に '\0' のつくchar配列である. '\0' は 0 と同一.文字を意識するときに使用する. 'a' の書式を文字定数という.ただし,int型の値である. "a" の書式を文字列リテラルという. 文字列リテラルを直接書き換えることはできないが,配列変数の初期化で代入し,そこを書き換えることは可能. 'a' "a" 文字: 文字列: 'a' '\0' 入pp リp.51, pp.56-58, p.283

21 配列変数に文字列を格納するには 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' がないため,文字列ではない. リpp.56-58

22 文字列をずらす 入力: "Wakayama" 出力: Wakayama akayamaW kayamaWa ayamaWak
rotateword.c

23 文字列をずらすには word 'W' 'a' 'k' 'a' 'y' 'a' 'm' 'a' '\0' 'W' c = word 'a'
(旧) 'W' c = word 'a' 'k' 'a' 'y' 'a' 'm' 'a' 'W' '\0' (新)

24 まとめ 「型 変数名[要素数];」と宣言すると,変数名[0] ~ 変数名[要素数-1] が利用できる.
配列とfor文を組み合わせて,配列の各要素に対して一律の処理をすることができる. 多次元配列を用いると,2次元,3次元,…に自然に情報を格納できる. 文字列は,末尾に '\0' のつく文字配列である.文字列を配列に格納すれば,書き換えられる.


Download ppt "情報処理Ⅱ 2007年11月5日(月)."

Similar presentations


Ads by Google