My teacher has assigned a program to use both if-else
statements and switch
statements, so we understand how to implement both. The program asked us to prompt the user to input their weight and height in pounds and meters respectively. This is my attempt:
Without the 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; } }
With the switch
#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; } }
This was the way I thought of, to include a switch statement. Is there some way to implement the first code block to just a switch statement?
I was almost certain that it could not be done to use ranges nor to use doubles (18.5). I emailed my teacher and they gave me an answer along the lines of
It may not make sense to you, but sometimes you are going to have to write a program that does not make sense. I am not saying that you don't have legitimate questions, but if anyone can figure it out you can. But then, maybe it can't be figured out. That's the challenge".
So, I'm asking: Is there some method to just use a switch statement for the first code block, or is what I did the best way to use a switch statement in the code, even if it is in no way necessary?
Using range in switch case in C/C++ In the switch statement we pass some value, and using different cases, we can check the value. Here we will see that we can use ranges in the case statement. After writing case, we have to put lower value, then one space, then three dots, then another space, and the higher value.
Explanation: The switch/case statement in the c language is defined by the language specification to use an int value, so you can not use a float value. The value of the 'expression' in a switch-case statement must be an integer, char, short, long. Float and double are not allowed.
In computer programming languages, a switch statement is a type of selection control mechanism used to allow the value of a variable or expression to change the control flow of program execution via search and map.
As always in C++, favour standard library algorithms. In this case you want to do a range lookup. This is easy with an ordered sequence of boundaries:
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; };
Actually, I suggest you
switch
(see BONUS section below)using namespace std
(see Why is "using namespace std" considered bad practice?)See a live demo on 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"; } }
Prints
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
BONUS
You can be more elegant without the requirement to use 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)); }
Unless you have an absolutely ghastly compiler extension, you can't switch
on a range in C++.
But you could use a switch elegantly if you create a std::vector
of the BMI ranges:
std::vector<double> v = {18.5, 25.0 /*etc*/}
Then use std::lower_bound
along with std::distance
to get the position of a given BMI in the above ranges. This is the quantity that you switch
on.
You could then go one stage further and define a std::vector<std::string>
of the output messages. Then you need neither a switch
nor an if
block! All the selection logic is delegated to std::lower_bound
.
I deliberately haven't given you the full code: I trust these hints are sufficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With