使用switch语句进行范围检查

use*_*449 42 c++ switch-statement

我的老师已经分配了一个程序来使用if-else语句和switch语句,因此我们了解如何实现它们.该程序要求我们提示用户分别以磅和米为单位输入他们的体重和身高.这是我的尝试:

没有开关

#include "stdafx.h"
#include <iostream>

using namespace std;


int main()
{
    double height, weight, BMI, heightMeters, weightKilo;
    const double KILOGRAMS_PER_POUND = 0.45359237;
    const double METERS_PER_INCH = 0.0245;

    cout << "Please enter your height (inches) and weight (pounds)" << endl;
    cin >> height >> weight;

    weightKilo = weight*KILOGRAMS_PER_POUND;
    heightMeters = height*METERS_PER_INCH;
    BMI = weightKilo / (heightMeters*heightMeters);

    if (BMI < 18.5) {
        cout << "You are underweight " << endl;
    }
    else if (BMI >= 18.5 && BMI < 25.0) {
        cout << "You are normal" << endl;
    }
    else if (BMI >= 25.0 && BMI < 30.0) {
        cout << "You are overweight" << endl;
    }
    else if (BMI >= 30.0 && BMI < 35) {
        cout << "You are obese" << endl;
    }
    else {
        cout << "You are gravely overweight" << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

随着开关

#include "stdafx.h"
#include <iostream>

using namespace std;


int main()
{
    double height, weight, heightMeters, weightKilo;
    int BMI, q;
    const double KILOGRAMS_PER_POUND = 0.45359237;
    const double METERS_PER_INCH = 0.0245;

    cout << "Please enter your height (inches) and weight (pounds)" << endl;
    cin >> height >> weight;

    weightKilo = weight*KILOGRAMS_PER_POUND;
    heightMeters = height*METERS_PER_INCH;
    BMI = weightKilo / (heightMeters*heightMeters);

    if (BMI < 18.5) {
        q = 1;
    }
    else if (BMI >= 18.5 && BMI < 25.0) {
        q = 2;
    }
    else if (BMI >= 25.0 && BMI < 30.0) {
        q = 3;
    }
    else if (BMI >= 30.0 && BMI < 35) {
        q = 4;
    }
    else {
        q = 5;
    }

    switch (q) {
        case 1: cout << "You are underweight" << endl; break;
        case 2: cout << "You are a normal weight " << endl; break;
        case 3: cout << "You are overweight" << endl; break;
        case 4: cout << "You are obese" << endl; break;
        case 5: cout << "You are gravely overweight" << endl; break;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我想到的方式,包括一个switch语句.有没有办法将第一个代码块实现为switch语句?

我几乎可以肯定,使用范围也不能使用双打(18.5).我给老师发了电子邮件,他们给了我一个答案

这对你来说可能没有意义,但有时你将不得不编写一个没有意义的程序.我并不是说你没有合法的问题,但如果有人能够弄清楚你能做到的话.但是,也许它无法弄清楚.这就是挑战".

所以,我问:是否有一些方法只是为第一个代码块使用switch语句,或者是我在代码中使用switch语句的最佳方法,即使它没有必要?

seh*_*ehe 108

与C++一样,支持标准库算法.在这种情况下,您需要进行范围查找.通过有序的边界序列,这很容易:

double const boundaries[] = { 18.5, 25, 30, 35 };

switch (upper_bound(begin(boundaries), end(boundaries), BMI) - boundaries) {
    case 0: cout << "You are underweight "       << endl; break;
    case 1: cout << "You are normal"             << endl; break;
    case 2: cout << "You are overweight"         << endl; break;
    case 3: cout << "You are obese"              << endl; break;
    case 4: cout << "You are gravely overweight" << endl; break;
};
Run Code Online (Sandbox Code Playgroud)

其实,我建议你

观看Coliru的现场演示

#include <iostream>
#include <algorithm>

const char* bmi_classification(double bmi) {
    static double const boundaries[] = { 18.5, 25, 30, 35 };

    double const* lookup = std::upper_bound(std::begin(boundaries), std::end(boundaries), bmi);
    switch (lookup - std::begin(boundaries)) {
        case 0: return "underweight";
        case 1: return "normal";
        case 2: return "overweight";
        case 3: return "obese";
        case 4: return "gravely overweight";
    }
    throw std::logic_error("bmi_classification");
}

int main() {
    for (double BMI : { 0.0, 18.4999, 18.5, 24.0, 25.0, 29.0, 30.0, 34.0, 35.0, 999999.0 }) {
        std::cout << "BMI: " << BMI << " You are " << bmi_classification(BMI) << "\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

打印

BMI: 0 You are underweight
BMI: 18.4999 You are underweight
BMI: 18.5 You are normal
BMI: 24 You are normal
BMI: 25 You are overweight
BMI: 29 You are overweight
BMI: 30 You are obese
BMI: 34 You are obese
BMI: 35 You are gravely overweight
BMI: 999999 You are gravely overweight
Run Code Online (Sandbox Code Playgroud)

奖金

无需使用即可更优雅switch:

Live On Coliru

const char* bmi_classification(double bmi) {
    constexpr int N = 5;
    static constexpr std::array<char const*, N> classifications {
        { "underweight", "normal", "overweight", "obese", "gravely overweight" }};
    static constexpr std::array<double, N-1> ubounds {
        { 18.5, 25, 30, 35 }};

    auto lookup = std::upper_bound(std::begin(ubounds), std::end(ubounds), bmi);
    return classifications.at(lookup - std::begin(ubounds));
}
Run Code Online (Sandbox Code Playgroud)

  • 一个美丽的实现.通过研究每个部分,OP将受益,我也是如此. (30认同)
  • 在你的switch语句中,为什么你没有写:`upper_bound(...) - begin(boundary)`在我看来,它更通用. (2认同)

Bat*_*eba 21

除非你有一个绝对可怕的编译器扩展,否则你不能switch使用C++中的范围.

但是如果你创建了一个std::vectorBMI范围,你可以优雅地使用一个开关:

std::vector<double> v = {18.5, 25.0 /*etc*/}

然后std::lower_bound一起使用std::distance以获得给定BMI在上述范围内的位置.是你的数量switch.

然后,您可以进一步进一步定义std::vector<std::string>输出消息.那你既不需要switch也不需要if块!所有选择逻辑都委托给std::lower_bound.

我故意没有给你完整的代码:我相信这些提示就足够了.


Laj*_*pad 8

我们需要适应输入,所以,而不是这个代码:

if (BMI < 18.5) {
        q = 1;
    }
    else if (BMI >= 18.5 && BMI < 25.0) {
        q = 2;
    }
    else if (BMI >= 25.0 && BMI < 30.0) {
        q = 3;
    }
    else if (BMI >= 30.0 && BMI < 35) {
        q = 4;
    }
    else {
        q = 5;
    }

    switch (q) {
    case 1: cout << "You are underweight" << endl; break;
    case 2: cout << "You are a normal weight " << endl; break;
    case 3: cout << "You are overweight" << endl; break;
    case 4: cout << "You are obese" << endl; break;
    case 5: cout << "You are gravely overweight" << endl; break;

    }
Run Code Online (Sandbox Code Playgroud)

你需要类似的东西

switch (1 + (BMI >= 18.5) + (BMI >= 25) + (BMI >= 30) + (BMI >= 35)) {
    case 1: cout << "You are underweight" << endl; break;
    case 2: cout << "You are a normal weight " << endl; break;
    case 3: cout << "You are overweight" << endl; break;
    case 4: cout << "You are obese" << endl; break;
    case 5: cout << "You are gravely overweight" << endl; break;
}
Run Code Online (Sandbox Code Playgroud)

逻辑是将if-elses转换为数学公式,返回int.


Rah*_*thi 5

你不能在开关内使用双.文件说:

switch ( expression )
   case constant-expression : statement
   [default   : statement]
Run Code Online (Sandbox Code Playgroud)

表达式必须是整数类型或类类型,对于该类型,有明确的转换为整数类型.按积分促销中的描述执行整体推广.

在旁注:

有一些编译器(如Clang 3.5.1)允许case x ... y作为C++语言的扩展.但这也是一个完整的数据类型.就像是

switch(x){
       case 0:
            cout << "Test1";
            break;
       case 0 ... 9:
            cout << "Test2";
            break;
Run Code Online (Sandbox Code Playgroud)