PowerPoint

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