为什么?是C / C ++中的转义序列?

Why is “?” an escape sequence in C/C++?

在C/C++中有四个特殊的非字母字符需要跳出:单引号EDOCX1,0,双引号EDOCX1,1,反斜率EDCX1 2,问号EDCOX1 3。显然是因为它们有特殊的含义。对于单个char",对于字符串文字,\,但是为什么?是其中之一?

我今天读了一本教科书中的转义序列表,我意识到我以前从来没有逃过?,也从来没有遇到过它的问题,只是可以肯定的是,我在gcc下测试过它:

1
2
3
4
5
6
7
#include <stdio.h>
int main(void)
{
    printf("question mark ? and escaped \?
"
);
    return 0;
}

C++版本:

1
2
3
4
5
6
#include <iostream>
int main(void)
{
    std::cout <<"question mark ? and escaped \?" << std::endl;
    return 0;
}

两种程序输出:question mark ? and escaped ?

所以我有两个问题:

  • 为什么\?是转义序列字符之一?
  • 为什么不逃逸?工作正常,甚至没有警告。
  • 在我要问这个问题之前,我自己找到了答案,因为我在So中找不到副本,所以我决定用Q&A样式发布它。

    更有趣的是,转义的\?在其他语言中也可以与?在某些语言中相同,我用lua/ruby进行了测试,尽管我没有发现这个文档,但这也是真的。


    Why is \? one of the escape sequence characters ?

    因为它是特殊的,答案导致三叉图,C/C++预处理器将下面的三个字符序列替换为相应的单个字符。(C11〈5.2.1.1和C++ 11〉2.3)

    1
    2
    Trigraph:       ??(  ??)  ??<  ??>  ??=  ??/  ??'  ??!  ??-
    Replacement:      [    ]    {    }    #    \    ^    |    ~

    三角图现在几乎没用了,主要用于模糊目的,在ioccc中可以看到一些例子。

    gcc默认不支持trigraph,如果代码中有trigraph,将警告您,除非启用了选项-trigraphs3。在-trigraphs选项下,第二个\?在以下示例中很有用:

    1
    2
    printf("\?\?!
    "
    );

    如果不转义?,则输出为|

    有关三角图的更多信息,请参见神秘线"??!???!"在旧代码中

    Why non-escaping ? works fine, there's not even a warning.

    因为?和双引号"可以用标准来表示:

    C11 §6.4.4.4 Character constants Section 4

    The double-quote " and question-mark ? are representable either by themselves or by the escape sequences \" and \?, respectively, but the single-quote ' and the backslash \ shall be represented, respectively, by the escape sequences \' and \\.

    类似于C++:

    C++11 §2.13.2 Character literals Section 3

    Certain nongraphic characters, the single quote , the double quote ", the question mark ?, and the backslash \, can be represented according to Table 6. The double quote " and the question mark ?, can be represented as themselves or by the escape sequences \" and \? respectively, but the single quote and the backslash \ shall be represented by the escape sequences \’ and \\ respectively. If the character following a backslash is not one of those specified, the behavior is undefined. An escape sequence specifies a single character.