• ベストアンサー

前置単項演算子の優先順位や言葉の定義

javascriptの場合 ++ や -- は前置きなら右結合、後置きなら左結合ということのようですが、この結合規則の具体例ってどういったものでしょうか。 そして例えば++a--だとどっちが先に評価されるのでしょうか。(結果は同じだとしても) また2項演算子の + や - などの結合規則は理解できるのですが、単項演算子の場合に結合規則が具体的に何のことを言っているのかどうもよくわかりません。 例えば !--abc や ++a-- のように単項演算子を並べた場合も、どのように結合して何をもって右とか左と言うのか、という点を明確にしたいです。 (特にjavascriptに限った話ではないのでjavaやcなど他の言語での解説でもかまいません) いままであやふやにしてしまっていた言葉や定義をここではっきりしたいです。 具体的な例で示していただけると助かります。

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

ECMAScript 5.1 では後置演算子の方が前置演算子よりも優先順位が高いので ++a-- は (合法だとして) ++(a--) と解釈されます. つまり「-- してから ++」となる. あと, 単項演算子の結合規則は実質的に単項演算子の位置だけで決まってしまいます. つまり, 前置演算子は右結合, 後置演算子は左結合としか解釈の仕様がありません. どういうことかというと, 中置 2項演算子では a+b+c という式を (a+b)+c a+(b+c) のどちらとも解釈できるため, (+ の場合) 左結合と指定することで前者の解釈を強制しています. ところが, 前置演算子では !~+--a のように書いても !(~(+(--a))) としか解釈できないので, 結合規則を指定する意味はありません. なお, 結合規則は「同じ優先順位を持つ演算子同士の間でどちらを優先するか」を規定するものなので, 最初の例のように優先順位が異なる演算子の間では考える必要はありません.

ankodaisuki
質問者

お礼

とても参考になりました。 ありがとうございました!

