为什么这个C程序编译没有错误? [英] Why does this C program compile without an error?

查看:159
本文介绍了为什么这个C程序编译没有错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C初学者,我和C.打我打一个C code是这样的:

 的#include<&stdio.h中GT;
诠释的main()
{
    的printf(世界你好\\ n);
    \\
    返回0;
}

虽然我用 \\ 明知故犯,C编译器不会抛出任何错误。这是什么符号在C语言用的?

编辑:

即使是这样工作的:

 \\ n;


解决方案

该序列反斜杠换行是从code在一个非常早期的阶段除去翻译过程(第2阶段)。它曾经是你如何创建长字符串之前有字符串连接,并且是你怎么还在扩展宏多行。

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


  

翻译的语法规则中的precedence由以下指定
  阶段。 5)


  
  

      
  1. 物理源文件多字节字符映射,在实施定义
      的方式,对源字符集(引入新行字符
      端的行指标)如果需要的话。三字符序列替换
      对应的单字符内部重新presentations。

  2.   
  3. 反斜杠字符的每个实例( \\ ),紧跟​​着一个新的行
      人物被删除,拼接物理源线形成逻辑源代码行。
      只有在任何物理源行的最后一个反斜杠有资格成为一部分
      这样的剪接。源文件不为空应以新行字符结束,
      其中应不会马上$任何此类面前一个反斜杠字符pceded p $
      拼接发生。

  4.   
  5. 源文件被分解为preprocessing标记 6)和序列
      空白字符(包括注释)。源文件,不得在结束
      偏preprocessing令牌或在部分评论。每个注释被替换
      一个空格字符。换行字符将被保留。是否每一个非空
      较新线等空白字符序列保留或更换
      一个空格字符是实现定义的。

  6.   
  7. preprocessing指令被执行,宏调用展开,
       _Pragma 单目运算符前pressions执行。如果一个字符序列
      匹配通用字符名的语法由令牌产生
      级联(6.10.3.3)的行为是不确定的。 A 的#include preprocessing
      指令导致命名的头或源文件被从第1阶段处理
      通过4阶段,递归。然后,所有preprocessing指令都将被删除。

  8.   
  9. 每个源字符集成员和逃生字符常量序列
      字符串转换为执行字符相应的成员
      组;如果没有相应的部件,它被转换为限定的实施
      成员比空(宽)字符等。 7)

  10.   
  11. 相邻字符串文字令牌是连接在一起。

  12.   
  13. 空白字符分隔标记不再显著。每
      preprocessing标记转换成令牌。由此产生的标记是
      语法和语义分析,并翻译为一个翻译单元。

  14.   
  15. 所有外部对象和函数引用得到解决。库组件
      联系到满足功能到外部引用和对象未在规定
      当前翻译。所有此类翻译输出被收集到一个节目图像
      其中包含需要在其执行环境中执行的信息。

  16.   

  
  

5)实现应表现为,如果这些不同的阶段出现,尽管很多通常在实践中折叠在一起。


  
  

6)正如在6.4节所述,分割源文件的字符转换为preprocessing令牌的过程
  上下文相关的。例如,请参见&LT的处理;一个的#include preprocessing指令中


  
  

7)的实现不一定所有的非对应的源字符转换到同一执行
  性格。


如果你有一个空或流浪反斜杠后的任何其它字符,你将有一个编译错误。我们可以告诉你没有后任何东西,因为你没有编译错误。


你的问题的另一部分,约:

 \\ n;

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

  I = 1;

你有一个前pression与被废弃的值;它用于修改其副作用评估 I

有时候,你会发现code,如:

  * PTR ++;

编译器会提醒你,恩pression的结果会被丢弃;恩pression可以简化为:

  PTR ++;

和将实现在程序相同的效果。

I'm a beginner in C, and I was playing with C. I typed a C code like this:

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

Even though I used \ knowingly, the C compiler doesn't throw any error. What is this symbol used for in the C language?

Edit:

Even this works:

"\n";

解决方案

The sequence backslash-newline is removed from the code in a very early phase (phase 2) of the translation process. It used to be how you created long string literals before there was string concatenation, and is how you still extend macros over multiple lines.

See §5.1.1.2 Translation Phases of the C99 standard:

The precedence among the syntax rules of translation is specified by the following phases.5)

  1. Physical source file multibyte characters are mapped, in an implementation defined manner, to the source character set (introducing new-line characters for end-of-line indicators) if necessary. Trigraph sequences are replaced by corresponding single-character internal representations.
  2. Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. Only the last backslash on any physical source line shall be eligible for being part of such a splice. A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character before any such splicing takes place.
  3. The source file is decomposed into preprocessing tokens6) and sequences of white-space characters (including comments). A source file shall not end in a partial preprocessing token or in a partial comment. Each comment is replaced by one space character. New-line characters are retained. Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is implementation-defined.
  4. Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed. If a character sequence that matches the syntax of a universal character name is produced by token concatenation (6.10.3.3), the behavior is undefined. A #include preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted.
  5. Each source character set member and escape sequence in character constants and string literals is converted to the corresponding member of the execution character set; if there is no corresponding member, it is converted to an implementation defined member other than the null (wide) character.7)
  6. Adjacent string literal tokens are concatenated.
  7. White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. The resulting tokens are syntactically and semantically analyzed and translated as a translation unit.
  8. All external object and function references are resolved. Library components are linked to satisfy external references to functions and objects not defined in the current translation. All such translator output is collected into a program image which contains information needed for execution in its execution environment.

5) Implementations shall behave as if these separate phases occur, even though many are typically folded together in practice.

6) As described in 6.4, the process of dividing a source file’s characters into preprocessing tokens is context-dependent. For example, see the handling of < within a #include preprocessing directive.

7) An implementation need not convert all non-corresponding source characters to the same execution character.

If you had a blank or any other character after your stray backslash, you would have a compilation error. We can tell that you don't have anything after it because you don't have a compilation error.


The other part of your question, about:

"\n";

is quite different. It is a simple expression that has no side-effects and therefore no effect on the program. The optimizer will completely discard it. When you write:

i = 1;

you have an expression with a value that is discarded; it is evaluated for its side-effect of modifying i.

Sometimes, you'll find code like:

*ptr++;

The compiler will warn you that the result of the expression is discarded; the expression can be simplified to:

ptr++;

and will achieve the same effect in the program.

这篇关于为什么这个C程序编译没有错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