山水

山水

stdbool.h は通常、次のように定義されます。

#define false   0
#define true    1

(源泉:オープンBSDマスラー、等。 )

そしてUnixプログラムには、false次のように定義された失敗ステータスコードが1つしかありません。

int
main(int argc, char *argv[])
{
    return (1);
}

完全性のために、Unixプログラムの定義は次のtrueとおりです。

int
main(int argc, char *argv[])
{
    return (0);
}

明らかに、これはvalueの正反対ですfalse。明らかにstdbool.hにあります。私が使ったバージョンはオープンBSDcoreutilsにはより多くのバージョンがあるため言葉が多い

これらの違いが発生する歴史的な理由は何ですか?

答え1

プログラムはさまざまな理由で失敗する可能性があります。たとえば、grep必要なパターンが見つからない場合、または指定されたファイルのいずれかを開くことができない場合は失敗します。

現在、Unixでは、子プロセスから親プロセスに1(符号なし)バイト値(リターンコード)を渡すことができます(どのシグナルが子プロセスを殺したか、コアが生成されたかなどに関する情報は無視しています。more詳細情報)少し後ろ)。

失敗する方法はさまざまであるため、これらのさまざまな障害をエンコードする複数の戻りコードと成功を示す1つの戻りコードを持つことが合理的です。

0)は成功を示す合理的な選択であり、残り(1-255)は失敗(および失敗の種類)を表します。

成功には17、失敗には0〜16、18〜255を使用することが完全に可能です。しかし、単純化のために成功には0、失敗には1〜255を選択します。したがって、範囲があります。成功の場合は255を使用し、失敗の場合は0〜254を使用することも同様に簡単です。ただし、これは将来の変更を8ビット以上のリターンに制限し、単一のエラーコードの範囲を単純に保ちます。

答え2

あなたはリンゴを船と比較しています。味が違います。 :-)

山水

一つ山水 0これは、cとシェルの両方でfalse [a]を意味します。

$ if ((0)); then echo true; else echo false; fi
false

または、より移植性がありますが、より複雑なテストでは、次のようになります。

$ echo $(( 22 == 23 ))
0

[a]実際に作成される内容は、10進0バイト値が(A値)祭り値の単語48に透明に変換されるASCII文字()(ほとんどのシステムではASCIIですが、他のシステムではおそらく異なるものかもしれません)です。このバイト値はfalseを意味しますか?0c char00cから

算術拡張は事実上C演算の直接コピーであるため、これはほとんどのシェルに当てはまります。そこにはいかなる違いもあってはなりません。

終了ステータス

ただし、ユーティリティの終了ステータス($?)は異なります。

$ echo "$(( 22 == 23 )) $? -- $((22 == 22 )) $?"
0 0 -- 1 0

理論

私はこれがなぜそうであるかについて私自身の意見を提示することができます。

存在する古典ロジック、意図された意味論で、真理値は真です(1またはヴェルム )、偽または偽(0またはフルサム )

命題論理真理表:真の値を1、偽の値を0とします。

nothing/emptyそれは人間の考え方をより近い方法でコード化しただけですfalse

この説明はC言語でコーディングする

ただし、エラー終了状態に1つの値しかない場合(0)が狭すぎて論理が反転し、(0)が次に変わります。成功、エラーのいくつかの考えられる理由で、より多くのコードを残します。これがシェルで使用される方法です。

答え3

真=1、偽=0の起源

真が1で偽が0である理由の歴史的背景が気になる場合、ブール代数学は1847年、ジョージ・ブル(George Bool)が「発明」したことを指摘したいと思います。これは、最初の電子コンピュータが登場するずっと前のことでした。ブール代数は Mathematical Analysis of Logic に掲載されました。プロジェクト・グーテンベルク(Project Gutenberg)のコピーを読むことができます。http://www.gutenberg.org/files/36884/36884-pdf.pdf

私はそれをよく読んだと主張していませんが、ジョージブール自身が本当に1を使用し、偽に0を使用したことを十分に見ました。


計算に対するブール効果

ブールの代数学(「ブール代数学」)は、彼の死後長い間選択され、計算に使用されるまでほとんど無視されました。シリコンベースのコンピュータの前でも、ブール代数はバイナリ電子デバイス(アナログとは対照的)で有用に使用されていました。数学論理演算子をトランジスタ配線に置き換えるのは簡単です(参照ここ)。そこでは、複数の論理ゲートが一緒に接続され、2進数を表し、単純な算術演算の実行


「if」ステートメントに関して、これらのステートメントはCPUの「条件付きジャンプ」操作で発生します。ここでジャンプはgoto高級言語ではジャンプと呼ばれます。

条件付きジャンプの場合、CPUはジャンプするかどうかを選択する便利な方法を定義する必要があります。最も一般的な2つの条件は、「0の場合はジャンプ」と「負の場合はジャンプ」です(下線付きの部分を参照)。ここ)。しかし、数値を正または負の数として解釈することは、同じCPU操作が使用されるため、主観的である可能性があります。どちらも賞賛符号付き整数は、「符号なし」整数のように機能します。

ifしたがって、これは次の理由でゼロを偽に、1を真として表すのが一般的な用語であることを意味します。

  • 符号なし整数では負/正の定義は機能しません。
  • 0 は真、1 は偽を表し、これは通常使用されるブール代数とは反対です。

シェルはなぜ違うのですか?

その反対の仕事をする殻の由来は見つけにくい。 0の成功は確かに1970年代にさかのぼります。おそらくUnixの初期バージョンでしょう。わからない)。

私の考えは、プロジェクトが1つの方法で完全に成功し、いくつかの方法で失敗することができるということです。

明らかなのは、trueandfalseコマンドが、条件付きロジックで使用するためのコマンド終了状態のシェルの解釈に従うように設計されていることです。

if first_command ; then
    second_command
fi

上記のコードは、成功するsecond_commandと実行されるという意味ですfirst_command。したがって、常に成功する論理プレースホルダーの良い名前はですtrue

答え4

これが私が考えることができる唯一の理由であり、私にとってはかなり強力に見えます。

ブール演算をコンピュータ演算に変換する最も簡単な方法は、0forFALSE1forを使用することですTRUE。これにより、これを使用するすべての操作が意味を持ちます。

TRUE  && TRUE =  TRUE  ( 1 * 1 = 1)
TRUE  && FALSE = FALSE ( 1 * 0 = 0)
TRUE  || FALSE = TRUE  ( 1 + 0 = 1)
FALSE || FALSE = FALSE ( 0 + 0 = 0)

その他など

同時に、プログラムはさまざまなエラーを報告するために複数の終了状態を必要とします。正しい終了状態をに設定してから、残りの255文字(符号なし文字)をエラー終了状態として使用する0ことが論理的です。

もちろん、今良い出口を持つことは非常に非論理的ですが1、悪い出口は引き裂かれた配置に変わります02..555

関連情報