Purpose of Trigraph sequences in C++?
根据C++03标准2.3/1:
Before any other processing takes place, each occurrence of one of the following sequences of three characters ("trigraph sequences") is replaced by the single character indicated in Table 1.
1
2
3
4
5
6
7 ----------------------------------------------------------------------------
| trigraph | replacement | trigraph | replacement | trigraph | replacement |
----------------------------------------------------------------------------
| ??= | # | ??( | [ | ??< | { |
| ??/ | \ | ??) | ] | ??> | } |
| ??’ | ? | ??! | | | ??- | ? |
----------------------------------------------------------------------------
在现实生活中,这意味着代码
" );
我的问题是,使用三角图的目的是什么?使用三角图有什么实际的好处吗?
答:有人提到一些欧洲键盘没有所有标点符号,所以非美国的程序员在日常生活中必须使用三角键?
upd2:默认情况下,Visual Studio 2010关闭了对Trigraph的支持。
这个问题(关于密切相关的有向图)有答案。
归根结底,ISO 646字符集没有C语法的所有字符,因此有些系统的键盘和显示器无法处理字符(尽管我认为现在这些字符非常罕见)。
一般来说,您不需要使用它们,但您需要了解它们,以准确了解遇到的问题。三角图是"
1 | '\?' |
因此,有两种方法可以避免示例问题:
1 2 3 4 5 | printf("What?\?! " ); printf("What?""?! " ); |
但是你必须记住你什么时候打两个"?"你可能正在开始一个三角学的角色(当然这绝对不是我想的东西)。
实际上,在日常生活中,我根本不担心三角图和有向图。但是你应该意识到它们,因为每隔几年你会碰到一个与它们相关的bug(剩下的时间你会诅咒它们的存在)。如果编译器能够被配置为在遇到三角图或有向图时发出警告(或出错),那就更好了,这样我就可以知道我已经得到了一些我应该故意处理的东西。
为了完整性,有向图的危险性要小得多,因为它们被作为记号处理,所以字符串文字中的有向图不会被解释为有向图。
为了在C/C++程序中使用标点符号进行有趣的教育(包括一个能让我揪头发的三叉虫),看看萨特的GOTW第86条。
附录:
在默认情况下,gcc似乎不会处理(并且会警告)三角图。其他一些编译器有关闭Trigraph支持的选项(例如IBM的)。Microsoft在VS2008中开始支持必须显式启用(使用-wall或其他方法)的警告(c4837)。
摘自
The ASCII special characters
[ ,] ,{ ,} ,| , and\ occupy character set positions designated as alphabetic by ISO. In most European national ISO-646 character sets, these positions are occupied by letters not found in the English alphabet.A set of trigraphs is provided to allow national characters to be expressed in a portable way using a truly standard minimal character set. This can be useful for interchange of programs, but it doesn't make it easier for people to read programs. Naturally, the long-term solution to this problem is for C++ programmers to get equipment that supports both their native language and C++ well. Unfortunately, this appears to be infeasible for some, and the introduction of new equipment can be a frustratingly slow process.
今天的孩子们!-)
是的,国外设备,如IBM 3270终端。3270没有花括号,如果我记得的话!如果您想在IBMMini/Mainframe上编写C,就必须对每个块边界使用可怜的三元图。幸运的是,我只需要用C语言编写软件来模拟IBM的一些小型计算机设备,而不需要在System/36上编写C软件。
看"P"键旁边:http://www.9999hp.net/keyboard/temp/1389260-big.jpg
嗯,很难说。"回车"旁边有一个额外的按钮,我可能把它放反了:可能是丢失的"["/"]"对。无论如何,如果你不得不写C,这个键盘会让你伤心。
此外,这些终端还显示EBCDIC,IBM的"本机"主机字符集,而不是ASCII(感谢PavelMinaev提醒)。
另一方面,就像GNUC指南所说:"你不需要这种大脑损伤。"GCC编译器默认情况下会禁用这个"特性"。
它们适用于缺少C++基本字符集中的一些字符的系统。不用说,这样的系统非常罕见。
在C++0X中已经提出了用于去除的三叉树。也就是说,支持它们似乎仍然有很强的论据——参见C++委员会文件N29。显然,EBCDIC是他们需要的一个主要据点。
我见过90年代早期用来帮助将PL/1程序从大型机转换为在PC上运行/编译/调试的三角图。
他们曾尝试使用pl/i to c编译器在PC上编辑pl/i,他们希望代码在移回不支持大括号的大型机时能够正常工作。我建议他们可以使用宏,比如
1 2 | #def BEGIN { #def END } |
或者作为更友好的损益表替代方案
1 2 | #def BEGIN ??< #def END ??> |
如果他们真的想得到幻想,他们可以尝试
1 2 3 4 5 6 7 | #ifdef MAINFRAME #def BEGIN ??< #def END ??> #else #def BEGIN { #def END } #endif |
然后程序看起来就像是用帕斯卡写的。他们只是滑稽地看着我,一整天都不跟我说话。我想我不怪他们。:)
是什么扼杀了这项工作,而不是三图,它是IO系统在平台之间的差异。在PC上打开文件与在大型机上打开文件大不相同,这会引入太多的Kludges,无法在两者上运行相同的代码。
一些欧洲键盘没有(不是吗?)拥有美国键盘上所有的标点符号,因为它们需要特殊字母字符的键。例如,瑞典的键盘会有一个A形环,花括号就在这里。
为了适应这些用户,三角图是一种只使用最常见的ASCII字符输入标点符号的方法。
主要是因为C标准早在1989年就引入了它们,当时在某些机器上,三角图映射到的字符存在问题。在1998发布C++标准的时候,对三叉树的需求不是很大。它们是C上的疣,它们就像C++上的疣一样。他们有必要——特别是在说英语的世界之外——这就是为什么他们被加入C。
它们的存在主要是出于历史原因。现在,大多数语言的大多数现代键盘都允许访问所有这些字符,但这曾经是一些欧洲键盘的一个问题。这就是三角图被发明的原因。
如果你不知道它们是用来干什么的,你就不应该使用它们。
不过,了解它们仍然很好,因为您可能会在代码中意外和无意地使用它们。