【问题标题】:Unexpected call when using function in simple driver在简单驱动程序中使用函数时出现意外调用
【发布时间】:2016-10-23 14:45:55
【问题描述】:

我正在测试函数'min',它在自己的驱动程序中返回两个double 值中的较小者。

输出应如下:
请输入第一个双精度值:
...
请输入第二个双精度值:
...

但我以相反的顺序收到前面的消息。这个问题的正确解释是什么?
以下是完整代码:

#include <stdio.h>
#include <stdbool.h>

double min(double x, double y) { return x < y ? x : y; }
void set_response(bool *);
double get_double(int);

int main(void)
{
    bool quit = false;

    printf("-----This is the driver for evaluation of \'min\' function.-----\n");
    printf("-----Enter string not beginning with \'q\' to continue.____-----\n");
    printf("-----Enter string beginning with \'q\' to quit.____________-----\n");

    while (set_response(&quit), !quit)
        printf("Result of \'min\' function is: %f\n", min(get_double(1), get_double(2))), getchar();

    printf("Thanks for efforts, dude!\n");

    return 0;
}

void set_response(bool * resp)
{
    if (getchar() == 'q')
        *resp = true;
    else
        *resp = false, scanf("%*s");
}

double get_double(int order)
{
    printf("Please enter %s double value:\n", order == 1 ? "FIRST" : "SECOND");
    double val;
    while (scanf("%lf", &val) != 1)
    {
        scanf("%*s");
        printf("Please enter %s correct double value:\n", order == 1 ? "FIRST" : "SECOND");
    }
    return val;
}

【问题讨论】:

  • C 中不保证参数的求值顺序。只有使用中间序列点(例如:&& 或 || 等)才能做到。
  • 我可以发誓我知道逗号运算符的参数是从左到右计算的,然后最右边的一个用作结果。你引起了我的注意。
  • 啊!但是函数调用 f(a,b,c) 不是使用逗号运算符! a、b 和 c 的评估顺序未指定。我从 C 常见问题中记住了这一点 - 我会看看我能找到它并引用它。
  • 找到它:c-faq.com/.xx/expr/comma.html。对于总引文完整性:K&R2 Sec。 3.5 页。 63. :-)
  • @carveone 感谢您的回答和链接有趣的资源!

标签: c function call


【解决方案1】:
min(get_double(1), get_double(2))

是一个函数调用,所以不保证其参数的求值顺序是第一get_double(1)第二get_double(2)

解决方法可能是:

double x1 = get_double(1);
double x2 = get_double(2); 

然后在函数调用中使用x1和x2作为参数:

min(x1, x2)

【讨论】:

【解决方案2】:

遵循公理:

*only one statement per line and (at most) one variable declaration per statement.*

本行参数求值顺序:

printf("Result of \'min\' function is: %f\n", min(get_double(1), get_double(2)));
getchar();

是从右到左,因为参数是从右到左压栈的。

强烈建议从您的代码中删除所有“聪明”(但不能按预期工作)的东西。

在这种情况下,对get_double() 进行两次调用并保存结果,然后调用printf() 函数。

【讨论】:

    猜你喜欢
    • 2022-01-25
    • 2018-09-13
    • 2017-12-09
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    相关资源
    最近更新 更多