簡體   English   中英

什么??!?! 運算符在 C 中做什么?

[英]What does the ??!??! operator do in C?

我看到一行 C 看起來像這樣:

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

它編譯正確,似乎運行正常。 看起來它正在檢查是否發生了錯誤,如果發生了,它會處理它。 但我不確定它實際上在做什么或它是如何做的。 看起來程序員確實在嘗試表達他們對錯誤的感受。

我從來沒見過??!??! 之前在任何編程語言中,我無法在任何地方找到它的文檔。 (谷歌不幫助搜索詞,如??!??! )。 它有什么作用以及代碼示例如何工作?

??! 是一個三合字母,翻譯成| . 所以它說:

!ErrorHasOccured() || HandleError();

由於短路,這相當於:

if (ErrorHasOccured())
    HandleError();

本周的大師(處理 C++,但在這里相關),我在那里撿到了這個。

三合字母的可能起源或正如@DwB 在評論中指出的那樣,更有可能是因為 EBCDIC 很困難(再次)。 在IBM developerWorks板的討論似乎支持這一理論。

來自 ISO/IEC 9899:1999 §5.2.1.1,腳注 12(h/t @Random832):

三字符序列允許輸入未在不變代碼集中定義的字符,如 ISO/IEC 646 中所述,這是七位美國 ASCII 代碼集的子集。

那么,為什么這通常存在可能與它在您的示例中存在的原因不同。

這一切都始於半個世紀前,將硬拷貝通信終端重新用作計算機用戶界面。 在最初的 Unix 和 C 時代,即 ASR-33 電傳打字機。

這個設備很慢(10 cps)、嘈雜和丑陋,它對 ASCII 字符集的看法以 0x5f 結束,所以它(仔細看圖片)沒有任何鍵:

{ | } ~ 

三合字母被定義為解決特定問題。 這個想法是 C 程序可以使用在 ASR-33 和其他環境中發現的 ASCII 子集,但缺少高 ASCII 值。

你的例子實際上是兩個??! , 每個意思| ,所以結果是|| .

然而,幾乎按照定義,編寫 C 代碼的人都有現代設備, 1所以我的猜測是:有人炫耀或自娛自樂,在代碼中留下一種復活節彩蛋供您找到。

它確實有效,它導致了一個廣受歡迎的 SO 問題。

ASR-33 電傳打字機

ASR-33 電傳打字機


1. 就此而言,三合字母是由 ANSI 委員會發明的,該委員會C 取得巨大成功首次見面,因此原始 C 代碼或編碼人員都不會使用它們。

這是一個 C三合字母 ??! | ,所以??!??! 是運算符||

如前所述??!??! 本質上是兩個 三合字母??!??!再次)混合在一起,被替換翻譯為|| ,即邏輯 OR ,由預處理器執行。

包含每個三合字母的下表應該有助於消除替代三合字母組合的歧義:

Trigraph   Replaces

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

來源: C:參考手冊第 5 版

所以看起來像??(??)的三合字母最終會映射到[]??(??)??(??)將被替換為[][]等等,你明白了。

由於在預處理期間替換了trigr.c字母,您可以使用cpp自己查看輸出,使用一個愚蠢的trigr.c程序:

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

並用以下方法處理它:

cpp -trigraphs trigr.c 

你會得到一個控制台輸出

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

如您-trigraphs必須指定選項-trigraphs ,否則cpp將發出警告; 這表明三合字母已成為過去,除了混淆可能會碰到它們的人之外,沒有任何現代價值


至於引入三字符背后的基本原理,在查看ISO/IEC 646 的歷史部分時會更好地理解:

ISO/IEC 646 及其前身 ASCII (ANSI X3.4) 在很大程度上認可了電信行業中有關字符編碼的現有實踐。

由於 ASCII 沒有提供除英語之外的其他語言所需的大量字符,因此制作了許多國家變體,用所需的字符替換了一些較少使用的字符

(強調我的)

因此,本質上,某些國家變體中替換了一些需要的字符(存在三合字母的字符)。 這導致使用由其他變體仍然存在的字符組成的三合字母的替代表示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM