9

我是 C 的初学者,我在玩 C。我输入了这样的 C 代码:

#include <stdio.h>
int main()
{
    printf("hello world\n"); 
    \
    return 0;
}

即使我\故意使用,C 编译器也不会抛出任何错误。这个符号在 C 语言中是做什么用的?

编辑:

即使这样也有效:

"\n";
4

5 回答 5

11

在翻译过程的早期阶段(阶段 2)从代码中删除序列反斜杠换行符。它曾经是您在字符串连接之前创建长字符串文字的方式,也是您仍然将宏扩展到多行的方式。

请参阅 C99 标准的 §5.1.1.2 转换阶段:

翻译的语法规则之间的优先级由以下阶段指定。5)

  1. 如有必要,物理源文件多字节字符以实​​现定义的方式映射到源字符集(为行尾指示符引入换行符)。Trigraph 序列被相应的单字符内部表示替换。
  2. 每个反斜杠字符 ( \) 的实例后面紧跟一个换行符都被删除,拼接物理源代码行以形成逻辑源代码行。只有任何物理源行上的最后一个反斜杠才有资格成为此类接头的一部分。非空源文件应以换行符结尾,在进行任何此类拼接之前,该换行符之前不应紧跟反斜杠字符。
  3. 源文件被分解为预处理标记6)和空白字符序列(包括注释)。源文件不应以部分预处理标记或部分注释结尾。每个注释被一个空格字符替换。保留换行符。除换行符之外的每个非空空白字符序列是保留还是替换为一个空格字符是实现定义的。
  4. 执行预处理指令,扩展宏调用,并 _Pragma执行一元运算符表达式。如果与通用字符名称的语法匹配的字符序列由标记连接 (6.10.3.3) 生成,则行为未定义。预处理指令导致命名的#include头文件或源文件从阶段 1 到阶段 4 以递归方式进行处理。然后删除所有预处理指令。
  5. 字符常量和字符串文字中的每个源字符集成员和转义序列都被转换为执行字符集的相应成员;如果没有对应的成员,则将其转换为除空(宽)字符之外的实现定义的成员。7)
  6. 相邻的字符串文字标记被连接起来。
  7. 分隔标记的空白字符不再重要。每个预处理令牌都被转换为一个令牌。生成的标记在句法和语义上进行分析,并作为翻译单元进行翻译。
  8. 所有外部对象和函数引用都已解析。链接库组件以满足对当前翻译中未定义的函数和对象的外部引用。所有此类翻译器输出都被收集到程序映像中,该程序映像包含在其执行环境中执行所需的信息。

5)实现应该表现得好像这些单独的阶段发生了一样,即使在实践中许多通常是折叠在一起的。

6)如 6.4 所述,将源文件的字符划分为预处理标记的过程是上下文相关的。例如,请参阅预处理指令<内的处理。#include

7)实现不需要将所有不对应的源字符转换为相同的执行字符。

如果杂散反斜杠后有空格或任何其他字符,则会出现编译错误。我们可以告诉您在它之后没有任何内容,因为您没有编译错误。


你问题的另一部分,关于:

"\n";

是完全不同的。这是一个简单的表达式,没有副作用,因此对程序没有影响。优化器将完全丢弃它。当你写:

i = 1;

您有一个带有被丢弃值的表达式;它被评估为修改的副作用i

有时,您会发现如下代码:

*ptr++;

编译器会警告你表达式的结果被丢弃;表达式可以简化为:

ptr++;

并且会在程序中达到同样的效果。

于 2012-04-06T15:56:20.450 回答
4

\当紧跟一个换行符时,会被预处理消耗,并导致下一个“物理”行连接到当前逻辑行。这对于编写长的预处理指令非常重要,这些指令必须全部在一个逻辑行上:

#define SHORT very log macro \
   consisting of lots and \
   lots of preprocessor \
   tokens

如果删除反斜杠换行序列,则不再正确。来自 Unix 文化的其他一些语言具有类似的反斜杠行延续语法:源自 Bourne shell 的 POSIX shell 语言,以及 makefile。

$ this is \
one shell command

About "\n";,这是用于形成表达式语句的主要表达式。在 C 中,表达式可以用作语句,并且一直被利用。printf例如,您的调用是一个表达式语句。printf("hello world\n")是一个后缀表达式,它调用一个函数,获得一个返回值。因为您将此表达式用作语句,所以返回值被丢弃。的返回值printf 表示打印了多少个字符,或者它是否成功,所以通过丢弃它,你的程序会让自己忘记printf调用是否真的有效。

由于表达式语句的值被丢弃,如果这样的语句也没有副作用,它是一个无用的语句,什么都不做(比如你的"\n")。但是这种无用的表达语句并没有错误。如果您在编译器命令行中添加警告选项,您可能会收到诸如“没有效果的语句”之类的警告。

于 2012-04-06T16:06:58.643 回答
0

反斜杠 \ 由 C 预处理器解释。它保护它的下一个字符(你的情况下的换行符)。

于 2012-04-06T15:51:32.463 回答
0

反斜杠只是转义下一个字符。在这种情况下,可能是行结束 (CR) 字符。完全合理。

于 2012-04-06T15:52:13.950 回答
0

反斜杠加上它后面的内容是一个转义序列;"\n" 一起是换行符(打印换行符)。另一个重要的是“\t”,用于制表符。

于 2012-04-06T15:56:45.687 回答