質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

解決済

8回答

366閲覧

ifなどの条件式で条件を分割しなければいけない理由

Shoto9023

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

0クリップ

投稿2021/05/24 07:33

これは純粋な質問で、(というかそれに関するドキュメントや記事が見つからなかっただけなのですが)C言語に限らず、多くの言語でifなどでの条件式中で条件を分けなければいけないと思います。

例えば、

c

1if (a <= b < c)

では正しく評価されないと思います。

c

1if (a <= b && b < c)

でなければならないのは、どういった理由の元なのでしょうか?

ここで理由は、システム的な(コンパイル処理や実行処理中での)理由がわかればそちらのほうがいいです。

わかりにくい質問ではありますが、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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 == intint < int == boolで解釈が変わりますが気持ち悪くないですか?

どうしたらいいでしょうか?


なんとなく、

だいたいにおいて直感に反しないルールがもしできていれば、それがさまざまな言語で使われ、広がっていたでしょう。
そうなってないということは、単純にこうしたらいいんじゃないの? という方法にはなにかしら別の直感に反する挙動があってそれをうまく排除できない

ということなのかと思います。

投稿2021/05/25 00:33

編集2021/05/25 01:20
quickquip

総合スコア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
Yoshi88

総合スコア623

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

正しく評価されない

いやいや,その言語の評価ルールの上で「正しく」評価しているわけで.

それを,
「これこれこういう場合だけは,(a <= b && b < c) という意味に特例的に(?)評価するよ」とかいう話にするとしたら,その分だけルールが複雑になる.
複雑になるということは,読むのも書くのも難易度が上がる.

…というわけで,理由としては,
「わざわざルールを複雑にしてまで得たいような機能でもないから」ではないでしょうか.

投稿2021/05/24 08:06

fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/05/24 08:42

なんだろう,実生活で(数式として?) a <= b < c と書いたとしたら,これは {a,b,c} の3つの値の間の大小関係を示していて, a < c という意味合いを含む(よね?). この例なら,この記述が (a <= b && b < c) という意味に解釈されるとしたら,それは,「コード と 実生活(数学) での記述の見た目が同じになる点」が利点なのかな? とか思う. でも,だとしたら,例えば (a <= b && b > c) と評価される意図で a <= b > c というコードを書かれたら,今度は違和感が半端ない気がする. 気のせい?
fana

2021/05/24 08:45

あと, a <= b < c と (a <= b && b > c) とでは, bの評価回数が変わるのか? 同じなのか? とか,いちいち不安になりそう.
guest

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

otn

総合スコア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
swordone

総合スコア20669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2021/05/24 12:37

大勢に影響ないですが一応突っ込んでおくと、比較の演算子は規格上は 真のとき1を、偽のとき0を返すと明記されております。「0以外」でもしかしたら100だったり-1000だったりするんじゃないかと恐れる必要はありません。
guest

0

C言語に限らず、多くの言語でifなどでの条件式中で条件を分けなければいけないと思います。
とのことですが、システム的な(コンパイル処理や実行処理中での)理由というのはありません。

Pythonでは以下のように書けます。
if a <= b < c:

これは言語設計者がその言語の文法をどう決めるかだけの問題です。

投稿2021/05/24 07:40

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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
backyard

総合スコア534

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2021/05/24 08:41

> これが嫌なら、もう3つの値の比較を一気に行えるプログラミング言語を自分で設計して作るしか無いと思います。 そんなことはないでしょう。Python はできます。
backyard

2021/05/24 09:04

ついでに言うと、演算子自体をオーバーロード出来る言語であれば実現できちゃいそうですね(おそらく本題の質問からは外れてしまいますが)。言語から作らなくても、手はありますね。 実際海外掲示版で同じような話になって、実演している人がいました。Pythonほどお手軽に、ではありませんが。 https://wandbox.org/permlink/jzOmfpc1rqPVWs7M (Wandboxのサンプルコード)
guest

0

たんに、
if ((a <= b) < c)
という評価がされるだけです。
それでよければそういう記述をすればいいです
あくまで2値間の演算ですよ

投稿2021/05/24 07:57

y_waiwai

総合スコア88040

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問