オブジェクト指向言語論 第三回 知能情報学部 新田直也
演算子と式 なぜ演算子が必要か? 基本的な演算子はプログラミング 言語に組み込まれている. 足し算を行う while プログラム z = x; c = 0; while (c < y) { z++; c++; } z = x + y; 書くのが楽 読むのも楽 間違えにくい 修正しやすい おまけに高速
演算子,オペランド,式 演算子: 演算を表す記号. (+, -, *, /, >, ==, …) オペランド: 演算対象となる変数,定数,式. 式: 演算子とオペランドを(正しく)結合して得られるもので何かの値を表現する. (a + b) – (c / d) a > b (a > b++)?d->x : (a = b = *c) / k 評価: 式が示す値を計算すること. 型: 変数と同様すべての式は型を持つ.
左辺値 左辺値: 値を代入できる式 左辺値でないもの 変数 x = 20; b = (c = 3); c++; 配列添字式 a[20] = 1; 間接参照式 *p = 15; 左辺値でないもの 15 = 23; a + 2 = 5; a++ = 5
式の読み方 優先順位: 式中に複数種の演算子が存在するとき,どの演算子から先に評価するか? 10 + 20 * 30 → * の方が + より強いので, 10 + (20 * 30) と同じ 結合規則: 同じ優先順位の演算子間でどちらから先に評価するか? 10 + 20 + 30 + は左から右(左結合)に評価されるので, (10 + 20) + 30 と同じ
式の書き方(1) 演算子は型を持っている. 算術演算子(+, -, *, /,…): 「数値, 数値 → 数値」 算術演算子(+, -, *, /,…): 「数値, 数値 → 数値」 関係比較演算子(<, >, ==, !=,…): 「数値, 数値 → 真偽値」 2項論理演算子(&&, ||): 「真偽値, 真偽値 → 真偽値」 代入演算子(=, +=, *=, -=, /=,…): 「左辺値, 数値 → 数値」 100 + 20 100 < 20 (100 < 20) || (100 > 20) a = (b = c)
式の書き方(2) 単項符号(+, -): 「数値 → 数値」 - x 単項論理演算子(!): 「真偽値 → 真偽値」 単項論理演算子(!): 「真偽値 → 真偽値」 3項演算子(?:): 「真偽値, 数値, 数値→ 数値」 ポインタ演算子(*), アドレス演算子(&): 「アドレス(左辺値でない) → 左辺値」 「左辺値 → アドレス」 - x ! (a == b) (100 < 20) ? 100 : 20 * a & x
式の書き方(3) 配列参照演算子([]) 「アドレス(左辺値), 数値 → 左辺値」 基本的に型を守っている限りどれだけ大きな式でも書ける. (a = b = c = d = f = g) > 0 (((a > b) || (a == b))?(a = (b = c) + d):e++) > 0 a[10]
左辺値情報の利用方法 左辺値でないものに代入できない 左辺値でないものはアドレス(格納場所)を持たない int a[100]; int *p; p = a; → ○(pが左辺値なので) a = p; → ×(aは左辺値でないので) printf(“%d\n”, &a); → ×(aは左辺値でないので) printf(“%d\n”, &p); → ○(pが左辺値なので)
算術演算子 符号演算子 四則演算子 整数剰余演算子 べき乗演算子 インクリメント/デクリメント演算子 +, - +, -, *, / % ^ +, - 四則演算子 +, -, *, / 整数剰余演算子 % べき乗演算子 ^ インクリメント/デクリメント演算子 ++, -- 前置演算 n = ++i; (i = 1 のとき n = 2) 後置演算 n = i++; (i = 1 のとき n = 1)
ビット演算子 AND演算子 & OR演算子 | NOT演算子 ~ XOR演算子 ^ 左シフト演算子 << 右シフト演算子 左シフト演算子 << 右シフト演算子 算術シフト >> 最上位に符号ビットが入る 論理シフト >>> (Javaのみ) 最上位に0が入る
関係演算子 大小比較演算子 等値演算子 注意: <, >, >=, <= ==, != <, >, >=, <= 等値演算子 ==, != 注意: 関係演算子は真偽値を返す.(真:1, 偽:0) if (a == b) { a = a + b; } a = a + (a == b) * b;
論理演算子 論理積 && 論理和 || 論理否定 !
参照演算子 メンバ参照演算子 -> ポインタ参照演算子 * 配列参照演算子 [] 手続き呼び出し演算子 ()
代入演算子 単純代入演算子 複合代入演算子 a = b ○を二項算術/ビット演算子と置いたとき, a ○= b は, a = a ○ b を意味する. 例: +=, -=, *=, /=, %=, &=, <<=, >>=, |=, ^=
三項演算子 三項演算子 (a == b) ? c : d
型変換 明示的型変換 暗黙の型変換 キャスト変換 代入変換 算術変換 double d; float f; d = (double)f; f = d; doubleが切り捨てられてfloatに変換される 算術変換 d = f + d; 精度の高いdoubleの方に合わせてから演算
プログラムを書くときの礼儀 読む人にわかり易いプログラムを書くこと. 優先順位や結合規則を知らなくても読めるように. a = b >> c + d; → a = b >> (c + d); 無理に短く書かない. a = a + (a == b) * b; → if 文を使って書く