如何将本程序中的if else语句转为switch语句? Visual Studio 2019 C++

How do I turn the if else statements in this program to switch statements? Visual Studio 2019 C++

我已经查找了执行此操作的示例,但是当我尝试像这样格式化代码时,它不起作用。这是我要转换的程序。

#include <stdio.h> 

double comp_tax(double salary);

int
main(void)
{
    double salary, tax;

    printf("Input your annual salary >$ ");
    scanf_s("%lf", &salary);

    tax = comp_tax(salary);

    if (tax != -1.0)
        printf("your tax is $%.2f", tax);
    else
        printf("your salary is outside the table ranged");

    return 0;
}

double
comp_tax(double salary)
{
    double tax;
    
    if (salary < 0.0)
        tax = -1.0;
    else if (salary < 15000.00)
        tax = 0.15 * salary;
    else if (salary < 30000.00)
        tax = (salary - 15000.00) * 0.18 + 2250.00;
    else if (salary < 50000.00) 
        tax = (salary - 30000.00) * 0.22 + 5400.00;
    else if (salary < 80000.00)
        tax = (salary - 50000.00) * 0.27 + 11000.00;
    else if (salary <= 150000.00)   
        tax = (salary - 80000.00) * 0.33 + 21600.00;
    else
        tax = -1.0;

    return (tax);
}

switch 语句只能在条件等于整数的情况下使用。例如:

int n;
std::cin >> n;
switch(n)
{
    case 0:
        // do something if n == 0
        break;

    case 1:
        // do something if n == 1
        break;

    default:
        // otherwise, do this
}

在你的情况下,你不是基于像 salary == n 这样的逻辑进行切换,所以你不能使用 switch 语句。


从技术上讲,您可以:

switch(static_cast<int>(salary) / 5000):
{
    case 3:
    case 4:
    case 5:
        tax = 0.15 * salary;
        break;
    case 6:
    case 7:
    case 8:
    case 9:
        tax = (salary - 15000.00) * 0.18 + 2250.00;
        break;
      .
      .
      .
    default:
        tax = -1;
}

但这可能不是您想用 switch 做的。

if/else 个案例的顺序是更自然的表示。

如果代码 必须 出于某种原因被强制转换为 switch 语句,则以下可能是一种可能的混淆。

double comp_tax(double salary)
{
    double tax = 0;
    double ks = salary / 1000;

    switch((ks > 0) * ((ks < 15) + (ks < 30) + (ks < 50) + (ks < 80) + (ks <= 150)))
    {
    case 1:  tax += (ks - 80) * 0.33;  ks = 80;
    case 2:  tax += (ks - 50) * 0.27;  ks = 50;
    case 3:  tax += (ks - 30) * 0.22;  ks = 30;
    case 4:  tax += (ks - 15) * 0.18;  ks = 15;
    case 5:  tax += ks * 0.15;         return tax * 1000;
    }

    return -1;
}

注意:以上使用给定的括号和税率计算了最高 150K 的工资的累进税。它不会匹配 OP 超过 30K 的数字,因为原始代码有可疑的“跳跃”,例如 comp_tax(29999.99) == 4950comp_tax(30000.00) == 5400.

switch 只能用于比较整数与 case 中的 constexpr 整数是否相等。

我建议创建一个 std::map,将阈值作为 Keys 映射到函数,以便快速轻松地进行查找。我还建议 不要 使用硬编码公式编写程序,因为每次阈值或百分比发生变化时,您都必须重新计算这些公式。相反,您可以添加一个函数,在第一次调用 comp_tax() 函数时创建此 map 并在程序执行的其余部分保留它。

示例:

#include <cmath>
#include <functional>
#include <initializer_list>
#include <limits>
#include <map>
#include <utility>

auto make_salary_tax_map() {
    std::map<double, std::function<double(double)>> retval;

    // the thresholds and the percentages - simple to maintain
    static const std::initializer_list<std::pair<double, double>> salary_tax = {
        {     0., .00},
        { 15000., .15},
        { 30000., .18},
        { 50000., .22},
        { 80000., .27},
        {std::nextafter(150000, 300000.), .33},    // to match the <= in your comp_tax()
        {std::numeric_limits<double>::max(), .33}, // salary > 150000, percentage?
    };

    double prev_threshold = 0.;
    double add = 0.;
    double threshold;
    double percent;

    for(auto& st : salary_tax) {
        std::tie(threshold, percent) = st;

        // decrease the threshold a little to be able to use lower_bound,
        // except for the max value for a double.
        double th = threshold == std::numeric_limits<double>::max() 
                                 ? threshold
                                 : std::nextafter(threshold, 0.);

        // store the function for this threshold:
        retval[th] = [=](double s) { return (s - prev_threshold) * percent + add; };

        prev_threshold = threshold;
        add = threshold * percent;
    }

    return retval;
}

有了它,您的 comp_tax() 功能就变成了:

double comp_tax(double salary) {
    // static, so it's only initialized once:
    static const auto salary_tax = make_salary_tax_map(); 

    // efficiently find the function for this salary and call it
    return salary_tax.lower_bound(salary)->second(salary);
}