【问题标题】:Why the following code gives this output?为什么下面的代码给出了这个输出?
【发布时间】:2016-04-30 20:13:45
【问题描述】:

我正在使用printf() 函数进行调整。由于printf() 函数采用格式说明符来识别要打印的数据类型(如果我错了,请纠正我)作为参数传递给它的数据类型的值,所以我尝试做这样的事情---

#include<stdio.h>
int main()
{
char *f="%d";
char *g="asd";

printf(f,g);
return 0;
}

而o/p是--

4210739

我无法理解为什么 o/p 是一个数字?

【问题讨论】:

    标签: c printf format-specifiers


    【解决方案1】:

    因为,您的代码调用了undefined behavior

    您正在尝试使用 %d 格式说明符打印 字符串。您应该改用 %s 格式说明符。对特定格式(转换)说明符使用错误类型的参数会调用 UB。

    引用C11,第 7.21.6.1 章

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

    改变

    char *f="%d";
    

    char *f="%s";
    

    【讨论】:

    • 这当然不是未定义的行为。格式 %d 告诉 printf() 语句将参数视为整数。将指针(内存地址)视为整数非常高兴。它打印的数字是g的地址
    • @Tibrogargan 所以你基本上是说,C 标准是错误的?哇...多么美好的一天!
    • @Tibrogargan - 允许系统在不同的寄存器中传递指针和整数(以及浮点值),而无需定义它是如何做到的。使用错误的格式可能会打印来自错误寄存器的值 - 完全未定义。
    • @Tibrogargan 我看不出 6.3.2.3 的相关性。这里没有发生指针到整数的转换。可变参数只接受默认参数提升。指向整数的指针不是默认参数提升。
    • @Tibrogargan nopes,因为对于这种情况,标准提到了 UB。我很好。 :)
    【解决方案2】:

    如前所述,%d 说明符指定您将传递一个整数作为第二个参数,并改为传递一个指针(*char 类型)变量。所以printf() 例程将指针解释为一个整数并按原样打印它(实际上是它的值)。

    要正确输出字符串,您应该使用%s 说明符。

    【讨论】:

      【解决方案3】:

      你说,

      由于 printf() 函数采用格式说明符来识别要打印的数据类型(如果我错了,请纠正我)

      我不确定,但我认为你在这里可能有点错误。

      当你打电话时

      printf(f, g);
      

      要理解的关键是printf 无法知道g 的类型

      当您调用 printf 时,您的工作是确保对于您在格式字符串中使用的每个格式说明符(即每个 % 事物),您传递一个参数正确的类型。对于格式字符串中的每个%d,您必须传递一个int。对于格式字符串中的每个%f,您必须传递一个double。对于格式字符串中的每个%s,您必须传递一个指向有效字符串的char *。以此类推。

      在您的代码中,格式字符串中有一个%d,但不是传递int,而是传递一个指向字符串的char *。所以你不会得到你期望的结果。

      %d 想要int,但你没有给它。你传递了一个char *,但printf 不知道如何处理它。 (如果您使用过%s,那么printf 就会知道如何处理char *。)

      【讨论】:

        猜你喜欢
        • 2021-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-12
        • 2012-09-21
        • 1970-01-01
        相关资源
        最近更新 更多