关于c ++:C ++中Trigraph序列的用途?

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 |
----------------------------------------------------------------------------
| ??=      | #           | ??(      | [           | ??<      | {           |
| ??/      | \           | ??)      | ]           | ??>      | }           |
| ??’      | ?           | ??!      | |           | ??-      | ?           |
----------------------------------------------------------------------------

在现实生活中,这意味着代码printf("What??!
" );
将导致打印What|,因为??!是一个用|字符替换的三角序列。

我的问题是,使用三角图的目的是什么?使用三角图有什么实际的好处吗?

答:有人提到一些欧洲键盘没有所有标点符号,所以非美国的程序员在日常生活中必须使用三角键?

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 C++ Programming Language特别版,第829页

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。


它们的存在主要是出于历史原因。现在,大多数语言的大多数现代键盘都允许访问所有这些字符,但这曾经是一些欧洲键盘的一个问题。这就是三角图被发明的原因。

如果你不知道它们是用来干什么的,你就不应该使用它们。

不过,了解它们仍然很好,因为您可能会在代码中意外和无意地使用它们。