trigraph

关于C/C++中的trigraph

(2008-03-02 21:27:42)
    今天看书看到这个词,书上没给解释,上网查了下,意思很"隐讳",不过总算是搞明白怎么回事了,呵呵,写下来~~~
    

   先用简单的话讲一下什么是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


c11  spec 2.4
1
Trigraph sequences
[lex.trigraph]
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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值