C语言中的隐式转换?

3

这里发生了什么:

printf("result = %d\n", 1);
printf("result = %f\n", 1);

输出:

result = 1
result = 0.000000

如果我在尝试打印这些变量之前确保它们的类型,那么当然可以正常工作。为什么第二个打印语句没有被隐式转换为1.00000?
5个回答

8
在第二种情况下,您的格式字符串与参数类型不匹配 - 结果因此是未定义的行为。

9
“行为”中多一个字母“u”是一个额外的加分项。对于英国人来说,这个字母相当于“备胎”,以防“o”遭受不幸。 - Moo-Juice
1
@Moo-Juice:同样也为了让这个单词拥有完整的元音字母集合。 - caf
1
@caf:为什么我找不到y? =) - Arkku
1
@Arkku:顺便说一下,完全不相关的话题,单词“facetiously”按字母顺序包含所有元音字母(包括y!) - 英语中至少还有一个单词具有相同的特性。 - Paul R

4
1没有转换成1.0的原因是,printf只是一个具有可变参数数量的C函数,并且只有第一个(必需)参数具有指定类型(const char *)。因此编译器“无法”知道它应该转换“额外”的参数——它在printf实际读取格式字符串并确定它应该得到一个浮点数之前被传递。
现在,不可否认的是,您的格式字符串是编译时常量,因此编译器可以将printf作为一个特殊情况,并警告您有关不正确的参数(正如其他人所提到的,一些编译器至少会这样做,如果您要求他们)。但在一般情况下,它不能知道任意vararg函数使用的具体格式,也可能以复杂的方式构造格式字符串(例如在运行时)。
最后,如果您希望将特定类型作为“可变”参数传递,需要进行强制类型转换。

请注意,对于可变参数,charshort 会被提升为 int,而 float 会被提升为 double - tomlogic

2
一个未定义的行为。一个整数被当作浮点数处理。

意思是“一个整数被当作浮点数处理”。 - Paul R
1
printf 实际上正在寻找一个 double。 - caf

1
简短的回答是printf并不是真正的C++。Printf是一个C函数,它接受一个可变参数列表,并根据格式字符串中指定的类型将提供的参数应用于基础格式字符串。
如果您想进行任何实际类型检查,您应该使用流和字符串 - 这是好老的C风格printf的实际C++替代品。

0

有趣,假设你放置了'1.0'应该没问题

我想printf只会获取变量的地址,它无法知道它是什么。但我认为编译器应该有良心地警告你。


编译器不知道函数期望的类型,这就是使得可变参数函数很容易出错的原因。 - Alexander Rafferty
@Alexander:请注意,某些编译器(例如gcc)会检查printf等的格式字符串,并且在参数数量和/或类型不匹配时可能会发出警告。 - Paul R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接