http://www.sw.it.aoyama.ac.jp/2014/CP1/lecture3.html
© 2005-14 Martin J. Dürst 青山学院大学
実例: if (a & 1 == 1)
意図: if ((a&1) == 1) // 奇数かの判断
実体: if (a & (1==1)) (教科書 p. 388
参照)
不運の幸い: 1==1 の結果 (真) はたまたま 1
で表現 (その保証は一切ない)
結論 1: シフトやビットごと論理演算では優先度要確認
結論 2: if (a & 1) だけでも大丈夫
(偶数の場合、結果が 0 (偽)、奇数の場合、結果が 1 (真))
(identifier, 名前)
int a, b, c, d, e;buf より
buffer)uruudoshi より leap_year)if 文の構文 (文法)(syntax of the if statement (grammar))
if ( 条件式 )
文
文法には固定部分 (上記で
if、(、)、終端記号) と置き換えられる部分 (非終端記号)
がある。
文法は形だけ、意味 (動作) は別
if 文の意味(semantics of the if statement)
条件式を評価し、結果が真であれば文を実行し、偽であれば文を実行しない。
式 ; (式文, expression statement)if 文、switch 文、 for 文、
while 文などreturn 文、break 文など{}
で囲まれる複数の文のまとまり、compound statement)誤解を招く書き方:
if (score >= 60)
printf("60 点以上です。\n");
printf("あなたは合格です。\n");
誤解のない書き方:
if (score >= 60) {
printf("60 点以上です。\n");
printf("あなたは合格です。\n");
}
if と else の組み合わせif (score >= 60) {
printf("60 点以上です。\n");
} else {
printf("来年また会いましょう。\n");
}
if - else if - else
の書き方if 文と if -
else 文しかないif - else if - else
if - ... - else で考えるif (...) {
...
}
else if (...) {
...
}
else {
...
}
if - else if - else
の書き方の悪い例if (...) {
...
}
else if (...) {
...
}
else if (...) {
...
}
else {
...
}
if 文の代わり: 三項演算子(ternary operator; 条件演算子, conditional operator)
よくある一句:
if (x > y)
max = x;
else
max = y;
次が同等:
max = (x > y) ? x : y;
if 文の代わり: 条件式&& や || で if
文のようなものが作れる:
if (score >= 60) {
grade = calculate(score);
}
の代わりに
score>=60 && (grade=calculate(score));
例: gcc 03B1.c && ./a
例: gcc -o 03B1 03B1.c && ./03B1
効果:
二つの実行も上記のよう接続可能
main からの戻り値が 0
の場合は真、それ以外の場合は偽 (C 内部と逆)
switch 文の構文switch ( 式 ) {
case 定数1 :
処理1 ;
break;
case 定数2:
case 定数3:
処理2 ;
...
break;
default :
処理3 ;
break;
}
switch 文の注意点break がない場合、プログラムはそのまま続く
int a = 5, b = 1;
switch (a) {
case 4:
b = 3;
break;
case 5:
b = 7;
case 6:
b *= 3;
break;
}
実行後、b の値は 21
break
を意図的に使わないとき、コメントで明記
if と switch の使い分け主な目安:
ifswitch を検討switch を検討for 文の文法for ( 初期化; 継続条件; 次の一歩 ) {
繰り返す処理;
}
while 文の文法while ( 継続条件 ) {
繰り返す処理;
}
for と while の使い分け主な目安:
forforwhiledo ... while 文文法:
do {
繰り返す処理;
} while ( 継続条件 );
(loop invariant)
(Russian peasant multiplication)
a0, b0: 最初の (被) 乗数 (入力)
sf: 最後の合計 (出力)
目的: sf = a0 · b0
普遍条件: ai · bi + si = a0 · b0
数学的帰納法の基底:
i = 0 の場合、
初期化により s0 = 0 ⇒
a0 · b0 + s0
= a0 · b0 + 0 =
a0 · b0
証明するもの: 普遍条件が 0 ≦ i ≦ f の時に成立
数学的帰納法の帰納のステップ:
普遍条件が k 回目の最初に成り立てば、 k 回目の最後、すなわち k+1 回目の最初にも成立
ak · bk + sk = a0 · b0
ak が偶数の場合: ak · bk + sk = ak/2 · bk·2 + sk = a0 · b0 (/ は整数の割算)
ak が奇数の場合: ak · bk + sk = ak/2 · bk·2 + bk + sk = a0 · b0
よって、sk+1 = sk + ( ak が奇数の場合のみ) bk
ak+1 = ak / 2; bk+1 = bk · 2
終了条件: ai = 0
ai+1 = ai / 2 によって、 ai が毎回半減、いずれ 0 になる
結果の確認:
ai = 0 の場合、ai · bi + si = 0 · bi + si = 0 + si = si = a0 · b0
よって ai = 0 の場合, si が出力として正しい
switch を使用)表示の例: