题
据C ++'03标准2.3 / 1:
任何其他处理发生之前,三个字符(“三字母序列”)以下序列之一的每次出现是由表1中所示的单个字符代替
---------------------------------------------------------------------------- | trigraph | replacement | trigraph | replacement | trigraph | replacement | ---------------------------------------------------------------------------- | ??= | # | ??( | [ | ??< | { | | ??/ | \ | ??) | ] | ??> | } | | ??’ | ˆ | ??! | | | ??- | ˜ | ----------------------------------------------------------------------------
在现实生活中,这意味着该代码printf( "What??!\n" );
将导致印刷What|
因为??!
是将被替换为字符|
一个三字符序列。
我的问题是,使用三字母的目的是什么?有没有使用三字母的任何实际的好处?
UPD :在回答中提到,一些欧洲键盘没有所有的标点字符,那么非美程序员们在日常生活中使用的三字母
<强> UPD2 强>:Visual Studio 2010中具有三字母支持默认关闭
解决方案
这个问题(关于密切相关有向图)有问题的答案。
它归结为一个事实,即ISO 646字符集不具备C语法的所有字符,所以也有一些系统与键盘和显示器无法用文字处理(虽然我想象的是,这些是非常罕见的现今)。
在一般情况下,你不需要使用它们,但你需要知道他们正是你遇到了这个问题。三合字母是该“?
”字符具有一个转义序列的原因:
'\?'
那么几种方法你能避免你的例子问题是:
printf( "What?\?!\n" );
printf( "What?" "?!\n" );
但你在打字的时候两记“?”你可能会开始一个三字符的字符(和它肯定是从来没有的东西,我想)。
在实践中,三字母和连字是什么我不担心在所有的某一天到一天的基础。但是你应该知道他们,因为每一次几年你会遇到与他们有关的错误(你会花一天的休息咒骂他们的所有脑干)。这将是很好,如果编译器可以被配置为警告(或错误),当它遇到一个三字符或有向图,所以我知道我已经得到的东西,我应该明知处理。
和公正的完整性,有向图是很危险的要少得多,因为他们得到处理作为标记,所以字符串文本内有向图不会得到解释为有向图。
有关的各种乐趣不错的教育,在C / C ++程序(包括三字符错误,会defintinely有我拉我的头发)标点符号,看一看的香草Sutter的GOTW#86文章。
附录:
它看起来像GCC不会处理(和将警告)默认三字母组合。其他一些编译器有选项关闭对三字符的支持(IBM的例子)。微软开始支持必须明确启用在VS2008警告(C4837)(使用-Wall或东西)。
其他提示
从The C++ Programming Language
特别版,829页
在ASCII特殊字符
[
,]
,{
,}
,|
和\
占据由ISO指定为字母字符集的位置。在大多数欧洲国家的ISO-646的字符集,这些位置由英文字母没有找到字母占据。一个组三合字母的被提供以允许在使用一个真正的标准最小字符集的可移植的方式来表示的国家的字符。这可以是节目交换有用的,但它不会使人们更容易阅读程序。当然,长期的解决这个问题是C ++程序员得到一个支持他们的母语和C ++以及设备。不幸的是,这似乎对于一些是不可行的,并引入新的设备可以是一个令人沮丧的缓慢过程。
今天的孩子们! : - )
是,外国设备,诸如一个IBM 3270终端。 3270都有,如果我没有记错,没有花括号!如果你想用C写在IBM微型/主机,你的必须的使用猥琐三合为每块边界。幸运的是,我只用C来写软件的模拟的一些IBM小型机设施,实际上没有写C软件的在的系统/ 36。
下一个看到 “P” 键:
嗯。很难说。旁边有“回车”额外的按钮,我可能有它向后:也许这是“[” /“]”一对失踪。无论如何,这个键盘会导致你悲伤,如果你有编写C。
另外,这些终端显示EBCDIC,IBM的 “天然” 大型机字符集,而不是ASCII(感谢,帕维尔Minaev,对于提示)。
在另一方面,像GNU C导说:“你不需要这样的脑损伤。” gcc编译离开该“特性”默认禁用。
它们是用于在缺少一些在C ++中的基本字符集的字符的系统中使用。不用说,这样的系统是极其罕见的。
三字母已经提出了用于C ++ 0x中去除。这就是说,有似乎仍然是支持他们的有力论据 - 见C ++委员会文件的 N2910 其中讨论这一点。显然,EBCDIC是一个主要的据点需要它们的地方。
我已经看到了90年代初用于帮助从大型机转换PL / 1运行程序/编译/调试的PC上三字母组合。
他们具有编辑PL / I的个人计算机上使用PL / I C编译器,并涉足他们想要的代码工作时移回其不支持大括号大型机。我建议他们可以使用宏象
#def BEGIN {
#def END }
或作为友好PL / I替代
#def BEGIN ??<
#def END ??>
如果他们真的想获得幻想,他们可以尝试
#ifdef MAINFRAME
#def BEGIN ??<
#def END ??>
#else
#def BEGIN {
#def END }
#endif
和然后程序会看起来就像是写在帕斯卡。他们只是看着我好笑,不会和我说话了一天的休息。我不认为我责怪他们。 :)
什么打死的努力没有什么三图表,它是平台之间的IO系统的差异。在PC上打开文件是如此比它已经推出了太多的组装机,以保持相同的代码上都运行在大型机很大的不同。
欧洲一些键盘不(没?)有,美国有键盘,因为他们需要的钥匙他们不寻常的字母字符的所有标点字符。因此,例如,(做这件事),瑞典键盘将有一个环在大括号了。
要容纳的用户,三合字母是仅使用最常见的ASCII字符输入标点的方法。
主要是因为C标准引入他们早在1989年,当有与该字符的存在下三合字母地图可以在一些机器上的问题。由C ++标准于1998年出版的时候,需要三合不大。他们是基于C疣;他们只是尽可能多的C ++疣。有必要为他们 - 尤其是外面的英语世界 - 这就是为什么它们被添加到C
他们大多有历史的原因。如今,大多数语言最现代化的键盘允许访问所有这些字符,但使用一些欧洲的键盘是一个问题一次。这就是为什么三字母被发明。
如果你不知道他们是什么,你不应该使用它们。
这还是很好的了解他们,不过,因为你可能会意外地和无意地使用一个在你的代码。