情報処理Ⅱ 第5回 2004年11月2日(火) 演算子のすべて(復習) 1. 関数呼び出し( ),配列の添字[ ],構造体のメンバ参照(., ->) 2. 単項演算子(!, 単項*, ++, 単項+, sizeof, キャストなど) 3. 乗除(2項*, /, %) 4. 加減算(2項+, 2項-) 5. シフト(<<, >>) 6. 関係(<, >, <=, >=) 7. 関係(==, !=) 8. ビット演算(&) 9. ビット演算(^) 10. ビット演算(|) 11. 論理演算(&&) 12. 論理演算(||) 13. 3項演算子(? :) 14. 代入演算子(=, +=など) 15. コンマ(,) 高い 優 先 順 位 低い 優先順位を変えたければ,( )で囲む.( )が何重にもなることがある.{ }や[ ]は, この目的で使用できない. 2 3項演算子 オペランド1 ? オペランド2 : オペランド3 例: t = (a > b) ? a : b; ⇒ if (a > b) t = a; else t = b; 演算結果は左辺値ではない まずオペランド1を評価する.それが真であればオペランド2を, 偽であればオペランド3を評価して,その値を演算結果とする. × a > b ? a : b = 10; ○ *(a > b ? a : b) = 10; a, bはポインタ変数 3項演算子の入れ子も可能だが,読みにくい 3 その他の演算子 関数呼び出し: ( ) 配列の添字: [ ] コンマ演算子: , 例: for (i = 0, p = function(p[i], 1); i < 10; i++) これらは構文の一部であり,演算子ではない. 4 代入の順序について オペランドの評価順序は,特に明記したものを除いて,不定 (処理系依存)である.式の中で同一のオブジェクトに2つ以 上の代入をしないよう心がける. 例: x=2; printf("%d, %d", ++x, ++x); の出力は 「3 4」かもしれないし,「4 3」かもしれない. 例: x % 2 ? (x = x * 3 + 1) : (x /= 2); は意 図通りに動作する(が,if文で書くほうが自然). 5 まとめ Cでは多彩な演算子が利用できる.いくつかは数学の記号に 近く,いくつかはC独特である. 各演算子には優先順位がある. 同じ優先順位の演算の評価順序を決めるのは,結合の方向 である(演算子により,「左から右」か「右から左」かが決まっ ている). 評価されない式に注意. 6 本日学ぶこと 配列(array),文字列,多次元配列 次に学ぶこと:ポインタ(pointer) 配列とポインタは,Cではきわめて重要な要素. ここでつまづくと,ろくにプログラムは作れない. 問題 配列を用いて,行列計算(和,積,逆行列,固有値などの計 算)ができるか? 7 配列とは? 配列は,同一の型のオブジェクトを1個以上連続して 記憶域(メモリ)に配置し利用するための機構である. 同一の型のオブジェクト: a[0]はint,a[1]はchar,とい うのはNG. 1個以上: 1個でもいい.0個はNG. 連続して: 隙間がない.a[10]の次はa[11],その次は a[12],…となる. 8 配列の宣言(1) int a[3]; と宣言すると,3個のint型オブジェクトを確保 する. a[0], a[1], a[2]が左辺値として使用できる. 宣言の形にも関わらず,a[3]は使用できない.代入したとき の動作は不定. 「配列は0から始まる」と覚える. a a[0] a[1] a[2] 変数名: 参照可能だが 代入は不可. オブジェクト: 代入と参照が 可能. 9 配列の宣言(2) 配列のサイズは? × 整数以外,負の数,0 × 変数や関数呼び出しを含む値 ○ 正の整数値に評価される定数式(定数のみからなる式) 一括の宣言 int a[3], b[5]; のように,一つの宣言文で複数の配列 を宣言できる. 10 ビットパターンのプログラムを配列で 0 0 1 0 1 0 0 0 y[7] y[6] y[5] y[4] y[3] y[2] y[1] y[0] 0 0 1 0 1 0 0 a 0 11 配列の初期化 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}; 12 要素数を明示しない宣言 int a[ ] = {100, 200, 300}; は int a[3] = {100, 200, 300}; と同じ. 要素数をコンパイラが決めてくれる. 要素数を決め打ちする必要がなく,将来変更する可能性のあ るとき,この書法が積極的に用いられる. × int a[ ]; 13 配列の要素数の求め方 aを配列変数とすると,sizeof(a) / sizeof(a[0]) でその要素数が求められる. 算術型に限らず,どんな型でも成立する. aがポインタ変数の場合や,mallocライブラリルーチンなどで 動的に確保した配列領域には,利用できない. 14 文字列 文字列は,末尾に '\0' のつくchar配列である. '\0' は 0 と同一.文字を意識するときに使用する. 'a' の書式を文字定数という.ただし,int型の値である. "a" の書式を文字列リテラルという. 文字列リテラルを直接書き換えることはできないが,配列変数 の初期化で代入し,そこを書き換えることは可能. 文字: 'a' 文字列: "a" 'a' '\0' 15 文字列と配列変数 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'}; と同じ. 文字列ではない. 16 文字列を書き換える例 i i i i i i i i i = 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 と出力できる? printf("i = %9d", i); の「9」を書き換える. 17 多次元配列の宣言 多次元配列: 配列の配列 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] オブジェクト: 代入と参照が 可能. 18 多次元配列の初期化 例 int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int a[3][3] = {1, 2, 3, 4}; int a[3][3] = {{1, 2}, {3, 4}}; int a[2][2][2] = {{1, 2}, {3, 4}}; int a[ ][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; 最も左だけ 省略可能 初期値が明示されて いない要素には,0が 代入される. 19 行列の積を求めるプログラム(1) 2×2の行列は int a[2][2]; で宣言. float,double,unsigned intのほうがいい場合も a と b の積を c に格納するとき: b[0][0] b[1][0] b[0][1] b[1][1] a[0][0] a[0][1] c[0][0] = a[0][0] * b[0][0] c[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][0] + a[0][1] * b[1][1] a[1][0] a[1][1] c[1][0] = a[1][0] * b[0][0] c[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][0] + a[1][1] * b[1][1] 20 行列の積を求めるプログラム(2) 一般に, n×mとm×pの行列の積を求めることができ,結果は n×pの行列になる. c[i][j] = ∑0≦k≦m-1(a[i][k] * b[k][j]) これを 0≦i≦n-1,0≦j≦p-1 に対して計算すればよい. p 3つの変数i, j, k による3重ループ m n n p 21 まとめ 「型 変数名[要素数];」と宣言すると,「変数名[0]」 ~ 「変数名[要素数-1]」が利用できる. 配列宣言と同時に,{ … } を用いて初期化も可能. 文字列は,末尾に '\0' のつく文字配列である.文字列を 配列に格納すれば,書き換えられる. 多次元配列を用いると,2次元,3次元,…に自然に情報を格 納できる. 22 次に学ぶこと ポインタ(Pointer) 問題 文字列が回文("noon", "トマト" など)かどうか判定でき る? float型の値のビットパターンを出力できる? 23 ポインタ ポインタとは? 指し示すもの 配列とはまた別の,実用的かつ多様な型を作る一つの方式 (派生型) y *y 24
© Copyright 2024 ExpyDoc