【问题标题】:why does printf("a" "b" "c") prints abc in C [duplicate]为什么 printf("a" "b" "c") 在 C 中打印 abc [重复]
【发布时间】:2014-07-17 12:53:13
【问题描述】:

我在 C 中有以下代码:

#include<stdio.h>
void main(){
    printf("a" "b" "c");
}

它输出:

abc

谁能解释一下原因?

我猜它是"a" "b" "c" 预处理为"abc"。我是对的还是其他原因?

【问题讨论】:

  • 5.1.1.2 翻译阶段 6 连接相邻的字符串文字标记。
  • +1 这是一个很好的问题,除非你知道它可能很难弄清楚的术语。
  • @ShafikYaghmour 我可以谦虚地请求,既然这个问题有一个更好的标题,而且答案也稍微详细一点,那么它保持开放吗?如果它已关闭,那么搜索问题的人将找不到它,并且他们可能不会查看标题为“是否存在语法错误?”的内容。
  • @MattMcNabb 这是一个很好的观点,我改写了问题和标题,所以现在应该更好了。
  • @MattMcNabb:即使它被标记为重复,人们仍然可以搜索它,没有必要分割 IMO 的所有内容(这就是我们拥有重复系统的原因)。它们显示为“重复”而不是“关闭”是有原因的。

标签: c


【解决方案1】:

相邻的字符串文字作为翻译阶段 6 的一部分连接起来。

阶段的简要总结(来源:C99 标准,释义)

  1. 源文件中的三元组和多字节字符映射到源字符集
  2. \ 结尾的行被拼接
  3. 文件解析为一组预处理标记
  4. 已处理预处理指令
  5. 字符常量和字符串字面量迁移到执行字符集
  6. 连接相邻的字符串文字。
  7. 编译的其余部分(不包括链接)
  8. 链接

【讨论】:

  • 那么题末OP的猜测几乎是准确的吧?
  • 所以简而言之preprocessing期间完成。我想我猜对了:D。谢谢!我期待这样的答案。
  • @barakmanos 取决于您是否要调用阶段 6“预处理”。 gcc -E 不进行第 6 阶段。
  • 这是一个很好的答案,我不得不说。
  • @MattMcNabb 是的!谢谢你提到gcc -E 根据printf() 的语法我知道错了。它现在给出编译错误。
【解决方案2】:

相邻的字符串文字在编译 翻译阶段 6. 由于"a" "b" "c" 被进一步视为"abc" 字符串文字。

如果您不熟悉这个术语,第 6 阶段在某种程度上介于预处理和实际的“正确”编译之间。

【讨论】:

  • 真正的语言律师,是“翻译”而不是“编译”
  • @WojtekSurowka:完全正确,已更正。
  • 很好,我今天刚学到新东西! en.cppreference.com/w/cpp/language/translation_phases
  • 难道不是说 OP 在问题末尾所做的猜测是正确的(即,这不是在预处理过程中发生的)吗?
  • @barakmanos:这是在预处理之后。
【解决方案3】:

因为你在做String literal concatenation

传递给 printf 的结果 cstring 是 "abc\0"

【讨论】:

  • 感谢您的参考。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-15
  • 2015-11-20
  • 2020-07-15
  • 2014-01-15
  • 1970-01-01
相关资源
最近更新 更多