关于C/C++中的trigraph,类似"??!"

来源:互联网 发布:运营商云计算案例 编辑:程序博客网 时间:2024/05/21 15:40
今天看书看到这个词,书上没给解释,上网查了下,意思很"隐讳",不过总算是搞明白怎么回事了,呵呵,写下来~~~
    

   先用简单的话讲一下什么是trigraph吧,这样不会一上来就是没人看得懂的话,trigraph是三字母词,又叫三连字,实在搞不懂翻译<<ThinkingicC++>>的人是怎么想的,居然翻译成"三个图形字符",搞得我想了老半天...关于C/C++中的trigraph

   言归正传,总得来说,thrgraph是C/C++为了照顾老一辈的"无产阶级革命家"而出现的,当时他们的条件极其艰苦,键盘上缺了很多键,无法输入以下九个字符:

    # \ ^ [ ] { } | ~

由此推才出现了 trigraph .

   换句话说,就是把上面的每个字符用其他三个字符来代替,替换规则如下:

 ??= ??/ ??' ??( ??) ??< ??> ??! ??-

 

下面举个例子来说明,下面是一个C++的简单程序:

#include <iostream>

using namespace std;

 

int main() {
   cout << "[]" <<endl;

   return 0;
}

在当时键盘没有那九个符号的时候,那些程序员们就这么写:

??=include <iostream>

using namespace std;

 

int main() ??<
   cout << "??(??)"<< endl;

   return 0;
??>

   以上内容转自百度上搜到的某个空间看到的,空间名叫"草"...

    将trigraph 替换成对应的字符发生在预处理之前,因此 trigraph可以在源码中的任何位置都可以用,包括字符串内,函数体开头,预处理指令等。

   有人说,如果那我就是用一个字符串常量,其中包含了 "??="怎么办?比如说就是要打印两个问号接一个等号,怎么办?很简单,把它拆开写,为了打印出 "??=",我们把它拆成 "??" "=" 即可,因为 C/C++在处理字符串字面值的时候,会把相邻的多个字符串字面值合并成一个,而这个合并操作发生在trigraph 替换之后,
下面的程序就可以正确的打印出两个问号和一个等号:

#include <iostream>

using namespace std;

 

int main() {
   cout << "??" "="<< endl;
}

实测中,
VC 8 不给任何提示将 trigraph 替换成对应字符,
GCC 4.0.3 则要求加上编译参数 -trigraphs 才会做相应转换。

虽然 GCC 的做法是不符合标准的,但是更加安全。
更详细的情况可以参考标准 2.3。

 

以下是从c语言参考课程里摘的一段话:

   C源程序的源字符集被包含在7位ASCII字符集中,但不是ISO646-1983Invariant CodeSet的子集。三字母(trigraph)序列允许C程序仅使用ISO(国际标准组织)Invariant CodeSet编写。三字母是编译器用对应的标点字符替换的三字符序列(以两个问号开头)。你可以在C源文件中使用三字母,该源文件的字符集不能包含某些标点字符的方便图形表示。

 

   一个三字母总是作为单个源字符处理,在第一次转换阶段中,在识别字符串文字和字符常量中的转义字符之前进行三字母的转换。仅识别表1.1中列出的9个三字母,所有其它字符序列不作转换。

   字符转义序别\?防止类似三字母的字符序列被误解释(有关转义序列的信息,参见本章后面的“转义序列”)。例如,如果你试图用以下printf语句打印字符串What??!:

printf(“What??!\n");

打印的字符串What|,因为??!是一个三字母,它被|字符所替换。正确打印这个字符串的语句如下:

printf(What?\?!\n");

在这个printf语句中,在第二个问号之前加上一个反斜杠转义字符防止??!作为一个三字母的误解释。

 

   嗯,就这么多,应该解释得很清楚了吧,反正我是明白了~~关于C/C++中的trigraph

原创粉丝点击