Floating point 浮点访问说明符的行为与预期不符 #包括 int main() { printf(“%f”,5); }

Floating point 浮点访问说明符的行为与预期不符 #包括 int main() { printf(“%f”,5); },floating-point,Floating Point,此代码正在打印0.000000。任何人都能解释为什么会发生这种情况。%f格式需要一个double参数,您正在传递一个int。这是未定义的行为,任何事情都可能发生。你很幸运,所发生的只是0.00000的印刷 在C语言中,变量函数不知道在调用位置传递给它们的参数的类型。对于printf,他们只能信任格式字符串来提供该信息。任何好的编译器都应该在参数类型和(编译时已知的)格式字符串不匹配时发出警告,我很惊讶你们的不匹配。函数的实现可以依赖于已应用的默认参数提升,但仅此而已 在实践中,两种常见的情况是参

此代码正在打印0.000000。任何人都能解释为什么会发生这种情况。

%f
格式需要一个
double
参数,您正在传递一个
int
。这是未定义的行为,任何事情都可能发生。你很幸运,所发生的只是0.00000的印刷

在C语言中,变量函数不知道在调用位置传递给它们的参数的类型。对于
printf
,他们只能信任格式字符串来提供该信息。任何好的编译器都应该在参数类型和(编译时已知的)格式字符串不匹配时发出警告,我很惊讶你们的不匹配。函数的实现可以依赖于已应用的默认参数提升,但仅此而已


在实践中,两种常见的情况是参数在堆栈上传递,在这种情况下,在调用站点推送的
int
5
将被解释为64位
双精度
,或者参数通过寄存器传递,在这种情况下,
printf
函数将从浮点寄存器中获取一个
double
值,该值未在调用站点设置,并且包含上次使用时留在那里的值。

这称为未定义行为,因为“%f”需要一个float或double,而您给它的是整数
5

未定义的行为意味着编译器可以做任何合法的事情来处理这种情况

要解决此问题,您有三个选项:

  • printf(“%i”,5)
  • printf(“%f”,5.0)
  • printf(“%f”,(双)5)

  • 这是因为在您的示例中,
    5
    是一个整数,而不是浮点。因此,当您使用格式字符串
    %f
    将其传递给
    printf
    时,您会得到未定义的行为。要使其成为浮点,请使用浮点(
    5.0
    )声明它。这将为您提供预期的输出

    例子:
    %f
    double
    类型(或
    float
    ,它在变量参数列表中自动升级为
    double
    )的格式说明符,但您要向它传递一个
    int
    。正如其他回答者正确指出的那样,这是未定义的行为

    但是为什么输出是零而不是其他垃圾值呢?这需要了解一些最常见的问题

    最有可能发生的情况是,您(可能)的32位
    int
    值将零扩展为64位
    值,这样额外的32位零将填充符号位、11位指数和有效位的前20位。这导致一个值非常接近于零,以至于定点
    %f
    格式将其四舍五入到
    0.00000
    。使用
    %e
    %g
    格式可能会显示一个小但非零值

    同样,这只是一个实现细节,不同的C实现可能会给出不同的输出,或者导致分段错误

    你可能想写的是

    • printf(“%f”,5.0)
      (为
      %f
      格式使用正确的数据类型),或
    • printf(“%d”,5)
      (为
      int
      类型使用正确的格式字符串)

    为防止意外使用不匹配的
    printf
    调用,如
    printf(“%f”,5)
    ,启用编译器警告(例如,将
    -Wall
    选项与GCC一起使用),编译程序时要注意它们。

    因为int显示为double-这是逗号后要显示的位置的定义-看看如何在google中通过printf()方法显示double/float:)编译器没有警告您关于
    %f
    -int不匹配的问题吗?试着自己调查一下。。比如说,[%f]、5.0][%f]、.5][“%.5f”、5][“%.5f”、5.0]零扩展不会发生在通用IA-32 ABI上(32位被推送,64位被读取,没有零扩展),也不会发生在通用的x86-64 ABI上(第一个浮点参数是从
    xmm0
    获得的),所以我不确定您的观点是什么。
    #include <stdio.h>
    int main()
    {
        printf("%f",5);
    }
    
    #include <stdio.h>
    int main()
    {
        printf("%f", 5.0);
    }
    
    5.000000