这是什么?????!运算符在C中做什么?
我看到一行 C 代码,如下所示:
!ErrorHasOccured() ??!??! HandleError();
它编译正确并且似乎运行正常。看起来它正在检查是否发生了错误,如果发生了,它就会处理它。但我不太确定它实际上在做什么或它是如何做的。看起来程序员确实正在尝试表达他们对错误的感受。
我以前从未在任何编程语言中见过 ??!??!
,而且我在任何地方都找不到它的文档。 (Google 不支持像 ??!??!
这样的搜索词)。它有什么作用以及代码示例如何工作?
I saw a line of C that looked like this:
!ErrorHasOccured() ??!??! HandleError();
It compiled correctly and seems to run ok. It seems like it's checking if an error has occurred, and if it has, it handles it. But I'm not really sure what it's actually doing or how it's doing it. It does look like the programmer is trying express their feelings about errors.
I have never seen the ??!??!
before in any programming language, and I can't find documentation for it anywhere. (Google doesn't help with search terms like ??!??!
). What does it do and how does the code sample work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
??!
是一个 三字母,转换为|。所以它说:
由于短路,相当于:
本周大师 (涉及 C++,但与这里相关),我在那里找到了这个。
三字母组的可能起源 或者@DwB 在评论中指出,这更有可能是由于 EBCDIC 很困难 (再次)。 <一href="https://web.archive.org/web/20191226092436/https://www.ibm.com/developerworks/community/论坛/html/topic?id=77777777-0000-0000-0000-000014505842#77777777-0000-0000-0000-000014505849" rel="noreferrer">IBM Developerworks 板上的这个讨论似乎支持了这一理论。
来自 ISO/IEC 9899:1999 §5.2.1.1,脚注 12 (h/t @Random832):
??!
is a trigraph that translates to|
. So it says:which, due to short circuiting, is equivalent to:
Guru of the Week (deals with C++ but relevant here), where I picked this up.
Possible origin of trigraphs or as @DwB points out in the comments it's more likely due to EBCDIC being difficult (again). This discussion on the IBM developerworks board seems to support that theory.
From ISO/IEC 9899:1999 §5.2.1.1, footnote 12 (h/t @Random832):
好吧,为什么它通常存在可能与它在您的示例中存在的原因不同。
这一切都始于半个世纪前,将硬拷贝通信终端重新用作计算机用户界面。在最初的 Unix 和 C 时代,这是 ASR-33 电传打字机。
该设备速度缓慢(10 cps)、嘈杂且丑陋,其 ASCII 字符集视图以 0x5f 结束,因此(仔细观察图片)没有任何键
: codingstandard.com/rule/2-2-1-do-not-use-digraphs-or-trigraphs/" rel="noreferrer">三字母的定义是为了解决特定问题。这个想法是,C 程序可以使用 ASR-33 上以及其他缺少高 ASCII 值的环境中找到的 ASCII 子集。
但是,编写 C 代码的人几乎按照定义拥有现代设备,1 所以我的猜测是:有人炫耀或自娱自乐,在代码中为你留下了一种复活节彩蛋去寻找。
它确实有效,它引发了一个广受欢迎的SO问题。
ASR-33电传打字机
1. For that matter, the trigraphs were invented by the ANSI committee, which first met after C become a runaway success, so none of the original C code or coders would have used them.
Well, why this exists in general is probably different than why it exists in your example.
It all started half a century ago with repurposing hardcopy communication terminals as computer user interfaces. In the initial Unix and C era that was the ASR-33 Teletype.
This device was slow (10 cps) and noisy and ugly and its view of the ASCII character set ended at 0x5f, so it had (look closely at the pic) none of the keys:
The trigraphs were defined to fix a specific problem. The idea was that C programs could use the ASCII subset found on the ASR-33 and in other environments missing the high ASCII values.
However, people writing C code almost by definition had modern equipment,1 so my guess is: someone showing off or amusing themself, leaving a kind of Easter egg in the code for you to find.
It sure worked, it led to a wildly popular SO question.
ASR-33 Teletype
1. For that matter, the trigraphs were invented by the ANSI committee, which first met after C become a runaway success, so none of the original C code or coders would have used them.
如前所述
??!??!
本质上是两个 三字母(??!
和??!
再次)混合在一起,被替换翻译为||
,即逻辑或,由预处理器执行。包含每个三字母组合的下表应有助于消除替代三字母组合的歧义:
来源:C:参考手册第五版
因此,看起来像
??(??)
的三字母最终将映射到[]
、??(? ?)??(??)
将被替换为[][]
等等,你就明白了。由于在预处理过程中三字母被替换,您可以使用
cpp
自己查看输出,使用一个愚蠢的trigr.c
程序:并使用以下方法处理它:
您将获得控制台输出 正如
您所注意到的,选项
-trigraphs< /code> 必须指定,否则
cpp
会发出警告;这表明三字母已经成为过去,除了让可能遇到它们的人感到困惑之外,没有任何现代价值。至于引入三字母组合背后的基本原理,通过查看历史部分可以更好地理解ISO/IEC 646:
(强调我的)
因此,本质上,一些需要的字符(存在三字符组的字符)在某些国家变体中被替换。这导致使用由其他变体仍然存在的字符组成的三字母组的替代表示。
As already stated
??!??!
is essentially two trigraphs (??!
and??!
again) mushed together that get replaced-translated to||
, i.e the logical OR, by the preprocessor.The following table containing every trigraph should help disambiguate alternate trigraph combinations:
Source: C: A Reference Manual 5th Edition
So a trigraph that looks like
??(??)
will eventually map to[]
,??(??)??(??)
will get replaced by[][]
and so on, you get the idea.Since trigraphs are substituted during preprocessing you could use
cpp
to get a view of the output yourself, using a sillytrigr.c
program:and processing it with:
You'll get a console output of
As you can notice, the option
-trigraphs
must be specified or elsecpp
will issue a warning; this indicates how trigraphs are a thing of the past and of no modern value other than confusing people who might bump into them.As for the rationale behind the introduction of trigraphs, it is better understood when looking at the history section of ISO/IEC 646:
(emphasis mine)
So, in essence, some needed characters (those for which a trigraph exists) were replaced in certain national variants. This leads to the alternate representation using trigraphs comprised of characters that other variants still had around.
这是一个 C 三字母。
??!
是|
,因此??!??!
是运算符||
It's a C trigraph.
??!
is|
, so??!??!
is the operator||