関連するQ&A

  • 優先順位について質問

    優先順位とは、結合という観点において、「それが高い演算子ほどオペランドを先に結び付ける」こういうことでしょうか? 質問2:結合規則とは、同じ優先順位の演算子において、「より右にある演算子の結びつきが優先されるのか、あるいは、より左にある演算子の結びつきが優先されるのか」を示す概念。 こういうことでしょうか?

    • ベストアンサー
    • Java
  • 優先順位の概念について質問

    質問1:優先順位や結合の規則とは、本質的に「優先順位の高い演算子ほど、オペランドをより先に結び付けられる」であり、「演算実行の優先順位」ではありませんよね? 何故そう思ったかというと次の論理式をご覧ください。 a==1 && b==0 || a==1 && b==0 ※int a==1,b==0 この論理式がtureになるプロセスとして、 a==1を評価→true    ↓ b==0を評価→true ↓ &&は、a==1 && b==0の論理式をtrueと評価 ↓ ||は、左側の論理式a==1 && b==0がtrueだから、論理式全体がtrueだと判断し、 右側の論理式の評価を行わない。 プロセスとして、こうだと思うんですけど、優先順位として||は&&より低いですよね? 優先順位が「演算実行の優先順位」を意味するならば、右側の論理式のa==1 && b==0を評価してから||の演算をするはずで矛盾します。 よって、優先順位とは本質的に、「優先順位の高い演算子ほど、オペランドをより先に結び付けられる」であり、「演算実行の優先順位ではない」といえる。 質問2:「優先順位の高い演算子ほど、オペランドをより先に結び付けられる」であれば、例えば、上記の論理式の左側を例に挙げていえば、 b==0は&&と||の2つが共有してるが、&&の方が優先順位が高いから、b==0を先に結び付けてる、その意味でも「優先順位の高い演算子ほど、オペランドをより先に結び付けられる」 は正しいですか?

    • ベストアンサー
    • Java
  • postgres 外部結合(AからB、BからC)

    postgresの外部結合で質問です。 テーブルを複数外部結合する場合、 A(左)B(右)、 A(左) C(右)と外部結合する場合のSQLはよく載っているのですが A(左)B(右)で外部結合、 そしてさらに B(左)C(右)の外部結合のSQL例がなかなか載っておらず、見つけれません。 どなたか教えてください。

  • ()の役割について

    以下は、()の定義として正しいですか? 定義1:優先順位について、()内にある演算子の方が高くなる。 例えば、 「n=(10+10)/10;」は、本来は除法のほうが優先順位が高いから10/10という計算式から行うが、()により先に10+10が計算され、それから、20/10が計算され、nは2となる。 結合の規則については、()を用いるとその結合の規則の逆になる。 例えば、 n=80/10/1/(20/5);は、()が無ければ左から計算されるが、()があるから、「(20/5)」から計算され、あとは結合の規則通り左から計算されるから、nは2になる。 定義2:「キャスト演算子」としての役割がある。具体的には、大きいデータ型から小さいそれへの型変換を可能にし、「データが失われる可能性をプログラマが承知している旨」を明示する「明示的な型変換」の役割がある。

    • ベストアンサー
    • Java
  • インクリメント演算子の前置(++a)と後置(a++)の違い

    こんにちは、Java初心者です。どなたか質問タイトルの件で教えていただけませんでしょうか。 Javaのテキストで下のようなものがあったのですが、違いがテキストの説明ではよくわかりませんでした。この場合はどう違うのですか?初心者向けに、参照、演算の詳細なタイミングを一つ一つ教えていただけないでしょうか?前置の方が2になるのはなんとなくわかりそうなのですが、後置はさっぱりなのです。。。 int x, a=1; x=++a; ⇒xの値は2 int x, a=1, x=a++1; ⇒xの値は1のまま また、実例としてはどんな場合に前置又は後置を使うのですか? よろしくお願いいたします。

    • ベストアンサー
    • Java
  • C言語の副作用に関する未定義

    C言語で副作用を持つ演算を含む場合は、その副作用が実行されるタイミングが未定義となっているようですが、 以下のコード int a[10]; int i; while (i < 10) a[i++] = i; では、 a[i++] = i; の代入演算子(=)の結合規則が右から左であるため、aのインデックスとしてiが参照されるよりも早くiの値を代入しているため、未定義にならないと思うのですが、実際はどうなのでしょうか? (a[i] = i++; の場合は完全に未定義になる。) 実際にこのようなコードを書くことは無いと思いますが、気になったもので。 もしご存知の方がおいででしたら教えていただけないでしょうか。 よろしくお願いします。

  • 数学の問題です。解答解説お願いします!

    正の整数 𝑛 に対して, 𝑛 の約数の集合を 𝐷𝑛 と定義する. 例:𝐷6 ={1,2,3,6} また, 𝐷𝑛 の要素に対して, 二項演算 ⊕, ⊗, および単項演算 ′ を以下の様に定義する. • 𝑎 ⊕ 𝑏 = LCM 𝑎, 𝑏 最小公倍数 • 𝑎 ⊗ 𝑏 = GCD 𝑎, 𝑏 最大公約数 • 𝑎′=𝑛/𝑎 このとき, 右の選択肢からブール代数と呼べるものを全て選べ. 選択肢 (a) 𝐷2,⊕,⊗ ,′, 1, 2 (b) 𝐷4,⊕,⊗ ,′, 1, 4 (c) 𝐷6,⊕,⊗ ,′, 1, 6 (d) 𝐷8,⊕,⊗ ,′, 1, 8 (e) 上の(a)~(d)の中に適切な選択肢がない

  • 演算子の結合性

    演算子のリストに結合性という項目があります. 左から右,または右から左と書いてあると思います. 演算子のリストは上にある順から優先的に計算されるので, 例えば, ex) int i = hoge + bar * baz; としたとき,bar * baz が先に計算されることは理解しています. しかし掛ける,または足すオペランドの結合性がよくわかりません. *(掛ける)は「左から右」と一覧があるサイトには書いてあります. この「左から右」は,なにから見て左(右)なのでしょうか? C言語を何年か使っていますが,コンパイラが文をどのように解釈しているのか いまだによくわかっていません. よろしくお願いします.

  • 演算の法則(結合法則、交換法則)

    有理数a、bに対して、aとbの(算術)平均をとるというように  a*b=a+b/2(2分のa+bです) として定義された*はQにおける演算である。 上記の演算(Q、*)が代数系であるとき、可換的ではあるが結合的ではないとあるのですが、よく分かりません。 具体例を挙げて分かりやすく教えていただけますか。

  • 一般の結合法則について

    代数系の公理とその補則?として2項演算をn項演算に拡張するため まず 3項演算への拡張は公理で謳い A1A2A3=(A1A2)A3=A1(A2A3) n項演算への拡張として新たに A1A2A3...An=(A1A2....An-1)An : (1) と定義したうえで (1)=(A1A2......Ak-1)(Ak....An) (任意のkに対して):(2) とやっていますよね(大概の入門書では) でも(2)は実用の結合法則と異なっていますよね? 少なくとも私はn項の式があったらどれかの2つから始めてnを減らしていきます:(3)。 最初に(2)(大きく2つに分けて)で計算することはないです。 で,お願いです「(2)⇔(3)」を証明していただくか 証明が記された本をご教示ください。