C プログラミング入門 基幹7 (水5) 04: 式・条件分岐 (if) Linux にログインし、以下の講義ページ を開いておくこと http://www-it.sci.waseda.ac.jp/ teachers/w483692/CPR1/ 2015-04-27 1 今日の内容 式 算術演算子 条件分岐 if-else 比較演算子 その他 switch-case 2 代入 (assignment) 代入演算子によって変数の内容を書き換える こと 変数の初期化と似ているが、区別されている #include <stdio.h> int main(void) { double x = 15, y = 10, s, m; s = x + y; m = s / 2.0; ... x, y を初期化 y x 15 s 10 m ?? ?? s, m を式の評価値で置き 換える(=代入) 3 基本的な演算子 (operators) 代入演算子 a = 7 (変数 a の値を 7 に書き換える) x = (複雑な式) • 式の結果を x に代入する 4 基本的な演算子 (operators) 四則演算子 x + 10 除算 乗算 y - z n * 1.5 p / q 型により結果が異なる(後述) 剰余演算子 (9 を 4 で割った余り = 1) 9 % 4 インクリメント・デクリメント a++ a-- ++a --a 変数の値を 1 増加する 変数の値を 1 減少する 後置の評価値は変更前の値、前置は変更後の値 5 その他の演算子 (1) ビット演算子 (ビットごとに行われる) 演算: シフト: & AND | << >> OR ^ XOR ~ NOT C の規格では算術シフトか論理シフ トかは未定義 関数呼び出し printf("hello") 6 その他の演算子 (2) ポインタ関係 今後の回で説明 間接演算子 *, アドレス演算子 & 要素選択 . -> キャスト (int)A サイズ演算子 sizeof(int) カンマ演算子 式1, 式2 強制的に型を変更する。 ただしルールは非常に難しい ので使うときは注意。 char を 1 とする単位で返す。 sizeof(double) == 8 など 式1の評価値は捨てられて、 結果は式2の評価値となる 7 複合代入演算子 演算と代入を同時に行う a += 7 a = a + 7 と同じ 記号の順番に注意 -= &= <<= *= |= >>= /= ^= %= 8 式の評価 (evaluation) 演算子の計算を行うこと、関数の呼び出しを することなどで、値を計算することを評価 (evaluation) という s = (x + 2) * 2; ⇓ (変数の評価) s = (5 + 2) * 2; ⇓ (+ 演算子の評価) s = 7 * 2; ⇓ (/ 演算子の評価) 代入演算も評価値を持つ s = 14; ⇓ (代入演算子の評価) 最後の評価値は捨てられる 14; x 5 関数の呼び出しも 演算子の一種 s ? 代入で書き換えられる s 14 9 演算の順序 どの演算子から演算を行うかは優先順位と結 合方向で決まっている(詳しくはリファレンス参照) 優先順位 異なる演算子の演算順番 おおよそ数学の用法に近いが、一部は直観と反す る 結合方向 同じ演算子、または優先順位が同じ演算子の順序 a+b+c は (a+b)+c (左から右) となるなど 10 代入演算について 代入演算子はその代入された値を評価値とし て持つ 代入演算子を複数つなげて、連続した代入を 行うことができる x = y = 5; x = (y = 5); x = 5; (右から左への結合) 代入演算子の評価により 5 11 printf() も評価値を持っている printf も値を返す関数である 普段はあまり利用されず、単に無視されている 標準出力 printf("Hello, world!\n"); ⇓ (printf 関数の評価) 14; Hello, world! ▮ 出力された文字数が返され るが、この場合、特にそれ を使っていないので、その まま捨てられる 12 除算演算子の注意 int 同士の除算は結果が切り捨てられて int に なる int x = 5, y = 2; int x = 5, y = 2; double z; 浮動小数点リテラル 整数リテラル double z; z ⇓ z ⇓ z ⇓ z = (x + y) / 2; (変数の評価) = (5 + 2) / 2; (+ 演算子の評価) = 7 / 2; (/ 演算子の評価) = 3; 結果が整数となった z ⇓ z ⇓ z ⇓ z = (x + y) / 2.0; = (5 + 2) / 2.0; = 7 / 2.0; = 3.5; 少なくとも一方が double なら結果は double になる 13 制御構造 逐次実行 関数は、ブロック内の文を 書かれた順に実行する 条件分岐 変数などがある条件を満た す場合だけ実行する ループ(反復) 条件を満たす間、繰り返し 実行する 基本的には、条件判断と ジャンプ(実行位置の変 更)があれば実現できる。 14 制御構文 条件分岐(今回) ループ(次回) if - else for switch - case while (goto) do - while 15 if 文 構文 if (式) 文; if (式) {ブロック} ブロックとは { } で複数 の文をまとめた部分のこと である。 { } を含めてブ ロックですが、ここでは、 わかりやすいように { } を明示的に書いています。 与えられた条件を満たす場合のみ、次の文ま たはブロックを実行するための構文 式の値は以下の様に扱われる 0 以外…真 (true); 条件を満たした 0 …偽 (false); 条件を満たさなかった 16 if の例 条件によって表示が変わる。 5 で初期化した場合 #include <stdio.h> main(void) { int x = 5; // = -3; printf("x = %d\n", x); if(x < 0) { printf("x is negative\n"); } return 0; } x = 5 ▮ −3 で初期化した場合 x = -3 x is negative ▮ 17 条件判断のための演算子 制御構造の条件式として主に使われる 成り立てば 1 (真), そうでなければ 0 (偽) 比較演算子 代入演算子 = とは異なることに注意 x == 10 x < y y != 5 x > y 論理演算子 ≠ a >= b a <= b =>, =< というものはない 複数の比較を結合する (以下 x, y は真偽値) x && y x || y !x 論理積 かつ、 and 論理和 または、 or 論理否定 ではない、not 18 条件式の例 X が 0 以上 if(x >= 0) 0 以上 20 未満 if(x >= 0 && x < 20) if((x >= 0) && (x < 20)) ☠if( 0 <= x < 20 ) 3の倍数 優先順位的には括弧 はなくてもよいが書 いた方が読みやすい 場合もある 数学でよく書かれる ような、こういう書 き方はできない if( x % 3 == 0 ) 19 if 文の書き方 (基本) 基本的にはいつでもブロックで書くのが読み やすい 同じ行に書く 次の行に書く if(x < 0) { printf("x is negative\n"); } if(x < 0) { printf("x is negative\n"); } インデントを忘れない ほかにもたくさんあるが、あまり一般的ではない https://ja.wikipedia.org/wiki/字下げスタイル 20 if 文の書き方 (その他) 以下の記法は、見づらくなることがあるので、 他との整合性が十分とれる場合のみつかう。 素人は使わない。 1文だけなので、ブロックにしない if(x < 0) printf("x is negative\n"); すべて一行で書く if(x < 0) { printf("x is negative\n"); x+=1; } 1文だけの場合、1行で書く if(x < 0) printf("x is negative\n"); 21 if 文の注意 (1) ブロックを書かない場合、次の 1 文のみが対 象となるため、書き方で勘違いをする可能性 がある ブロックがない if(x < 0) { printf("x is "); printf("negative\n"); } if (式) {ブロック} if(x < 0) printf("x is "); printf("negative\n"); 2行目は常に実行さ れる if (式) 文; 22 if 文の注意 (2) 代入演算子と等価演算子の書き間違い 代入演算子 評価値は 0 となり、 常に偽となる if(x == 0) { printf("x is zero"); } if(x = 0) { printf("x is zero"); } gcc では -Wall -Wextra などの警告オプ ションを付けていれば、指摘してくれる 23 if – else 文 構文 if (式) 文1 else 文2; 文1,2 はブロックで もよい 式が真の場合は文1を、偽の場合は文2をそれ ぞれ実行する 24 if-else 文の例 式の評価に応じて実行される部分が変わる この場合、単に x とだけ書いても、 同じ意味になる。なぜなら、 0 で ない = 真 if(x != 0) { printf("x is non-zero\n"); } else { printf("x is zero\n"); } もちろん、ブロックでなくて も構わないが、ややこしくな るので、なるべくブロックで 書いた方がよいでしょう。 25 if 文が多重になる場合 else の後の文が if 文となる場合、見た目を簡 潔に書くための定型スタイルがある if(x == 0) { ... } else { if(x == 1) { ... } else { if(x == 2) { ... if(x == 0) { ... } else if(x == 1) { ... } else if(x == 2) { ... この様な else } if の連続をぶら 下がり else (dangling else) と 呼ぶことがある。 26 switch – case 文 整数の値に従って、実行する文を制御する 今回の講義では省略する 詳細は、2013年度の第4回後半を参照 27
© Copyright 2024 ExpyDoc