Hi ggxgank,
Just a word of practice... you will probably encounter a lot of case where you will need a "switch". You're still learning so it's ok to experiment.
Just note that "switch" is a bad smell and you will learn of lot (about good code) if you always try to look for the reason why the switch "is necessary" and try to replace it by other things.
For example here, don't be afraid to chain 5 "if" ^_^.
Also, take the habit to use functions ;o) and good names like :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
int readNumber()
{
int number;
std::cin >> number;
return number;
}
int doAddition()
{
int a = readNumber();
int b = readNumber();
return a + b;
}
int main()
{
using namespace std;
//--
for(auto keepGoing = true; keepGoing;)
{
cout << endl << "Select a Function 1-5" << endl;
cout << "1 - Addition" << endl;
cout << "2 - Subtraction" << endl;
cout << "3 - Division" << endl;
cout << "4 - Multiplication" << endl;
cout << "5 - quit ^_^" << endl;
int const operation = readNumber();
if(1 == operation)
{
int const result = doAddition();
std::cout << "Your Result is " << result << std::endl;
}
else if(2 == operation)
{
...
}
...
else if(5 == operation)
{
keepGoing = false;
}
else
{
}
}
//--
return 0;
}
| |
You will see more clearly the structure of your process. The refactoring will then be easier.
Not a thing to do, but you can eliminate the succession of "if" that looks too much like a kind of "switch" by using a table of functions : it's "simple" since you already use a number to indicate the operation you want to execute...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
#include <iostream>
int readNumber()
{
int number;
std::cin >> number;
return number;
}
int doAddition()
{
return readNumber() + readNumber();
}
int doSubtraction()
{
return readNumber() - readNumber();
}
int doMultiplication()
{
return readNumber() * readNumber();
}
int doDivision()
{
return readNumber() / readNumber();
}
typedef int (operationFunction)();
int readOperation()
{
using namespace std;
cout << endl << "Select a Function 1-5" << endl;
cout << "1 - Addition" << endl;
cout << "2 - Subtraction" << endl;
cout << "3 - Division" << endl;
cout << "4 - Multiplication" << endl;
cout << "5 - quit ^_^" << endl;
return readNumber();
}
int main()
{
operationFunction const* const doOperation[5] = { nullptr, doAddition ,doSubtraction, doMultiplication, doDivision };
for(auto keepGoing = true; keepGoing;)
{
int const operation = readOperation();
if((1 <= operation) && (operation <= 4))
{
int const result = (*doOperation[operation])();
std::cout << "Your Result is " << result << std::endl;
}
else if(5 == operation)
{
keepGoing = false;
}
else
{
std::cout << "Game over man !" << std::endl << std::endl;
}
}
//--
return 0;
}
| |
The "function pointers" thing is given only as an example of how to get rid of a switch, it is not to do per say. I find that a bit C-ish and ugly, but it's a lot better than a switch especially if your "routing" functionality use a simple integer to dispatch the operation.
You can see that the refactoring into functions make the code a lot easier to read but also to maintain because now, you have four operations that do exactly the same except for the computation part.
And this is what we expect somehow of a calculator... because then, you can add any two-infix-operand operation you want, just the same way ^_^
Note also that you don't have anymore all of those local variable that polluted your code... especially in a switch --> read more about local variable in a switch ;o)
Have fun :oP~