c ++简单的功能困境

时间:2017-08-18 17:36:07

标签: c++ function return

我正在学习c ++。这是我的问题:

简单"计算器"程序:读取两个数字和一个符号,将它们传递给函数calculate,如果forbiden char输入则返回值或错误。我提出了两个版本的功能,我不知道哪个版本是正确的#34;。他们在这里:

第一个直接打印,这不是一个好习惯(是吗?)。

void calculate(int x, int y, char s) {
  switch (s) {
  case ('+'): {
    std::cout << x + y << "\n";
  }
  case ('-'): {
    std::cout << x - y << "\n";
  }
  case ('*'): {
    std::cout << x * y << "\n";
  }
  case ('/'): {
    std::cout << x / y << "\n";
  }
  default: {
    std::cout << "Wrong sign input. Choose on of the following four:+-*/\n";
  }
  }
}

第二个人只做一件工作,有一个缺陷:例如输入是&#39; 5&#39;&#39; 6&#39;和&#39; - &#39;它将返回-1,并且它将被调用者处理为错误。

int calculate(int x, int y, char s) {
  switch (s) {
  case ('+'): {
    return x + y;
  }
  case ('-'): {
    return x - y;
  }
  case ('*'): {
    return x * y;
  }
  case ('/'): {
    return x / y;
  }
  default: {
    return -1;
  }
  }
}

在给定的情景中你会做什么?

5 个答案:

答案 0 :(得分:2)

您可以使用返回值来返回操作结果或状态代码,但不能同时返回两者(除非您使用我应避免的特殊值。)如何使用状态的返回值,并将结果设置为输出参数?

int calculate(int x, int y, char s, int & result); // returns: 0 - success; -1 - failure

答案 1 :(得分:1)

你有几个更好的选择。

  1. 抛出异常
  2. 返回std::numeric_limits<int>::max()
  3. 将实际结果放在由指针/引用传递的变量中,并使用状态返回值
  4. 我会选择例外。

    default:
        throw std::invalid_argument(std::string("invalid operator: ") + s);
    

答案 2 :(得分:1)

首先,将计算与输出计算结果分开是个好主意。

提出如何处理错误输入的问题......

另一种能够返回状态和结果的方法是使用std::pair作为返回类型。

std::pair<bool, int> calculate(int x, int y, char s)
{
   ...
}

并确保为成功案例返回{true, result},并针对不成功案例返回{false, 0}

答案 3 :(得分:0)

修改

处理错误的正确方法是抛出和捕获。这是一个版本。

#include <iostream>
#include <stdexcept>
using std::cout;
using std::cin;
using std::cerr;
using std::invalid_argument;

int calculate(int, int, char);

int main()
{
    int num1, num2;
    char symbol;
    cin >> num1 >> num2 >> symbol;
    try {
        cout << calculate(num1,num2,symbol) << '\n';
    } catch (const invalid_argument& error) {
        cout << error.what() << '\n';
        return 1;
    }
    return 0;
}

int calculate(int x, int y, char s) {
switch (s) {
    case '+':
        return x + y;

    case '-':
        return x - y;

    case '*':
        return x * y;

    case '/':
        return x / y;

    default:
        throw invalid_argument("Received non existing option!");
}
}

此处还有一个没有投掷的版本。

这是您的代码的工作版本。

#include <iostream>
using std::cout;
using std::cin;
using std::cerr;

int calculate(int, int, char);

int main()
{
    int num1, num2;
    char symbol;
    cin >> num1 >> num2 >> symbol;
    cout << calculate(num1,num2,symbol) << '\n';
    return 0;
}

int calculate(int x, int y, char s) {
switch (s) {
    case '+':
        return x + y;

    case '-':
        return x - y;

    case '*':
        return x * y;

    case '/':
        return x / y;

    default:
        cerr << "Unrecognised option!\n";
        return -1;
}
}

我也改变了格式。如果您对代码有任何疑问,请随意浏览。确实要问。

回答问题:更喜欢第二种方式。这是正确的方法。

答案 4 :(得分:0)

输出和计算应该是单独的功能。但是,如果它也可以是有效的输出值,则不应使用特殊的sentinel值来指示错误。

真正的问题是输入验证和计算是不同的功能。我会为潜在的操作创建一个enum,并将其传递给。

enum class Operation {
    ADD,
    SUBTRACT,
    MULTIPLY,
    DIVIDE
};

然后让calculate接受Operation。你仍然需要在某个地方验证输入,但它不应该在同一个地方。

default中你仍然需要一个calculate个案,因为enum s的值不是声明的值,但是因为你应该在别处验证输入,你可以制作这很简单assert