【问题标题】:why my printf is always repeating the first output [duplicate]为什么我的 printf 总是重复第一个输出[重复]
【发布时间】:2021-02-23 07:31:45
【问题描述】:
#include <stdio.h>
#include <math.h>

int main(void)
{
    float a = 16777215;
    int b = pow(2, 26);
    float c = 22345678;
    printf("%f\n", a);
    printf("%f\n", b);
    puts("---------------");
    printf("%f\n", c);
    printf("%f\n", b);
    return 0;
}

输出:

16777215.000000
16777215.000000
---------------
22345678.000000
22345678.000000

为什么前面的 printf 输出会影响后面的 printf 输出?

【问题讨论】:

  • 启用警告,int 不是%f。这是未定义的行为。
  • 您通过传递类型错误的数据来调用 未定义的行为。确定此特定结果的详细原因将需要有关环境的一些知识,包括调用约定。

标签: c


【解决方案1】:

b 不是浮点数。尝试 %i 表示整数或 %d 表示小数。

 #include <stdio.h>
 #include <math.h>
 
 int main(void)
 {
     float a = 16777215;
     int b = pow(2, 26);
     float c = 22345678;
     printf("%f\n", a);
     printf("%i\n", b);
     puts("---------------");
     printf("%f\n", c);
     printf("%i\n", b);
     return 0;
 }

【讨论】:

    【解决方案2】:

    你需要匹配类型否则可能会发生奇怪的事情:

    printf("%d\n", b);
    

    使用clang 编译原始代码会给出有用的警告:

    pow.c:10:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
        printf("%f\n", b);
                ~~     ^
                %d
    pow.c:13:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
        printf("%f\n", b);
                ~~     ^
                %d
    

    varargsprintf 这样的函数很难确定它们的类型要求,这取决于像 clang 这样的编译器要加倍努力并显示这样的提示。在调用此类函数时,您需要格外小心,并确保您按照文档中的说明准确进行操作。

    至于这最终是如何发生的,目前尚不清楚,但不一定如此。未定义的行为就是这样:任何事情都可能发生。它可以打印同样的东西。它可以工作。它可能会崩溃。不必解释。

    【讨论】:

    • printf("%f\n", (double)b);
    • 当然,但阻力最小的路径是一个字母的修复。
    【解决方案3】:

    尝试使用 %f 打印整数时的未定义行为

    试试

    printf("%d\n", b);
    

    为了回答您的具体问题,我的猜测是,在汇编级别,如果未正确指示转换,它将使用先前存储在 eax 寄存器中的值跳转到 ret。

    【讨论】:

      猜你喜欢
      • 2016-09-20
      • 2018-07-19
      • 1970-01-01
      • 2015-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      相关资源
      最近更新 更多