关于基本源字符集与替换字符序列
1.基本源字符集
用来写程序的字符集不必与程序中运行所使用的相同,对于非英语的应用也是如此。C 翻译程序仅仅理解英语的字母、用作运算符和标点符号的字符(共有29个)以及一些控制字符(回车符、换行符、横向制表符、纵向制表符和换页符等),这就是基本源字符集。执行字符集是定义实现的,但必须包含代表响铃符('\a')、回退符('\b')、回车符('\r')和换行符('\n')。
C++翻译器必须接受通用字符名,它以下列形式之一出现在源文本中:
\uNNNN
\UNNNNNNNN
这里的N代表一个十六进制数字,第一种形式对应的ISO 10646编码是0000NNNN(即由零引导的统一编码),而第二种形式对应的是NNNNNNNN。
2.三字符运算符
许多非美国键盘不支持基本源字符集中的一些字符,这给编写C程序带来困难,为了克服这个障碍,标准的C定义了一些三字符运算符,它是不变字符集(ISO 646-1983)中三字符一体的字符,在西方世界几乎随处可见。 三字符运算符以 ?? 作为引导字符,对应于源字符集中的那些不在ISO 646-1983字符集中的字符,预处理器将三字符运算符看作一个整体,只要遇到就用下表中的相应字符替换:
三字符运算符序列
────────┬───────╥────────┬───────
三字符运算符 │ C 源字符 ║ 三字符运算符 │ C 源字符
────────┼───────╫────────┼───────
??= │ # ║ ??/ │ \
??< │ { ║ ??! │ |
??> │ } ║ ??- │ ~
??( │ [ ║ ??' │ ^
??) │ ] ║ │
────────┴───────╨────────┴───────
下面是用C语言编写的示例程序,尽管看起来很奇怪,但它确实能正常工作。
//功能:使用三字符运算符的“Hello, world!” 程序
//编译选项 Code::Blocks GCC -trigraphs
??=include
int main(int argc, char *argv??(??))
??<
if (argc > 1 && argv??(1??) != NULL)
printf("Hello, %s!??/n", argv??(1??));
else
printf("Hello, world!??/n");
return 0;
??>
通常要对编译器进行相应的设置或在编译时加参数,否则三字符运算符可能不起作用,GCC编译器的编译参数是-trigraphs.
三字符运算符总是被当作一个整体对待,即使它出现在字符串中,也是先将它翻译为相应的源字符,然后才去考虑转义字符的问题。举一个例子,假设你想输出一个奇怪的字符串“What??!”,使用如下语句:
printf( "What??!\n" );
执行结果将会是:
What|
这并不是我们所期望的输出,而语句:
printf( "What?\?!\n" );
则可以得到输出:
What??!
这是因为 \ 将三字符运算符 ??! 分开了,预编译器看不到任何三字符运算符,继续后续处理转义字符,\? 被识别为问号 ? 的转义字符,于是得到正确的输出。
3.双字符运算符
为了努力开发更广泛可读性更强的程序,C++为非ASCII码开发者定义了一套双字符运算符集和新的保留字集,如下表所示:
新的C++双字符运算符和保留字
────────┬───────╥────────┬───────
标 识 │ 翻 译 ║ 标 识 │ 翻 译
────────┼───────╫────────┼───────
<% │ { ║ bitand │ &
%> │ } ║ bitor │ |
<: │ [ ║ xor │ ^
:> │ ] ║ compl │ ~
%% │ # ║ not_eq │ !=
not │ ! ║ and_eq │ &=
and │ && ║ or_eq │ |=
or │ || ║ xor_eq │ ^=
────────┴───────╨────────┴───────
下面是示例程序,看起来同样有些奇怪,但它的确可以通过编译。
// 功能:带有新的C++双字符和标记的“Hello, world!”程序
#include
using namespace std;
int main(int argc, char *argv<::>)
<%
if (argc > 1 and argv<:1:> not_eq NULL)
printf("Hello, %s!\n", argv<:1:>);
else
printf("Hello, world!\n");
return 0;
%>
上面的程序中,逻辑运算符(如and)和BASIC语言中的很相似,不过却是大小写敏感的,实际上这些新定义的保留字是在 头文件中的宏定义,例如:
#define and &&
因此,这些保留字遵循宏扩展的规则,出现在字符串或注释中的则不进行替换。
阅读(1050) | 评论(0) | 转发(0) |