【问题标题】:Explanation of the output obtained by using Macro使用宏获得的输出说明
【发布时间】: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;
}

【问题讨论】:

    标签: c macros printf


    【解决方案1】:

    为什么第二个% 没有打印出来?

    Ans :让我们将printf() 签名与您的用法进行比较,好吗?

    根据man page,签名,

    int printf(const char *format, ...);
    

    和你的使用情况

    printf(scanf, scanf);
    

    这里,

    • 第一个scanf 表示format 字符串,其中包括转换说明符。
    • 第二个scanfprintf()中第一个%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 就被忽略了。

    【讨论】:

      【解决方案2】:

      宏展开为:

      printf("%s Geeks Quiz ", "%s Geeks Quiz ");
      

      其中第一个字符串是打印格式字符串,第二个字符串是传递给该字符串的参数。

      所以第二个字符串将放在第一个字符串的 %s 的位置:

       "%s Geeks Quiz "
       ^
       Insert second string "%s Geeks Quiz " here.
      
      "%s Geeks Quiz  Geeks Quiz "
      

      【讨论】:

        【解决方案3】:

        只有第一个字符串是实际的格式化字符串,它是 printf 用来查找像 "%s" 这样的格式化代码的字符串。当它找到一个格式化代码时,它替换为相应的以下参数。

        所以如果格式字符串是"%s Geeks Quiz ",它将用格式字符串后面的第一个参数替换"%s",如果是相同的字符串,那么输出将是"%s Geeks Quiz Geeks Quiz "

        如果存在与相应格式代码不匹配的参数,则将其简单地忽略。

        另外,这与宏无关。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-04
          • 2014-06-24
          相关资源
          最近更新 更多