我注意到在C/C++中,字符/符号“`”和“@”并不作为运算符使用,
- 有人知道这个原因或历史上为什么会这样吗?
- 如果它们真的没有被使用,是否可以安全地使用#define将这些符号定义为另一个运算符/语句?
#define
只接受宏名称中的有效标识符 - 因此您无法执行以下操作:#define @ at
#define @(x) [x]
关于这一历史原因,ISO 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
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编辑器”。
$
的问题,你说得对--例如,在大多数平台上,GCC允许在标识符中使用它。 - Stephen Canon这样做可能是安全的,但几乎肯定是一个非常糟糕的想法。由于@
不是标准运算符,任何阅读您代码的其他人都必须去追踪@
的定义。我们命名函数并不仅使用符号,以便人类读取代码可以弄清楚它的作用。
顺便说一句,Objective-C使用@
。不确定是否与您的项目相关,但如果有人尝试从ObjC使用您的C代码,则所有他们的代码都会因为您的#define
而中断。
@
在 Objective-C(C 的超集)中被广泛使用。 - kennytm