范围检查使用switch语句

我的老师已经分配了一个程序来使用if-else语句和switch语句,所以我们知道如何实现这两个。 该计划要求我们提示用户分别input他们的重量和身高,以磅和米为单位。 这是我的尝试:

没有开关

 #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; } } 

随着开关

 #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; } } 

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

我几乎可以肯定,使用范围和使用双打是不能做到的(18.5)。 我发邮件给老师,他们给了我一个答案

这对你来说可能没有意义,但是有时你必须写一个没有意义的程序。 我并不是说你没有合理的问题,但是如果有人能弄清楚,你可以。 但是,也许它不可能被弄清楚。 这是挑战“。

所以,我问:是否有一种方法只是使用switch语句的第一个代码块,或者是我做了什么最好的方式来使用代码中的switch语句,即使它没有任何必要?

和往常一样在C ++中,更喜欢标准库algorithm。 在这种情况下,你想做一个范围查找。 这是一个有序的边界序列很容易:

 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; }; 

其实我build议你

  • 考虑不要使用switch (见下面的BONUS部分)
  • 做一个function而不是直接打印
  • using namespace std (请参阅为什么是“使用名称空间标准”被认为是不好的做法? )

在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"; } } 

打印

 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 

奖金

不需要使用switch就可以更加优雅:

住在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)); } 

除非你有一个绝对可怕的编译器扩展,否则你不能在C ++中打开一个范围。

但是,如果您创buildBMI范围的std::vector ,则可以优雅地使用开关:

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

然后使用std::lower_boundstd::distance来获取给定BMI在上述范围内的位置。 是您switch的数量。

然后你可以进一步去一个阶段,并定义输出消息的std::vector<std::string> 。 那么你不需要一个switch或一个if块! 所有select逻辑委托给std::lower_bound

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

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

 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; } 

你需要类似的东西

 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; } 

逻辑是将if-elses转换成一个math公式,返回一个int。

你不能在交换机内使用双精度。 该文件说:

 switch ( expression ) case constant-expression : statement [default : statement] 

该expression式必须是整型或types的types,其中有一个明确的转换为整型。 积分促销按照积分促销中的描述进行。

在旁注:

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

 switch(x){ case 0: cout << "Test1"; break; case 0 ... 9: cout << "Test2"; break; 

C ++中的开关只允许你检查整数和字符的值。

BMI是双重types,所以不可能在交换机中检查它的值。

在你的解决scheme中,你也应该声明variablesBMI为double。 如果将其声明为整数,则所有的小数结果将被转换为整数,并且将丢失小数位数。

你可以从一个数组/vectordynamic地计算你的case标签,而不是硬编码一个if / elseexpression式:

 //#include "stdafx.h" #include <iostream> using namespace std; inline int seg(double d){ //calculate segment for a BMI of d constexpr double segs[] = { 18.5, 25, 30, 35 }; constexpr int n = sizeof(segs)/sizeof(double); int r; for(r=0; r<n; r++) if(d<segs[r]) return r; return r; } 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); switch (seg(BMI)) { case 0: cout << "You are underweight" << endl; break; case 1: cout << "You are a normal weight " << 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; } } 

(如果你真的想要的话,你甚至可以使segfunctionconstexpr )。

你可以做一些事情:

 switch ((round)BMI) { case 1: case 2: case 3: .... case 15: case 16: case 17: cout<< "You are underweight " << endl; break; case 18: ... case 24: cout << "You are normal" << endl; break; case 25: ... case 29: cout << "You are overweight" << endl; break; case 30: ... case 34: cout << "You are obese" << endl; break; default: cout << "You are gravely overweight" << endl; } 

此外,我不禁注意到,因为您正在使用if-else您可以避免else-if语句中的第一个条件,如:

 if (BMI < 18.5) { cout << "You are underweight " << endl; } else if (BMI < 25.0) { cout << "You are normal" << endl; } else if (BMI < 30.0) { cout << "You are overweight" << endl; } else if(BMI < 35) { cout << "You are obese" << endl; } else { cout << "You are gravely overweight" << endl; } 

除此之外,你的两个实现看起来不错。