a = b = c = 1 + 2 * 3 - 4 / 5 て、どう読んだらええんや......
a = b = c = 1 + 2 * 3 - 4 / 5 \\
↓\\
a = (b = (c = ((1 + (2 * 3)) - (4 / 5))))
どうやったら、複数の演算子がごちゃまぜになった式の計算順序がわかるんだろう
計算の順序を理解する手順
-
演算子の**「優先順位」**を知る
-
「同じ優先順位」の演算子の**「結合法則(結合性・結合規則)」**を知る
-
優先順位と結合法則から、括弧をつけた式に変換する(=式が読めるになる!)
-
1~3を逆順に行う(=式が書けるようになる!)
-------以下は「優先順位」や「結合法則」が必要な理由なので、飛ばしてもOK------
例えば $1 + 2 * 3$のような式は、$(1 + 2) * 3$とも$1 + (2 * 3)$ともとれ、括弧を使わなければ、計算の順序があいまいになってしまう。
でも、(((((((......と永遠にも思える括弧が続く式を読みたいとは、だれも思わない。
優先順位と結合法則があると、計算の順序が定まって、忌々しくも鬱陶しい括弧を使う必要がなくなって、うれしい。
1. 演算子の「優先順位」を知る
演算子には、式のどの部分から優先して計算するかの順位、である**「優先順位」**というものがある。
例:*の方が+より優先順位が高いため、$1 + 2 * 3$は$1 + (2 * 3)$と計算する
C言語では以下のような感じ。
優先順位と評価順序
上の表では上から順に優先順位が高い
2.「同じ優先順位」の演算子の「結合法則(結合性・結合規則)」を知る
「同じ優先順位」の演算子には、**「結合法則(結合性・結合規則)」**がある。
左から先に計算することを「左結合」という。
左結合の例:+と-は同じ優先順位、かつ左結合のため、$1 + 2 + 3 - 4$は$((1 + 2) + 3) - 4$と計算する
また、右から先に計算することを「右結合」という。
右結合の例:代入演算子=は右結合のため、$a = b = c = d$は$a = (b = (c = d))$と計算する
3. 優先順位と結合法則に従って、括弧をつけた式に変換する(=式が読めるようになる!)
括弧をつけた式への変換方法
a. 括弧の内側でないもので、優先順位の最も高い演算子を探し、結合法則を確認する
b. 結合法則に従って、括弧をつける
c. a.bを繰り返し、演算子が探せなくなったら終わり
例: $a = b = c = 1 + 2 * 3 - 4 / 5$
- *と/が優先順位の最も高い演算子で左結合
- $a = b = c = 1 + (2 * 3) - (4 / 5)$
- +と-が優先順位の最も高い演算子で左結合
- $a = b = c = (1 + (2 * 3)) - (4 / 5)$
- $a = b = c = ((1 + (2 * 3)) - (4 / 5))$
- =が優先順位の最も高い演算子で右結合
- $a = b = (c = ((1 + (2 * 3)) - (4 / 5)))$
- $a = (b = (c = ((1 + (2 * 3)) - (4 / 5))))$
答え $a = (b = (c = ((1 + (2 * 3)) - (4 / 5))))$
わーい(+0)
4. 1~3を逆順に行う(=式が書けるようになる!)
つかれたので後で書く(かかない)
怒りの雑記(タグのHaskell成分)
Haskell において、(f.g.h$x)のような式も、上記の計算の順序と型さえわかればそれほど難しくない。
例:f.g.h$x
- (.)が最高で右結合
- f.(g.h)$x
- (f.(g.h))$x
先に関数同士を結合(.)していって、最後に値を適用($)する、みたいに読める
(以下さらなる怒りの雑記)
いくつかのC/C++に関するページでは、演算子の優先順位に番号を振るとき、優先順位の高い方から順に0,1,2,...としているが、
BohYoh.com【C言語講座】演算子一覧表
演算子の優先順位-Wikipedia
C++の演算子の優先順位
Haskellでは、言語仕様で優先順位(precedence)の高い方から順に9,8,...と振られており、混乱する原因なので、気を付けてほしい。てか実際、混乱した。(怒怒怒)
4.4.2 結合性宣言
あ、あと関数適用(f xの空白部分)はどの演算子よりも優先順位が高いけど、関数適用演算子($)はどの演算子よりも優先順位が低い(infixr 0)だから気を付けてね。(怒怒怒)