据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有我拉我的头发)标点符号各种有趣的一个很好的教育,看看香草萨特的GOTW#86条 。
附录:
它看起来像GCC不会处理(将警告)默认情况下,三字母组合。 其他一些编译器有选项关闭对三字符的支持(IBM的例子)。 微软开始支持必须明确允许(使用-Wall或东西)在VS2008警告(C4837)。
从The C++ Programming Language
特别版,829页
该ASCII特殊字符[
, ]
, {
, }
, |
和\
占据由ISO指定为字母字符集的位置。 在大多数欧洲国家的ISO-646的字符集,这些位置由英文字母没有找到字母占据。
一组三字母以允许使用一个真正的标准的最小字符集的可移植的方式来表达民族文字。 这可以是节目交换有用的,但它不会使人们更容易阅读程序。 当然,长期的解决这个问题是C ++程序员得到一个支持他们的母语和C ++以及设备。 不幸的是,这似乎是不可行的一些,并引进了新的设备可以是一个令人沮丧的缓慢过程。
今天的孩子们! :-)
是的,国外设备,如IBM 3270终端。 3270都有,如果我没有记错,没有花括号! 如果你想用C写在IBM微型/主机,您必须使用猥琐三合为每块边界。 幸运的是,我只用C编写软件来模拟一些IBM小型机设施, 在 System / 36没有实际编写C软件。
接下来看看到“P”键: http://www.9999hp.net/keyboard/temp/1389260-big.jpg
嗯。 很难说。 旁边有“回车”额外的按钮,我可能有它向后:也许这是“[” /“]”一对失踪。 无论如何,这个键盘会导致你悲伤,如果你有写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
然后程序会看起来就像是用Pascal编写。 他们只是看着我好笑,不会和我说话了一天的休息。 我不认为我责怪他们。 :)
什么杀害的努力没有什么三图表,它是平台之间的IO系统的差异。 在PC上打开文件是那么比它已经推出了太多的组装机,以保持上都运行相同的代码的主机很大的不同。
一些欧洲键盘不(没?)有,美国有键盘,因为他们需要的钥匙他们不寻常的字母字符的所有标点字符。 因此,例如,(做这件事),瑞典键盘将有一个环在大括号了。
为了满足这些用户,三合只使用最普通的ASCII字符输入标点符号的一种方式。
这主要是因为C标准在1989年,当时有与人物的存在是三合地图上的一些机器的问题介绍,他们回来了。 由C ++标准于1998年出版的时候,需要三合不大。 他们是基于C疣; 他们只是尽可能多的C ++疣。 有必要为他们 - 尤其是外面的英语世界 - 这就是为什么它们被加入到C.
他们大多有历史的原因。 如今,大多数语言最现代化的键盘允许访问所有这些字符,但使用一些欧洲的键盘是一个问题一次。 这就是为什么三字母被发明。
如果你不知道他们是什么,你不应该使用它们。
它仍然是很好的了解他们,不过,因为你可能会意外地和无意地使用一个在你的代码。