C中??!??!操作符的意思是什么

What does the C ??!??! operator do?

我看到一行C,看起来像这样:

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

它编译正确,运行正常。它似乎在检查是否发生了错误,如果发生了错误,它就会处理它。但我不太确定它到底在做什么,它是如何做的。看起来程序员确实在试图表达他们对错误的感受。

我以前从未见过任何编程语言中的??!??!,而且在任何地方都找不到它的文档。(谷歌对像??!??!这样的搜索词没有帮助)。它做什么,代码示例如何工作?


??!是一个转换为|的三角图。所以它说:

1
!ErrorHasOccured() || HandleError();

由于短路,相当于:

1
2
if (ErrorHasOccured())
    HandleError();

本周的Guru(处理C++,但这里相关),在这里我选择了这一点。

可能是三角图的起源,或者正如@dwb在评论中指出的那样,它更可能是由于EBCDIC比较困难(再次)。关于IBMdeveloperWorks板的讨论似乎支持这一理论。

根据ISO/IEC 9899:1999第5.2.1.1节脚注12(h/t@random832):

The trigraph sequences enable the input of characters that are not defined in the Invariant Code Set as
described in ISO/IEC 646, which is a subset of the seven-bit US ASCII code set.


好吧,一般来说,为什么会存在这一点可能与为什么它会存在于您的示例中不同。

这一切都始于半个世纪前,将硬拷贝通信终端重新用作计算机用户界面。在最初的Unix和C时代,这是ASR-33电传打字机。

该设备速度慢(10 cps),噪音大,外观难看,ASCII字符集的视图以0x5F结尾,因此(仔细看图片)没有任何键:

1
{ | } ~

三角图被定义为解决一个特定的问题。其想法是,C程序可以使用ASR-33和其他缺少高ASCII值的环境中的ASCII子集。

Your example is actually two of ??!, each meaning |, so the result is ||.

然而,写C代码的人几乎都有现代的设备,所以我的猜测是:有人在代码中炫耀或取笑自己,留下一个复活节彩蛋给你找。

它确实起作用了,它引出了一个非常流行的问题。

ASR-33 Teletype

&ASR-33电传打字机1。就这一点而言,三角图是由美国国家标准协会委员会发明的,该委员会在C取得巨大成功后首次开会,因此原始的C代码或编码人员都不会使用它们。


这是一个C三角。??!|,所以??!??!||的运算符。


如前所述,??!??!基本上是两个三角形(??!??!再次混合在一起,被替换为||的,即逻辑或,由预处理器。

下表包含每个三线图应有助于消除交替三线图组合的歧义:

1
2
3
4
5
6
7
8
9
10
11
Trigraph   Replaces

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

资料来源:C:A参考手册第5版

因此,一个看起来像??(??)的三角图最终将映射到[]??(??)??(??)将被[][]替换,依此类推,你就知道了。

由于在预处理过程中替换了三角图,因此可以使用cpp自己查看输出,使用一个愚蠢的trigr.c程序:

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

并通过以下方式进行处理:

1
cpp -trigraphs trigr.c

您将获得控制台输出

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

正如您所注意到的,必须指定选项-trigraphs,否则cpp将发出警告;这表明了三角图是如何成为过去的事物,除了可能会碰到它们的混淆者之外,没有现代价值。

至于引入三角图背后的基本原理,在查看ISO/IEC 646的历史部分时可以更好地理解:

ISO/IEC 646 and its predecessor ASCII (ANSI X3.4) largely endorsed existing practice regarding character encodings in the telecommunications industry.

As ASCII did not provide a number of characters needed for languages other than English, a number of national variants were made that substituted some less-used characters with needed ones.

(强调矿山)

因此,在本质上,一些需要的字符(有一个三角图的字符)被某些国家变体所取代。这就导致了使用由其他变体仍然存在的字符组成的三角图的替代表示。