通常情况下,#define
只接受宏名称中的有效标识符 - 所以你不能这样做:
#define @ at
#define @(x) [x]
与反引号类似。而且您没有提到“$”,有时标识符中允许使用“$”。
可能有一个特定于编译器的扩展来允许此类映射,但我不会使用它。
至于造成这种现象的历史原因,有以下几个方面:ISO 646 http://en.wikipedia.org/wiki/ISO/IEC_646保留给国家字符的国家实现的字符集。这些保留部分包括引起问题的字符,标准 C(以及标准 C++)中的三字母和二字母特征分别于 1989 年和 1994 年添加到 ISO C 中,以提供解决问题的方法。
三字母组
在 C89 标准化过程中添加了三字母字符,以防止人们看到 C 代码中使用的字母字符(斯堪的纳维亚语言)(改编自 B Stroustrup 的“C++ 的设计和演化”中的示例,使用丹麦码头):
#include <stdio.h>
int main(int argc, char **argvÆÅ)
æ
if (argc < 1 øø *argvÆ1Å == 'Ø0') return 0;
printf("Hello, %sØn", argvÆ1Å);
å
或者,在 ISO 8859-1 代码集中(或任何 ISO 8859-x 代码集):
#include <stdio.h>
int main(int argc, char **argv[])
{
if (argc < 1 || argv[1] == '\0') return 0;
printf("Hello, %s\n", argv[1]);
}
引入三字母组是为了生成代码的中性格式:
??=include <stdio.h>
int main(int argc, char **argv??(??))
??<
if (argc < 1 ??!??! *argv??(1??) == '??/0') return 0;
printf("Hello, %s??/n", argv??(1??));
??>
这也不是很可读,但对每个人来说都是一样的。
Trigraph Equivalent to
??/ \ backslash
??< { open brace
??> } close brace
??( [ open square bracket
??) ] close square bracket
??= # hash (pound in American, but a pound is £ in English)
??' ^ caret
??! | pipe
??- ~ tilde
该标准说“没有其他三字母”。这就是转义序列“\?”的原因被识别(作为一个简单的问号 - 尽管大概是“??/?”)。请注意,GNU 编译器集合 (GCC) 不会解释三字母组,除非您将其手放在火上(指定 '-trigraphs
' 在命令行上)。
Digraphs
二合字母于 1994 年添加,不像三字母那样普遍或具有侵入性;它们只出现在字符串和字符串文字之外。有向图是:
Digraph Equivalent to
<: [
:> ]
<% {
%> }
%: #
%:%: ##
使用二合字母(和三合字母)的示例:
%:include <stdio.h>
%:include <iso646.h>
int main(int argc, char **argv<::>)
<%
if (argc < 1 or *argv<:1:> == '??/0') return 0;
printf("Hello, %s??/n", argv<:1:>);
%>
具体是在签名和反引号中吗?
如果您查看上面的维基百科 URL,您会发现“@”和“`”有时都会被国家字符替换 - 因此不是好的标识符。不使用“@”的另一个原因是,在引入 C 时,“#”是默认的擦除字符,而“@”是终端的终止(行擦除)字符。因此,您必须记住对它们进行转义由于“#”只出现在行首,所以这不是太大的问题(使用“#”和“##”要晚得多——再次标准化),但“@”会被擦除出所有前面的输入就行了。这是'vi'之前的日子 - 'ed 是标准的 Unix 编辑器'。