C语言的结构

C语言的结构,c,syntax,grammar,C,Syntax,Grammar,为什么这样做有效 printf("Hello" "World"); 鉴于 printf("Hello ""World"); 不是吗? ANSI C连接相邻的字符串,这没关系。。。但这是另一回事。 这与C语言解析器或其他东西有关吗? 谢谢字符串必须在行尾之前终止。这是一件好事。否则,忘记关闭引号可能会阻止后续代码行的执行 这可能会花费大量的调试时间。现在,语法着色可以提供线索,但在早期有单色显示器 不能在字符串文本中创建新行。这是C.IMO的设计师们做出的一个选择。尽管这是一个很好的特性。 但

为什么这样做有效

printf("Hello"
"World");
鉴于

printf("Hello
""World");
不是吗? ANSI C连接相邻的字符串,这没关系。。。但这是另一回事。 这与C语言解析器或其他东西有关吗?
谢谢

字符串必须在行尾之前终止。这是一件好事。否则,忘记关闭引号可能会阻止后续代码行的执行


这可能会花费大量的调试时间。现在,语法着色可以提供线索,但在早期有单色显示器

不能在字符串文本中创建新行。这是C.IMO的设计师们做出的一个选择。尽管这是一个很好的特性。 但是,您可以执行以下操作:

printf("Hello\
""World");

这给出了相同的结果。

C语言是根据标记定义的,其中一个标记是标准语言中的字符串文字:s-char-sequence。s-char序列以未转换的双引号开始和结束,并且不能包含未转换的换行符

相关标准C99报价:

> Syntax
>   string-literal:
>     " s-char-sequence(opt) "
>     L" s-char-sequence(opt) "
>   s-char-sequence:
>     s-char
>     s-char-sequence s-char
>   s-char:
>     any member of the source character set
>           except the double-quote ", backslash \,
>           or new-line character
>     escape-sequence
然而,转义的换行符会在早期的翻译阶段(称为行拼接)中被删除,因此编译器永远无法解释它们。以下是相关的标准C99报价:

> Syntax
>   string-literal:
>     " s-char-sequence(opt) "
>     L" s-char-sequence(opt) "
>   s-char-sequence:
>     s-char
>     s-char-sequence s-char
>   s-char:
>     any member of the source character set
>           except the double-quote ", backslash \,
>           or new-line character
>     escape-sequence
翻译语法规则的优先顺序由以下阶段指定

物理源文件多字节字符以implementationdefined的方式映射到源字符集,必要时为行尾指示符引入新行字符。三角图序列被相应的单字符内部表示替换。 删除紧跟新行字符的反斜杠字符\的每个实例,将物理源行拼接成逻辑源行。只有任何物理源线上的最后一个反斜杠才有资格成为此类拼接的一部分。非空的源文件应以新行字符结尾,在进行任何此类拼接之前,该新行字符前不得紧跟反斜杠字符。 将源文件分解为预处理标记6和序列 包含注释的空白字符。源文件不应以 部分预处理标记或在部分注释中。每个注释都替换为 一个空格字符。保留新行字符。是否每个都是空的 除新行以外的空白字符序列被保留或替换为实现定义的一个空白字符。 执行预处理指令,展开宏调用,然后 _执行Pragma一元运算符表达式。如果一个字符序列 匹配由令牌生成的通用字符名的语法 连接6.10.3.3,行为未定义。A包括预处理 指令导致从阶段1处理命名的头文件或源文件 通过阶段4,递归地。然后删除所有预处理指令。 将字符常量和字符串文本中的每个源字符集成员和转义序列转换为执行字符集的相应成员;如果没有相应的成员,则将其转换为除空宽字符以外的implementationdefined成员。7 相邻的字符串文字标记被连接起来。 分隔标记的空白字符不再有效。每个 预处理令牌被转换为令牌。生成的令牌是 从语法和语义上分析并翻译为一个翻译单元。 解析所有外部对象和函数引用。库组件链接以满足对当前转换中未定义的函数和对象的外部引用。所有这些转换器输出都被收集到一个程序映像中,该映像包含在其执行环境中执行所需的信息。
我使用gcc时,它不插入任何换行符,只是让字符串文字继续到下一行。\表示继续到预处理器。这似乎不令人信服,您也可以忘记第二个代码段中的。是的,但是您会得到语法错误,语法错误比调试花费的时间要少。因此,这就像c中的每一个标记都必须分布在一条线上,对吗?不。标记化直到第3阶段才会发生。线路拼接是第2阶段。因此,如果标记包含反斜杠换行符对,则可以跨越多行。