条件文で(位置<サイズ)がこのような一般的なパターンになるのはなぜですか?


9

条件ステートメント(IF)では誰もがを使用(position < size)していますが、なぜですか?
慣習だけですか、それとも正当な理由がありますか?

野生で発見:

if (pos < array.length) {
   // do some with array[pos];
}

めったに見つかりません:

if (array.length > pos) {
   // do some with array[pos];
}

7
右側に「変数」がなくてもかまわない1つのケースは、ですif (MIN <= x && x <= MAX)。(一部の言語ではこれはMIN <= x <= MAX; として記述できますが、Cでは完全に合法ですが、それが何を意味すると考えているかを意味するものではありません)。
キーストンプソン


5
間隔はどのように書かれるかでは[min, max]なく関係しているかもしれません[max, min]。したがって、要素xをで記述することで、要素が区間に属することを確認するのは自然なことmin <= x <= maxです。
Andres F.

なんてこった。
トゥレインコルドバ2013

2番目の例は、次のようにさらに明確化できます(!(array.lengh <= pos))...
OldFart

回答:


48

より深いパターンは、標準の順序として「[変化するもの] [比較] [変化しないもの]」を自然に使用するというものです。位置は変わるかもしれませんが、サイズは変わらないので、この原則はあなたの例に当てはまります。

唯一の一般的な例外は、バグではなく一般的なものを回避するために、一部のプログラマーが反対の順序(ヨーダ条件と呼ばれる)を使用するようにトレーニングするときです。これは、主に私たちがアイデアを英語で表現する方法であり、ほとんどの最新のコンパイラがこれを検出して警告を発行するためです。variable = constantvariable == constant


3
開発ツールによっては、多くの場合、variable = constant構成に対して警告(またはエラー)を出します。
GalacticCowboy

5
+1。constant == variable現象の詳細については、「依田条件」を検索してください。
ジョンMガント2013年

