【问题标题】:Why don't I receive the wanted output of 2.50000...?为什么我没有收到想要的输出 2.50000...?
【发布时间】:2018-04-21 04:36:01
【问题描述】:

当我输入 "printf("%f\n", 5 / 2);" 行时在第 18 行和第 21 行中,我没有得到 2.5000 ......但是 0.0000 和 65,我不明白为什么。

int main(void){int a = 65;
char c = (char)a;
int m = 3.0/2;
printf("%f\n", 5 / 2);
printf("%c\n", c);              // output: A
printf("%f\n", (float)a);       // output: 65.000000
printf("%f\n", 5 / 2);
printf("%f\n", 5.0 / 2);        // output: 2.5000000
printf("%f\n", 5 / 2.0);        // output: 2.5000000
printf("%f\n", (float)5 / 2);   // output: 2.5000000
printf("%f\n", 5 / (float)2);   // output: 2.5000000
printf("%f\n", (float)(5 / 2)); // output: 2.0000000 - we cast only after division and result was 2
printf("%f\n", 5.0 / 2);        // output: 2.5000000
printf("%d\n", m);              // output: 1
system("PAUSE");
return 0; }

输出是:

0.000000
A
65.000000                                                                   
65.000000
2.500000
2.500000
2.500000
2.500000
2.000000
2.500000
1

【问题讨论】:

  • 第 18 行是哪一个?
  • %f 请求double5 / 2 的结果是 int (2)。如果您提供与请求类型不同类型的参数,则结果未定义。
  • 也许有匹配的副本,但应该是核心问题(使用错误的 printf 格式说明符)。
  • @purplepsycho 不,这不是一个合适的副本——这里的核心问题不是整数除法,而是使用了错误的 printf 格式说明符。

标签: c input output


【解决方案1】:

您不能使用%f 来格式化整数。这样做会调用未定义的行为。表达式5 / 2 等于整数2。您必须使用整数格式,例如%d,或者将其转换为double 以使用%f。所以改变:

printf("%f\n", 5 / 2);

到任一:

printf("%d\n", 5 / 2);

或:

printf("%f\n", (double) (5 / 2));

【讨论】:

  • ... 否则(如在原始代码中)是未定义的行为,顺便说一句,将打印什么取决于具体的实现。
  • @FelixPalmen 对,如果使用不兼容的格式,你无法预测它会做什么。
  • 这只是为了可能改进您的正确(和 uv'd)答案,以防 OP 有兴趣“解释”他的 0.0 输出:)
  • @FelixPalmen 好的,我添加了一条评论。
【解决方案2】:

来自C Standard#7.21.6.1p9

如果转换规范无效,则行为未定义。282) 如果任何参数不是相应转换规范的正确类型,则行为未定义。

表达式5/2 将结果作为整数2 给出,这是您在printf() 中使用的转换规范%f 的错误类型,并导致未定义行为

为了获得所需的输出(即 2.500000),您可以在 printf() 中使用 float 对表达式进行类型转换:

printf("%f\n", (float)5 / 2); // Output: 2.500000

作为替代方案,您可以将5/21.0 相乘以获得所需的结果,如下所示:

printf("%f\n", 1.0 * 5 / 2); // Output: 2.500000

注意:在这里,请确保在表达式中multiplication1.0 应该在5 / 2 之前,因为multiplicationdivision 具有相同的优先级并留给正确的结合性。结果与printf()5 / 2 * 1.0 表达式的预期结果不同。

【讨论】:

  • 可能是吹毛求疵,但它们不是从左到右执行,而是从左到右关联。
【解决方案3】:

问题是,printf 参数列表中的参数必须与格式字符串中指定的类型匹配。这里

printf("%f\n", (float)a);       // output: 65.000000

你会得到你期望的输出,但是在这里:

printf("%f\n", 5 / 2);

你没有得到2(整数除法的预期结果),但65.00000,因为printf()“在错误的地方寻找”值(即一些浮点寄存器,其中不存在整数除法的结果,但 printf 之前的旧值徘徊)。

因此,您始终必须确保格式字符串的类型和 printf 参数的类型正确匹配,否则会出现未定义的行为。

【讨论】:

    猜你喜欢
    • 2021-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多