user898058
user898058

Reputation:

Handling an 'else' type situation within a loop

I have a homework problem for my C++ class and the problem wants us to have the user input a wavelength and then output the correct type of radiation. The point to notice is that there are more Wave Name values than there are Wave Lengths.

My solution is listed below:

const double WAVE_LENGTH[] = { 1e-11, 1e-8, 4e-7, 7e-7, 1e-3, 1e-2 };
const char* WAVE_NAME[] = { "Gamma Rays", "X Rays", "Ultraviolet", "Visible Light", "Infrared", "Microwaves", "Radio Waves" };

double waveLength;

std::cout << "Enter a wavelength in decimal or scientific notation\nWavelength: ";
std::cin >> waveLength;

for (unsigned short i = 0U; i < 6U; ++i)
{
    if (waveLength < WAVE_LENGTH[i])
    {
        std::cout << "The type of radiation is " << WAVE_NAME[i] << std::endl;
        break;
    }
    if (i == 5U) // Last iteration
        std::cout << "The type of radiation is " << WAVE_NAME[i + 1] << std::endl;
}

My question is regarding my approach at solving the problem, specifically within the loop. I can't seem to find a way to handle all the situations without creating two conditions inside the loop which seems like it is a poor design. I realize I could use a series of if/else if statements, but I figured a loop is cleaner. Is my approach the best way or is there a cleaner way of coding this?

Thanks!

Upvotes: 0

Views: 122

Answers (3)

mb14
mb14

Reputation: 22596

You can test the last iteration in the same if. Notice there is no test anymore itn for.

for (unsigned short i = 0U; ; ++i)
{
    if (i == 6 || waveLength < WAVE_LENGTH[i])
    {
        std::cout << "The type of radiation is " << WAVE_NAME[i] << std::endl;
        break;
    }

}

Alternatively, you can add a extra wavelength set to MAX_FLOAT (or whatever is called in C++) or set the last one to zero and exit if wave_length[i] == 0.0. That way you don't need to "know" the number of wave lengths.

Upvotes: 0

Paul R
Paul R

Reputation: 212939

I think you can simplify your loop to this:

unsigned short i;

for (i = 0U; i < 6U; ++i)
{
    if (waveLength < WAVE_LENGTH[i])
    {
        break;
    }
}
std::cout << "The type of radiation is " << WAVE_NAME[i] << std::endl;

Upvotes: 4

NPE
NPE

Reputation: 500167

In my view a somewhat cleaner design is to add positive infinity as the last element of WAVE_LENGTH. This way your corner case will require no special handling:

#include <iostream>
#include <limits>

...

const double WAVE_LENGTH[] = { 1e-11, 1e-8, 4e-7, 7e-7, 1e-3, 1e-2,
                               std::numeric_limits<double>::infinity() };
const char* WAVE_NAME[] = { "Gamma Rays", "X Rays", "Ultraviolet", "Visible Light",
                            "Infrared", "Microwaves", "Radio Waves" };

double waveLength;

std::cout << "Enter a wavelength in decimal or scientific notation\nWavelength: ";
std::cin >> waveLength;

for (int i = 0; i < sizeof(WAVE_LENGTH) / sizeof(WAVE_LENGTH[0]); ++i)
{
    if (waveLength < WAVE_LENGTH[i])
    {
        std::cout << "The type of radiation is " << WAVE_NAME[i] << std::endl;
        break;
    }
}

Also note how I've avoided having to hard-code the length of the array (6U in your code) in the loop's terminal condition.

Upvotes: 1

Related Questions