未定义的C/C++符号作为运算符

ura*_*ray 3 c c++ syntax symbols operators

我注意到字符/符号'''和'@'在C/C++中不用作运算符,

  1. 有谁知道原因或历史原因为何如此?
  2. 如果它真的没用过,使用#define将这些符号定义为另一个运算符/语句是否安全?

Jon*_*ler 12

通常,#define只接受宏名称中的有效标识符 - 所以你不能这样做:

#define @      at
#define @(x)   [x]
Run Code Online (Sandbox Code Playgroud)

与反向报价相似.你没有提到'$',有时候会在标识符中使用'$'.

可能有一个特定于编译器的扩展来允许这样的映射,但我不会使用它.


至于历史原因,ISO 646字符集的某些部分保留给国家字符的国家实现.这些保留部分包括导致故障的字符,标准C(以及标准C++)中的三字符和有向图特征分别在1989年和1994年被添加到ISO C中,以提供问题的解决方法.

三合

在C89标准化过程中添加了Trigraphs,以防止人们看到他们的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Å);
å
Run Code Online (Sandbox Code Playgroud)

或者,在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]);
}
Run Code Online (Sandbox Code Playgroud)

引入三字符以产生代码的中性格式:

??=include <stdio.h>
int main(int argc, char **argv??(??))
??<
    if (argc < 1 ??!??! *argv??(1??) == '??/0') return 0;
    printf("Hello, %s??/n", argv??(1??));
??>
Run Code Online (Sandbox Code Playgroud)

这也不是很易读,但对每个人来说都是一样的.

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
Run Code Online (Sandbox Code Playgroud)

标准说"没有其他三字母".这就是转义序列'\?'的原因 被认可(作为一个简单的问号 - 虽然可能是'?? /?').请注意,GNU编译器集合(GCC)不会解释三字母,除非您握住它的手(-trigraphs在命令行上指定' ').

有向图

有向图是在1994年添加的,并不像三字母那样普遍或具有侵入性; 它们只出现在字符串和字符串文字之外.有向图是:

Digraph       Equivalent to
<:            [
:>            ]
<%            {
%>            }
%:            #
%:%:          ##
Run Code Online (Sandbox Code Playgroud)

使用有向图(和三字母)的示例:

%: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:>);
%>
Run Code Online (Sandbox Code Playgroud)

在标志和背面报价具体?

如果你看一下上面的维基百科网址,你会发现'@'和'`'有时会被国家字符替换 - 因此不是好的标识符.不使用'@'的另一个原因是,在引入C时,'#'是默认的擦除字符,'@'是终端的kill(行擦除)字符.所以,你必须记得逃避它们由于'#'只出现在一行的开头,所以问题不是太大(使用'#'和'##'来得更久,很久以后 - 再次标准化),但'@'会擦除排除了前面所有的输入.这就是'vi'之前的日子 - 'ed是标准的Unix编辑器'.