これは純粋な質問で、(というかそれに関するドキュメントや記事が見つからなかっただけなのですが)C言語に限らず、多くの言語でifなどでの条件式中で条件を分けなければいけないと思います。
例えば、
c
1if (a <= b < c)
では正しく評価されないと思います。
c
1if (a <= b && b < c)
でなければならないのは、どういった理由の元なのでしょうか?
ここで理由は、システム的な(コンパイル処理や実行処理中での)理由がわかればそちらのほうがいいです。
わかりにくい質問ではありますが、よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答8件
0
a < b < c
みたいに比較演算の連鎖を許容する言語処理系を作ると
a < b == c
の解釈は(a < b) and (b == c)
であることが自然でしょう。(<も==も比較演算子なので)
では、
a < b == TRUE
と書いた時(a < b) and (b == TRUE)
であることが自然ですか?
ちなみにPythonではすでに挙がっているとおり3項以上の比較演算子の連鎖が可能で、以下のような実行結果になります。
>>> 1 < 2 == True False >>> 2 > 1 == True True
(Trueは整数型の一種で、1と同一視されるので)
そのような罠があったとしても3項以上の比較演算子の連鎖を可能にするべきですか?
つまりこれを許容しますか?
という問題でしょう。
(さすがに「↑は当然だ、これでなんの問題があるの?」と質問者さんが主張するとは思ってないです)
Pythonの開発者は採用しました。
他の言語の開発者はあまり採用したくはないようです。
静的型付き言語でintとboolが別である時
int < int == bool
という型が付いた式は、
(int < int) and (int == bool)
としてintとboolに暗黙の変換を施しますか?
(int < int) and (int == bool)
としてエラーにしますか?
(int < int) == bool
と解釈しますか?
3番目だとするとint < int == int
とint < int == bool
で解釈が変わりますが気持ち悪くないですか?
どうしたらいいでしょうか?
なんとなく、
だいたいにおいて直感に反しないルールがもしできていれば、それがさまざまな言語で使われ、広がっていたでしょう。
そうなってないということは、単純にこうしたらいいんじゃないの? という方法にはなにかしら別の直感に反する挙動があってそれをうまく排除できない
ということなのかと思います。
投稿2021/05/25 00:33
編集2021/05/25 01:20総合スコア11235
0
ベストアンサー
C言語に限らず、多くの言語でifなどでの条件式中で条件を分けなければいけないと思います。
言われてみれば、確かに、2値の比較で記述するものが多いですね。
ここで理由は、システム的な(コンパイル処理や実行処理中での)理由がわかればそちらのほうがいいです。
コンピューターの原理が、”2つのレジスタを使った演算” であることが大きく影響しているからでしょう。
機械語のレベルで、アルゴリズムを考えたとき、2つのレジスタを使って演算して(加算や減算)、その結果を判定処理に使います。
Shinta's WEBSITE : COMPILER UNIX, Linux 関連の情報
コンパイル時のパース(構文解析)を検討したとき、「n個のパラメータを比較する」仕様より、「a と
b を比較する」仕様にしたほうが、単純になることは容易に想像できそうです。
という要因で、(おそらく) 2つの比較で記述するものが多いのだろうと
また、数学の話になりますが「ブール代数」や 「ド・モルガンの法則」でも、2つの値を比較することが基本です。
このようなコンピューターのアーキテクチャーを考えると、自然に、”比較は2つの値で表記する”ことになったのだろうと思います。
投稿2021/05/24 08:51
編集2021/05/25 02:24総合スコア623
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
正しく評価されない
いやいや,その言語の評価ルールの上で「正しく」評価しているわけで.
それを,
「これこれこういう場合だけは,(a <= b && b < c) という意味に特例的に(?)評価するよ」とかいう話にするとしたら,その分だけルールが複雑になる.
複雑になるということは,読むのも書くのも難易度が上がる.
…というわけで,理由としては,
「わざわざルールを複雑にしてまで得たいような機能でもないから」ではないでしょうか.
投稿2021/05/24 08:06
総合スコア11996
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/24 08:45
0
二つの被演算子から一つの結果を得る演算を二項演算と言いますが、
多くの言語では、加減乗除や、大小比較は二項演算として実現されています。
そのため、a < b < c
は、(a < b ) < c
として解釈され、true < c
またはfalse < c
となります。
a < b < c
が数学的な意味で解釈されるためには、この場合は三項演算として処理する必要があります。
a < b < c < d
だと四項演算ですね。こういう多項の処理は複雑なので、必要でないと判断されたのでしょう。
大小比較が二項演算なのは最初の高級言語であるFortran以来で、Cも含め多くの言語が踏襲しています。
大小比較を特別処理して二項演算でなくしているのはメジャーな言語ではPythonですね。
設計方針が、数学指向だったのでは無いかと思います。
FortranやCが出来た頃に比べるとCPUは強力にメモリーも莫大になったので、既存の言語はともかく、もっと多くの言語が採用してもいい気はします。
補足:
Pythonだと、
Python
1>>> x=2 2>>> 1 < x < 3 3True 4>>> (1 < x) < 3 5True 6>>> 1 < (x < 3) 7False 8>>> x=-2 9>>> -3 < x < -1 10True 11>>> (-3 < x) < -1 12False 13>>> -3 < (x < -1) 14True
と括弧を付けると意味が変わることから、「二つの被演算子から一つの結果を得る演算」の繰り返しでなく、三項全体として演算されていることが分かります。
(True
は数値の文脈では1
に自動変換されるので上記の結果になる)
投稿2021/05/24 09:45
総合スコア85901
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
c
1a <= b < c
というコードを処理する際、
c
1(a <= b) < c
として処理されます。
Cにおいて不等号は、真のとき0以外を、偽のとき0を返す演算子なので、
c
1(なんの数値かわからない) < c
という評価になり、意図していたはずの「bとcの比較」ができません。
投稿2021/05/24 07:43
編集2021/05/24 07:46総合スコア20669
0
もしかして……
c
1// b が3以上、10未満である場合 2if (3 <= b < 10)
のような書き方が出来ないのはなんでか?というお話ですかね??
これは、もう「プログラミング言語自体を作った人が、そう決めた」だけだと思います。実際にはif文の中の不等号も、足し算の「+」や掛け算「*」と同じ「演算子」、それも「左右の2値を計算して結果を出す」という「二項演算子」という種類の演算記号でしかありません。演算記号には優先度があり、たとえば「足し算より掛け算の記号を先に処理する」といったように、不等号や等号も含めて二項演算子の計算優先度がプログラミング言語ごとに決まっています。
ですので、別の方が回答されているように、「a<=b<c」は、ひだりから順番に2個の値を間に挟まる演算子(不等号)で処理し、「(a<=b) <c」というように解釈されてしまうのです。
これが嫌なら、もう3つの値の比較を一気に行えるプログラミング言語を自分で設計して作るしか無いと思います。現在そのような言語が無い理由は、多分「そんな面倒なものを作らずとも、2個の不等式をandやorで繋げば代用できるから」じゃないかな……と思ったり。
実際にプログラミング言語を設計して実装してみると判るのですが……。数式の構文をコンパイラーが解釈して実際に計算できるようにするのはクソ面倒くさいです。なので、使うか使わないか判らないし、利用頻度も低いものより、既にあるシンプルなものを組み合わせて実現できるならそれでいいじゃん?って考え方もなんとなく共感できます。
演算子の優先度についてはwikipediaに記事があるのでこちらも参考になさるとよいかとおもいます。
あと、余談ですが……。演算の優先順位が決まってるなら、まとめられる式は1つにまとめた方がいいんじゃない?という考えもあるかもしれませんが、あまりお勧めしません。理由は、演算子の優先順位はプログラミング言語によって異なる可能性があること。あと、優先順位を読み手がしならなければ、読み解く際に都度都度「どれが先だ?」と考えないといけないからです。
投稿2021/05/24 08:14
編集2021/05/24 08:26総合スコア534
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/24 08:41
2021/05/24 08:53
2021/05/24 09:04
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。