为什么这个C程序编译没有错误?

时间:2012-04-06 15:49:21

标签: c

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

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

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

编辑:

即便如此:

"\n";

5 个答案:

答案 0 :(得分:11)

序列反斜杠 - 换行符在转换过程的早期阶段(阶段2)从代码中删除。它曾经是在字符串连接之前创建长字符串文字的方式,以及如何在多行上扩展宏。

参见§5.1.1.2C99标准的翻译阶段:

  

翻译语法规则的优先级由以下内容指定   相。 5)功能

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

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

         

    6)如6.4中所述,将源文件的字符划分为预处理标记的过程是   依赖于上下文的。例如,请参阅#include预处理指令中的"\n"; 处理。

         

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

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


问题的另一部分,关于:

i = 1;

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

i

你有一个表达式,其值被丢弃;评估其修改*ptr++; 的副作用。

有时,您会找到如下代码:

ptr++;

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

{{1}}

并将在该计划中达到同样的效果。

答案 1 :(得分: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

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

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

答案 2 :(得分:0)

C预处理器解释反斜杠\ get。它保护其后续字符(案例中的新行字符)。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

反斜杠加上后面的内容是escape sequence; “\ n”一起是换行符(打印换行符)。另一个重要的是“\ t”,用于标签。

相关问题