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 u
We need to fit in the input, so, instead of this code:
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;
}
You need something like
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;
}
The logic is to convert the if-elses into a mathematical formula, returning an int.
A switch in C++ only allows you to check for the values of integers and chars.
The BMI is a double type, so it's not possible to check its value in a switch.
In your solution with the switch you also should declare the variable BMI as double. If you declare it as integer all decimal results will be casted to an integer, and you will lose the decimal places.
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.
You could calculate your case labels dynamically from an array/vector instead of hardcoding an if/else expression:
//#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;
}
}
(You could even make the seg functions constexpr
if your really wanted to).
You can do something like:
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;
}
Also I couldn't help but notice this that since you are using if-else
you can avoid the first condition in else-if
statements like:
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;
}
Apart from this, both of your implementations look good.
You can not use a double inside a switch. The documentation says:
switch ( expression )
case constant-expression : statement
[default : statement]
The expression must be of an integral type or of a class type for which there is an unambiguous conversion to integral type. Integral promotion is performed as described in Integral Promotions.
On a side note:
There are some compilers (like Clang 3.5.1) which are allowing the case x ... y
as an extension to the C++ language. But that too is for an integral datatype. Something like
switch(x){
case 0:
cout << "Test1";
break;
case 0 ... 9:
cout << "Test2";
break;