私は自分のコードベース(例えば、最近、これと同じものを見てきたif(DBNull == row["fieldName"]) methodCall()ほとんどの時間は、私が見て、それが他の方法で回避を行ってきたので、私は狂ったかと思った。
アンドリュー・グレイに

1
また(position < size)、上限を表すことも多いので、実際lowerbound <= position < upperboundには、サイズを上限として、の一部を再表現しています。2つの制約が明示さpositionれているため、は真ん中にのみ進むことができます。
Steve314 2013年

4
それはおそらく言語に関連しています。関係がXの特性であるように、「X演算子Y」を「Xは(演算子Y)」として解析します。比較を求めることで、Xの値が良いか悪いかを尋ねます(Yはローカルで定数として扱われます)。「pos <array.length」と尋ねると、「位置は大丈夫ですか(配列の長さよりも小さいですか)?」いいえの場合、ポジションに問題があります。私に別の立場を与えてください。しかし、配列の長さについては何も問題はありません。「array.length> pos」と尋ねると、配列が短すぎる場合は配列を増やす必要があるように感じます。

14

私がこれまでに見た唯一の正当化は、それが私たちが学校で学んだ数直線または他の順序付けのようなものであるということです。たとえば、次のように数行を記述します。

<--|--|--|--|--|--|-->
   1  2  3  4  5  6

小さいものは大きいものの左側に表示されます。同じことが日付などの他の事柄にも当てはまります(カレンダーのレイアウトを考えてみてください)。

基本的には、物事の順序について自然に考える方法に要約されます。最初のフォームは、メンタル処理をあまり行う必要がないため、読みやすくなっています。


1
より小さな値に評価される式が条件の最初に来るということですか?値がランタイムを変更する場合、それが真であることをどのように確認できますか?
TulainsCórdova2013

@ user61852実行時に値が何であるかを知る必要はありません。例:実行時に計算する2つの値valueAとvalueBがあり、valueAがvalueBよりも小さいことをテストしたい。「if(valueA <valueB)」のように書きます。valueAがvalueBよりも小さくなるかどうかは重要ではありません。(少なくとも私にとっては)それを見て、valueAがvalueBより小さいときに探していることを知るのは簡単です。「if(valueB> valueA)」が表示された場合、このコードブランチをたどるとき、停止してどちらが小さいかを考える必要があります。
Becuzz 2013年

1
誤解しました。私は答えを反対票を投じた。投票したいのですが、投票を変更できるように、サイトで回答の編集を求められます。投票できるように編集してください。
トゥレインコルドバ2013

@ user61852今すぐ投票を変更できるはずです。
2013年

11

それは主に慣習の問題ですが、これは私たちの考え方に最もよく一致すると私は考えています。強調する項目を示しています。

これらを英語に翻訳すると、「位置が配列の長さよりも小さい場合」というフレーズになります。この場合、文の主語は一時的な項目です。

逆に言うと、「配列の長さが位置よりも大きい場合」は、配列の長さ(固定値と見なされます)を主語に入れ、位置(一時的)が直接オブジェクトになります。


3
実際(最後の文で)位置は前置詞の対象になります。しかし、私はあなたが言おうとしていることに同意します。言語学では、位置がトピックであり、「配列の長さ未満」がコメントであると言えます。「トピック化された構成要素を文の最初に配置する傾向(トピックの先頭)は広まっています。」en.wikipedia.org/wiki/...
LarsH

4

私の意見、そしてこれは私の意見にすぎませんが、それは読みやすさのための慣習だということです。2つは同じですが、私の脳内で異なる感じ。配列のサイズがposよりも大きいかどうか知りたくありません。posが配列サイズより小さいかどうか知りたい。

それは半分空の対半分の議論のようなものです。数学的には同じですが、私の脳は状況に応じて異なって見えます。

個人的には

if (array.lengh > pos) {
    // do some with array[pos];
}

それがバグかどうか、そしてプログラマーが何を意味しているかについて考え始めます。彼は境界チェック以外のことをしようとしていますか?

たぶん私は明るくないかもしれませんが、コードのすべての行でそのような分析をしなければならない場合、私の脳は痛いです。


3

別の方法で、誰かが試みたものを表現するために...

順序がプログラムの動作に影響を与えない場合、違いは明らかに人間が最も読みやすいものの問題です。「トピック」を左側に置くことが理にかなっている言語上の理由は次のとおりです。

言語学では、文のトピックは話されているものであり、コメントはトピックについて話されているものです。この例では、我々はそれが取り得るpositionあるトピック「配列の長さ未満」である、とコメント。英語および他の多くの言語では、トピックは通常コメントの前に表現されます。
トピック化された構成要素を文の最初に配置する傾向(トピックの先頭)が広まっています。

親指の良いルールは、(この場合、または句)文などのコードのあなたのラインを考える文が何であるかを決定することですので程度、およびできれば最初にそれを置きます。多くの場合、「約」という文は、定数ではなく変数になります。しかし、コメントには変数含まれることがあるので、それだけではいきません。


1

これは2つの要素の組み合わせであり、どちらも初期の言語がコンパイルされた元になるアセンブラ(および現在の多くのアセンブラ)に由来しています。

  1. 配列はメモリ内のゼロベースのオフセットです(つまり、データの最初のチャンクは割り当てられたメモリブロックの先頭にあります... 0インデックス)。したがって、変化するピースに0..n-1を使用します。

  2. 値が別の値(またはレジスターなど)より小さい場合の分岐は、通常、単一の命令です。したがって、単純な小なり(<)演算子を使用します。

したがって、パターンは旧式のアセンブラーからANSI-C(いくつかの点でマクロアセンブラーに似ている)に移行し、そこからJavaや他のCのような言語に移行しました。


0

他の多くの答えが言ったように、それは非常にしばしば読みやすいです:

[thing that varies] [comparison] [thing that does not vary]

私が知っているほとんどすべての人がこのスタイルを独占的に使用しています。

=割り当てと==比較に使用するCスタイルの言語には、1つの例外があります。誤って入力した場合:

if (variable = 5) ...

の代わりに:

if (variable == 5) ...

これは有効なコード行であるため、エラーは発生しません。(一部のコンパイラーおよびIDEはこれを行うことについて警告しますが、そのような単純なタイプミスがあることは依然として非常に簡単です。)

ただし、次のように記述した場合:

if (5 == variable) ...

コンパイラー/インタープリターは、有効な構成ではないため、エラーになります(とにかくほとんどの言語で)。

この切り替えは、よくヨーダ条件と呼ばれます。

更新ヨーダコンディションが役立つ場所のリストです


-1

個人的に、私はこれを好みます:

bool positionIsWithinBounds = pos < array.length;
if (positionIsWithinBounds) {
   // do some with array[pos];
}

...それはより多くのコードですが、非常に読みやすいです。


4
比較に名前を付けるための+1。しかし、実際には、このアプローチはより複雑な条件文に適しています。このような単純なケースにはあまり適していません。それは実際に私は、「アレイ」、「境界」、「中」、そしてどのようなものを私は本能的にするためにそれが何を意味するのか知っているすべての平均、考えるために停止可能posであることを> array.length。つまり、条件の意味が非常に明確になりますが、実際にはIMOを読むのが少し難しくなります。
ジョンMガント2013年

追跡するためのさらに別の名前...
Deduplicator

-1

それは好みや慣習の問題です。一貫性を保ちたい場合は、次の2つの同等の合理的な方法で対処できます。

  1. 常に「主語」を最初に置いてください(それを文と考えてください)-テストが意味する値。だから例えばあなたは書くでしょうif (age>5)

  2. または、常に小さい方の要素を最初に配置します(値は画面上で自然な順序で並べられているので、それを考えてください)。したがって、たとえばif (a<b)、このコードの大部分がaであるか、大部分がbであるかに関係なく、記述します。

どちらの規則も、2番目ではなく最初に示したスニペットを推奨するので、この特定のケースでは答えがあると思います。ここで(1)と(2)の両方に違反するコードを記述しないようにするのが賢明だと思います。これは、ほとんどの人にとって読みにくくなるためです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.