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

时间:2013-10-15 06:49:30

标签: c++ c string gcc escaping

需要在C / C ++中转义四个特殊的非字母字符:单引号\',双引号\",反斜杠\\和问号\?。这显然是因为它们具有特殊含义。单'char,字符串文字为",转义序列为\,但为什么?为其中之一?

我今天阅读了教科书中的转义序列表,我意识到我之前永远不会逃脱?并且从未遇到问题,只是为了确定,我在gcc下测试了它:

#include <stdio.h>
int main(void)
{
    printf("question mark ? and escaped \?\n");
    return 0;
}

和C ++版本:

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

两个节目输出:question mark ? and escaped ?

所以我有两个问题:

  1. 为什么\?是转义序列字符之一?
  2. 为什么非逃避?工作正常,甚至没有警告。

  3. 在我提出这个问题之前,我自己找到了答案,因为我没有在SO中找到重复,我决定以Q&amp; A风格发布。

    更有趣的事实是转义的\?也可以和其他语言中的?一样使用,我在Lua / Ruby中测试过,即使我没有这样做也是如此找到这个记录。

1 个答案:

答案 0 :(得分:40)

  

为什么\?是转义序列字符之一?

因为它很特殊,答案导致Trigraph,C / C ++预处理器将以下三个字符的序列替换为相应的单个字符。 (C11§5.2.1.1和C ++11§2.3)

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

Trigraph现在几乎没用,主要用于混淆目的,在IOCCC中可以看到一些例子。

默认情况下,gcc不支持三元组,并且如果代码中有三字符,则会发出警告,除非启用了选项-trigraphs 3。在-trigraphs选项下,第二个\?在以下示例中很有用:

printf("\?\?!\n");  

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

有关三字母的更多信息,请参阅Cryptic line "??!??!" in legacy code


  

为什么非逃避?工作正常,甚至没有警告。

因为?(和双引号")可以由标准自己表示:

  

C11§6.4.4.4字符常量第4节

     

双引号"和问号?既可以单独表示,也可以分别由转义序列\"\?表示,但单引号'和反斜杠\分别由转义序列\'\\表示。

类似于C ++:

  

C ++11§2.13.2字符文字第3节

     

某些非字符字符,单引号,双引号",问号?和反斜杠\可以根据表6表示。双引号"和问号?可以分别表示为自己或转义序列\"\?,但单引号{{1}反斜杠应分别由转义序列\\’表示。如果反斜杠后面的字符不是指定的字符之一,则行为未定义。转义序列指定单个字符。