【发布时间】:2015-05-20 06:23:47
【问题描述】:
为什么不打印第二个'%'?
另外,如果我输入printf(scanf, scanf, scanf);,为什么它会给出相同的输出?
# include <stdio.h>
# define scanf "%s Geeks Quiz "
int main()
{
printf(scanf, scanf);
return 0;
}
【问题讨论】:
为什么不打印第二个'%'?
另外,如果我输入printf(scanf, scanf, scanf);,为什么它会给出相同的输出?
# include <stdio.h>
# define scanf "%s Geeks Quiz "
int main()
{
printf(scanf, scanf);
return 0;
}
【问题讨论】:
为什么第二个
%没有打印出来?
Ans :让我们将printf() 签名与您的用法进行比较,好吗?
根据man page,签名,
int printf(const char *format, ...);
和你的使用情况
printf(scanf, scanf);
这里,
scanf 表示format 字符串,其中包括转换说明符。scanf是printf()中第一个%s对应的参数。本质上,您的printf() 看起来像
printf("%s Geeks Quiz", "%s Geeks Quiz");
^ |-------------|
|
conversion argument for %s
specifier
因此,根据printf() 的工作原理,第一个%s 被%s Geeks Quiz 替换(这里,%s 是输出的一部分,不被视为格式说明符)。
所以,你最终的 o/p 看起来像
%s Geeks Quiz Geeks Quiz
另外,如果我输入
,为什么它会给出相同的输出printf(scanf, scanf, scanf);?
Ans:printf(scanf, scanf, scanf); 将产生与上述相同的输出,因为根据 C11 标准,第 7.21.6.1 章,fprintf() 函数,
如果格式已用尽而参数仍然存在,则多余的参数将 评估(一如既往),但在其他方面被忽略。
根据上面的解释,我们只有一个格式说明符 %s(来自第一个 scanf 替换),并且需要一个参数。所以,第三个scanf 就被忽略了。
【讨论】:
宏展开为:
printf("%s Geeks Quiz ", "%s Geeks Quiz ");
其中第一个字符串是打印格式字符串,第二个字符串是传递给该字符串的参数。
所以第二个字符串将放在第一个字符串的 %s 的位置:
"%s Geeks Quiz "
^
Insert second string "%s Geeks Quiz " here.
"%s Geeks Quiz Geeks Quiz "
【讨论】:
只有第一个字符串是实际的格式化字符串,它是 printf 用来查找像 "%s" 这样的格式化代码的字符串。当它找到一个格式化代码时,它将替换为相应的以下参数。
所以如果格式字符串是"%s Geeks Quiz ",它将用格式字符串后面的第一个参数替换"%s",如果是相同的字符串,那么输出将是"%s Geeks Quiz Geeks Quiz "。
如果存在与相应格式代码不匹配的参数,则将其简单地忽略。
另外,这与宏无关。
【讨论】: