在做一个项目时,我偶然发现了一个问题。使用预处理器定义值的一些算术结果为
0.00
。
#include <stdio.h>
#define PINGCOUNT 10
int main()
{
int successful = 5;
int lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;
printf("%.2lf\n", lossPercentage);
return 0;
}
我在在线编译器中重新运行了这段代码并得到了相同的结果。我不确定我的措辞是否不好,但我在网上找不到有关此主题的信息。
如果我首先声明
int count = PINGCOUNT
,然后将 PINGCOUNT
实例替换为 count
,则上述代码将起作用。此外,我尝试在一些简单的减法/加法中使用 PINGCOUNT
并且它工作正常。有什么明显我遗漏的东西吗?
由于程序中所有内容都是
int
,因此您正在进行整数除法,因此 (PINGCOUNT - successful) / PINGCOUNT
等于 0
,乘以 100
仍然是 0
。
然后,您尝试将结果打印为
double
,这会调用 未定义的行为。
更改此行
int lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;
至:
double lossPercentage = (PINGCOUNT - successful) * 100.0 / PINGCOUNT;
确保结果为
double
类型,按照您的预期执行操作。
预处理器值可以用于 C 中的算术吗?
是的。
但是为什么你不应该使用宏?
因为他们之前重新排列了程序文本 编译器正确地看到它,宏也是许多编程支持工具的主要问题。 (礼貌:Bjane Stroustrup)
虽然他说从C++的角度来说,同样是 也适用于 C 程序。
现在你的程序中发生了什么
您得到意想不到的结果并不是因为您使用了预处理器 您的计算中的值。这是因为你使用了不能的类型 存储浮点值,即int。
事实上你可以改变
int lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;
到
double lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;
另一种方法是在预处理器定义中使用 C 风格转换。
改变
#define PINGCOUNT 10
到
#define PINGCOUNT ((float)10)
并保留
int lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;
但是这里会失去精度,而且 C 型铸造会产生相关成本 - 问题只能是 运行时发现。请参阅这个SO问题。
尝试:
int lossPercentage = (PINGCOUNT - successful) * 100 / PINGCOUNT;
这只是一个整数问题: (PINGCOUNT - 成功)/PINGCOUNT) 等于 0 并且 * 100 仍然是 0。