范围检查使用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_bound
和std::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; }
除此之外,你的两个实现看起来不错。