打印对整数和浮点数的操作结果



考虑以下C程序:

int main() {
int a =2;
float b = 2;
float c = 3;
int d = 3;
printf("%d %f %d %f %d %f %d %fn", a/c, a/c, a/d, a/d, b/c, b/c, b/d, b/d);
printf("%dn", a/c);
}

其输出为:

0 0.666667 0 0.666667 2 0.666667 0 0.666667
539648

我完全无法理解这一点。为什么将 a/c 打印为整数给出 0,而 b/c 给出 2?在涉及浮点数和整数的计算中,不是所有整数都提升为浮点数吗?所以在这两种情况下,答案都应该是0。

在输出的第二行中,我只是将 a/c 打印为整数,出于某种原因,它给出了一个垃圾值(即使当我在第一个复合 printf 语句中打印它时它给出 0)。为什么会这样?

您有未定义的行为:

printf("%d %f %d %f %d %f %d %fn", a/c, a/c, a/d, a/d, b/c, b/c, b/d, b/d);

printf的格式说明符必须与所提供参数的类型匹配。由于printf不提供包含类型的参数列表,因此仅提供...除了标准类型转换之外没有隐式类型转换。

如果你有UB,基本上任何事情都可能发生。

可能发生的情况如下:

根据格式说明符,printf会消耗调用参数中的一定数量的字节。此字节数与指定的格式类型匹配。如果字节数与作为参数传递的字节数不匹配,则所有连续参数都不同步。 当然,您对数据的解释不正确。

对于根据 C 标准的初学者,没有参数的函数main应声明为

int main( void )

例如,如果您有以下声明

int a =2;
float c = 3;

然后printf以下方式调用函数

printf( "%d", a / c );

然后在引擎盖后面发生以下事件。

表达式a / c由于通常的算术转换,具有float的类型。

当函数printf是用省略号表示法声明的,然后声明到float类型的表达式a / c时,应用了将表达式转换为类型double的默认参数提升

因此,在此调用中,尝试使用为类型int设计的转换说明符%d输出类型double表达式。 Hanse 调用具有未定义的行为。

来自 C 标准(7.21.6.1 fprintf 函数)

9 如果转换规范无效,则行为为 undefined.275)如果任何参数不是 相应的转换规范,行为未定义。

相关内容

最新更新