(制御文: 条件、枝分かれ、繰り返し)
http://www.sw.it.aoyama.ac.jp/2016/CP1/lecture3.html
© 2005-16 Martin J. Dürst 青山学院大学
02B1 | 02C1 | 02C2 | |
100 points | 87 | 75 | 34 |
60 points | 1 | 13 | 52 |
errors | - | - | 1 |
not submitted | 1 | 1 | 2 |
Actual example: if (a & 1 == 1)
Intent: if ((a&1) == 1) // check if a is odd
Actual interpretation: if (a & (1==1))
(see
p. 388)
Accidental luck: The result of 1==1
(true) by chance was 1
(this is not guaranteed)
Conclusion 1: Please be careful with the priority of shift and bitwise operations
Conclusion 2: if (a & 1)
is enough (for even numbers, the
result is 0 (false), for evenodd numbers, the result is 1
(true))
int a, b, c, d, e;
buffer
is better than
buf
)leap_year
is better than uruudoshi
)(syntax (grammar) and semantics)
if
文の構文:if ( 条件式 )
文
文法には固定部分
(上記で if
、(
、)
、終端記号)
と置き換えられる部分
(非終端記号)
if
文の意味:条件式
を評価し、結果が真の場合、文
を実行
(偽の場合、文
を実行しない)
式;
(expression statement)if
statement,switch
statement, for
statement, while
statementreturn
statement,break
statement{}
)誤解を招く書き方:
if (score >= 60)
printf("60 点以上です。\n");
printf("あなたは合格です。\n");
誤解のない書き方:
if (score >= 60) {
printf("60 点以上です。\n");
printf("あなたは合格です。\n");
}
if
and else
if (score >= 60) {
printf("You got more than 60 points.\n");
} else {
printf("See you again next year.\n");
}
if
- else
if
-
else
elseif
or elsif
or
elif
if
- else if
- else
if
- ... - else
as a single structureelse if
/else
are indented at the
same level as the original if
: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));
Example: gcc 03B1.c && ./a
Example: gcc -o 03B1 03B1.c && ./03B1
How it works:
It is also possible to connect two different executions in this way.
The result of execution is the value returned from main
(0 if
successful).
Outside a program (i.e. in the shell), 0
is
true and other values are false.
Inside a C program, 0
is false and other
values are true.
switch
Statementswitch ( 式 ) {
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
を意図的に使わないとき、コメントで明記
break
の使用例switch
文の各 case
の最後if
と switch
の使い分け主な目安:
if
switch
を検討switch
を検討for
Statementfor ( 初期化; 継続条件; 次の一歩 ) {
繰り返す処理;
}
while
Statementwhile ( 継続条件 ) {
繰り返す処理;
}
for
と while
の使い分け主な目安:
for
for
while
do
... while
Statement文法:
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 が偶数の場合: a0 · b0 = ak · bk + sk = ak/2 · bk·2 + sk = ak+1 · bk+1 + sk+1 = a0 · b0 (/ は整数の割算)
ak が奇数の場合: a0 · b0 = ak · bk + sk = ak/2 · bk·2 + bk + sk = ak+1 · bk+1 + sk+1 = a0 · b0
終了条件: ai = 0
ai+1 = ai / 2 によって、 ai が毎回半減、いずれ 0 になる
結果の確認:
ai = 0 の場合、a0 · b0 = ai · bi + si = 0 · bi + si = 0 + si = si
よって ai = 0 の場合, si が出力として正しい
switch
を使用)表示の例: