c语言 - 将字符和整数值的加法打印为浮点数



我只是想知道为什么当我尝试打印char和整数值的加法时会得到一个 0 值。我的代码如下:

int y;
y = 10;
char z;
z = '9';
printf("%f", z + y);

这个 printf 的调用

printf("%f", z + y);

调用未定义的行为,因为您对 int 类型的对象使用了不正确的转换说明符%f

例如,您需要投射参数

printf( "%f", ( double )( z + y ) );

printf( "%f", ( float )( z + y ) );

尽管在最后一种情况下,由于默认参数升级,参数将被提升为双精度类型。

大多数情况下,当你调用一个函数,并且你传递了错误类型的参数时,C 会自动为你转换它。 例如,如果我写

#include <math.h>
int i = sqrt(144);
printf("%dn", i);

这有效,并打印12. 即使sqrt函数实际上想要一个double类型的参数,它也可以工作——因为编译器知道这一点,并在将我的int参数144传递给sqrt之前自动将其转换为double。 (在返回的过程中还有一个转换,因为sqrt返回一个double,在分配给i之前必须将其转换回int

printf函数本身就是这个规则的一个很大的例外。 在你的代码中,你有

printf("%f", z + y);

现在,你和我都知道%f想要一个double,但这不是传统上C语言可以知道的事情。 就 C 语言而言,printf函数接受一个类型const char *(即字符串)的参数,然后可能接受一些其他参数,具体取决于运行时在格式字符串中找到的特定%序列。 因此,编译器只做了一个半心半意的尝试,将它们转换为几个常见的类型,然后将它们传递给printf来完成其余的工作。 在你的例子中,由于z是一个chary是一个intz + y将是一个int,这就是传递给printf的内容。 当printf咀嚼格式字符串并找到格式说明符%f时,它无法知道实际传递了哪种类型的参数,因此它甚至无法尝试进行自己的任何转换。 它所能做的就是假设你实际上通过了double——而且,由于你没有,你会得到一个毫无意义的值。

现在,尽管正如我刚才所解释的,编译器传统上没有任何许可证来尝试将printf参数转换为正确的类型,但现代编译器通常会查看格式字符串(如果可以的话),并检查事情在运行时是否正常工作。 例如,当我通过我的一个编译器运行您的代码时,我得到warning: format specifies type 'double' but the argument has type 'int'. 如果您的编译器没有给您这样的警告,您可能想知道是否有办法启用它们,因为它们显然非常方便。

正如在注释部分中已经指出的那样,您有责任确保格式字符串和函数参数匹配。在您的情况下,它们不匹配。表达式z + y的结果是int类型,但您在格式字符串中使用了%f转换说明符,该说明符仅对数据类型floatdouble有效(float提升为double)。

如评论部分所述,您有两种选择来解决此问题:

  1. 将格式字符串更改为需要类型为int的参数,或
  2. 将参数转换为doublefloat

使用选项 #1 的解决方案如下所示:

更改行

printf("%f", z + y);

printf("%d", z + y);

使用选项 #2 的解决方案如下所示:

更改行

printf("%f", z + y);

printf("%f", (double) (z + y) );

最新更新