我为一次测验写了一些C代码.问题是,这个程序根据C17标准打印什么:

#include <stdio.h>

void foo(a)
{
    auto b = 1.7f;
    printf("%d\n", (int) (a + b));
}

int main(void)
{
    foo(10.6f);
}

我原以为答案是11.我的推理是这样的:a默认为int,因为如果您没有为参数指定类型(在&lt;c23中),那么就会发生这种情况,因此10.6f会将类型转换为值为10int.b默认为int,因为auto只表示自动存储持续时间(同样,在&lt;c23中),因此1.7f将类型转换为值为1的int.

但是,该函数打印2,似乎与传递给函数的浮点数的值无关.如果我传递一个int,它会如我所期望的那样工作.

这里发生了什么事?我误解了什么?

edit:我开始怀疑UB了.因为如果我这么做:

float f = 10.6f;
printf("%f\n", f);
foo(f);

结果我得了1分.

推荐答案

这是一种未定义的行为:

6.5.2.2-6

如果表示被调用函数的表达式具有 不包括原型,则整数提升是在 每个参数以及类型为Float的参数被提升为 双倍.这些被称为默认参数提升.如果 参数数量不等于参数数量,则 行为未定义.如果该函数定义为 包括原型,并且原型以省略号结尾 (,...)或提升后的参数类型不是 与参数类型兼容,其行为是 未定义.

float被提升为double,然后调用需要int的函数

C++相关问答推荐

在c++中使用堆栈的有效括号

`#if`条件中是否允许`sizeof`?

如何在C语言中正确打印图形

如何在C++中处理按键

用C语言计算文本文件中的整数个数

覆盖读取函数,但当文件描述符为3或4时,我有问题

C11/C17标准允许编译器清除复合文字内存吗?

Go和C中的数据 struct 对齐差异

为什么我在C代码中得到一个不完整的类型?

合并对 struct 数组进行排序

为什么会出现此错误?二进制表达式的操作数无效

如何使用WRITE()以指针地址的十六进制形式写入标准输出

If语句默认为true

与指针的原始C数组或C++向量<;向量<;双>>;

既然我们在 if 中将 int 的值更改为 10,为什么在第二个 fork 后,子进程及其创建的子进程都会打印 33 ?

GnuCobol 使用 double 类型的参数调用 C 函数

传递参数:C 和 C++ 中 array 与 *&array 和 &array[0] 的区别

如何在 C 中的 Postgres 函数的表中 for 循环

我怎样才能用c语言正常运行这两个进程?

将十六进制值或十进制值分配给 uint16_t 有什么区别?