質問

このように見えたCのラインを見ました:

!ErrorHasOccured() ??!??! HandleError();

それは正しくコンパイルされており、OKに実行されているようです。エラーが発生したかどうかを確認しているようです。しかし、私はそれが実際に何をしているのか、それがどのようにそれをしているのか本当に分かりません。プログラマーがエラーについて自分の感情を表現しようとしているように見えます。

私は見たことがありません ??!??! 前にプログラミング言語では、どこにもドキュメントが見つかりませんでした。 (Googleはような検索用語に役立ちません ??!??!)。それは何をし、コードサンプルはどのように機能しますか?

役に立ちましたか?

解決

??! aです トリグラフ それはに翻訳されます |. 。だから言う:

!ErrorHasOccured() || HandleError();

これは、短絡のため、次のものと同等です。

if (ErrorHasOccured())
    HandleError();

今週の第一人者 (C ++を扱いますが、ここでは関連性があります)、私はこれを取り上げました。

トライグラフの可能性のある起源 または、@DWBがコメントで指摘しているように、EBCDICが困難であるために可能性が高い(再び)。 これ IBM DeveloperWorksボードに関する議論は、その理論を支持しているようです。

ISO/IEC 9899:1999§5.2.1.1、脚注12(h/t @random832):

Trigraphシーケンスは、7ビットUS ASCIIコードセットのサブセットであるISO/IEC 646で説明されているように、Invariantコードセットで定義されていない文字の入力を可能にします。

他のヒント

まあ、これが一般的に存在する理由は、おそらくあなたの例に存在する理由とは異なるでしょう。

それはすべて半世紀前に始まり、ハードコピー通信端子をコンピューターユーザーインターフェイスとして再利用しました。 ASR-33テレタイプであった最初のUNIXおよびC時代。

このデバイスは遅い(10 cps)、騒々しくてugい、ASCIIのキャラクターセットのビューは0x5Fで終了したため、キーはありませんでした(写真をよく見る):

{ | } ~ 

トライグラフ 特定の問題を修正するために定義されました。アイデアは、CプログラムがASR-33および他の環境で見られるASCIIサブセットを使用して、高いASCII値を欠いているということでした。

あなたの例は実際には2つです ??!, 、それぞれの意味 |, 、結果は次のとおりです ||.

しかし、ほぼ定義上、Cコードを書いている人は最新の機器を持っていました、1 だから私の推測は: 誰かが自分自身を見せたり面白がっているか、 あなたが見つけるためにコードに一種のイースターエッグを残してください。

確かにうまくいきました、それは非常に人気のある質問につながりました。

ASR-33 Teletype

ASR-33テレタイプ


1.その点で、トライグラフは最初に会ったANSI委員会によって発明されました cは暴走の成功になるため、元のCコードやコーダーのいずれもそれらを使用しなかったでしょう。

それはcです トリグラフ. ??!|, 、 それで ??!??! オペレーターです ||

すでに述べたように ??!??! 基本的に2つです トライグラフ (??!??! 繰り返します)は、交換された翻訳されたマッシュと一緒に ||, 、すなわち 論理的または, 、プリプロセッサによって。

すべてのトライグラフを含む次の表は、代替のトライグラフの組み合わせを明確にするのに役立つはずです。

Trigraph   Replaces

??(        [
??)        ]
??<        {
??>        }
??/        \
??'        ^
??=        #
??!        |
??-        ~

ソース: C:リファレンスマニュアル第5版

だから、見た目のトライグラフ ??(??) 最終的にマッピングします [], ??(??)??(??) 置き換えられます [][] など、アイデアが得られます。

トライグラフは、前処理中に置き換えられるため、使用できます cpp 愚かなものを使って、自分で出力を見るために trigr.c プログラム:

void main(){ const char *s = "??!??!"; } 

で処理してください:

cpp -trigraphs trigr.c 

のコンソール出力を取得します

void main(){ const char *s = "||"; }

ご存知のように、オプション -trigraphs 指定する必要があります cpp 警告を発します。これは方法を示しています トライグラフは過去のものであり、彼らにぶつかるかもしれない人々を混乱させる以外の現代の価値はありません.


トライグラフの導入の背後にある理論的根拠については、見たときによく理解されています ISO/IEC 646の履歴セクション:

ISO/IEC 646とその前身ASCII(ANSI X3.4)は、電気通信業界のキャラクターエンコーディングに関する既存の慣行をほぼ支持しています。

ASCIIは英語以外の言語に必要な多くの文字を提供していなかったため、 必要なキャラクターを必要としていないキャラクターをいくつか置き換えた多くの国家バリアントが作られました.

(私の強調)

したがって、本質的に、特定の国家バリアントに必要なキャラクター(トライグラフが存在するもの)が交換されました。これは、他のバリアントがまだ周りに持っていたキャラクターで構成されるトライグラフを使用した代替表現につながります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top