【问题标题】:How printf("%d","<string>") work in C?printf("%d","<string>") 如何在 C 中工作?
【发布时间】:2014-09-26 22:09:45
【问题描述】:

我正在修改一些 C 概念并尝试了这个:

printf("%d %d %d", "%da", 'a', 'A'); //16079992 97 65

我可以理解,对于 aA,它会打印 ASCII 值:9765。但是我不明白为什么它会为"%da" 打印16079992。事实上,我不明白 C 在使用%d 将字符串输出为整数时如何解释它们。这背后必须有一些算法/逻辑。有人吗?

【问题讨论】:

  • "这背后肯定有一些算法/逻辑。" 不,没有。如果你过马路而不看两边,会发生什么?谁知道。你可能会被车撞到。你可能会被卡车撞到。任何事情都有可能发生。如果您以明确禁止的方式处理信息,您可能会得到完全的垃圾。

标签: c string int printf


【解决方案1】:

C 中的字符串字面量是 char 数组,在这种情况下将衰减为指向第一个元素的指针。

你所拥有的是未定义的行为,因为你在printf 中错误地指定了格式字符串并告诉它指针是一个 int 而它不是。大多数编译器给出正确的警告标志(我们应该始终使用)会为此提供警告,例如gcc 在使用-Wall 时会提供以下警告:

warning: format '%d' expects argument of type 'int', but argument 2 has type 'char *' [-Wformat=]
printf("%d %d %d", "%da", 'a', 'A'); 
^

clang 默认情况下会提供类似的警告。

作为参考,draft C99 standard 告诉我们字符串文字是 6.4.5 部分中的 char 数组 字符串文字

[...]初始化一个静态存储时长数组[...]为字符 字符串字面量,数组元素的类型为 char,并且是 用多字节字符的单个字节初始化 序列;[...]

6.3.2.1 部分介绍了指针的衰减左值、数组和函数指示符

[...]类型为“类型数组”的表达式被转换为 类型为“pointer to type”的表达式,指向初始 数组元素[...]

我们从7.19.6.1 部分得到未定义的行为fprintf 函数

[...]如果任何参数不是对应的正确类型 转换规范,行为未定义。

【讨论】:

  • !!!你是做什么的?语言规范的步行指数?只是好奇,您是否阅读过所有这些 C 变体的正式规范?
  • @Mahesha999 不,我知道的足够多,可以回答没有标准知识就无法正确回答的问题。有很多 SO 用户非常了解标准,请查看laguage-lawyer tag,很多人比我更了解。
  • 好的,但您仍然尝试阅读这些 C 变体的形式语言语法吗?可能会鼓励我。
  • @Mahesha999 好吧,语法是标准的一部分。因此,处理表达式、语句和声明的部分都包含形式语法。
【解决方案2】:

C 中的字符串是一个指针,它有一个数值(地址)。所以 printf 只是在那里打印字符串的地址。

【讨论】:

  • 其实是未定义的行为。在 64 位编译器上 %d 肯定不会打印字符串的地址,而在其他编译器上可能不会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-17
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
相关资源
最近更新 更多