Hey, I'm currently taking a introductory class for C++, I feel proud that I wrote a calculator program. Is there anything I can do to make my calculator more compact?
#include <iostream>
#include <string>
using namespace std;
int main()
{
start:
char what_is;
double num1, num2, num3, final, numbers;
int restart;
cout << "Pick an operation: +, -, *, /.\n";
start2:
cin >> what_is;
if (what_is == '+' || what_is == '-' || what_is == '*' || what_is == '/') {
cout << "Do you want to use 2 or 3 numbers?\n";
cin >> numbers;
}
else {
cout << "Please pick an operation.\n";
goto start2;
}
The general strategy is to look at each of your branches, and identify the things they have in common. Factor out the things that are common into a function, and provide the things that aren't common as arguments to the function.
Have an array of size 3. Pass in the number of numbers that the user wishes to compute with. If the user chooses to compute with less than 3 numbers, you simply don't use the last element of the array. This will reduce your code from 8 branches to 4 branches.
If you want to get even fancier, you can pass a string + function pointer/functor combo that prints and does the specified calculation type.
compact code isn't always a goal, it needs to be readable too.
Ganado gave you a great start on a happy medium between too much bloat and too compact to comprehend. The whole thing can be done in a few lines, but it would be gibberish. If you used recursion, for example, you can hide the # of numbers you want to process (you allow 3 currently) in the call stack and do N without asking the user for them.
one thing to do is look at other similar software. if you fire up windows calc, you will see...
- it does not prompt you for anything
- it does not spew text along with the results
- all it does is show what you typed in or the result of your last operation.
you may find all that spew useful, and that is fine, but most calculators are pretty minimal.
some general tips..
- try to keep the user interface (here, that is cin and cout) distinct from the work being done. Next week, if you learn to write a GUI program, can you pull the calculator part out and just have a new input/output interface using the GUI code? No, it is all intertwined... keep this in mind and eventually it will be second nature as you write more code.
- case statements should usually call a function. Large case statements are hard to track and follow... this is just style, but consider:
case a: foo(); break;
case b: bar(); break;
it is easy to see if you miss a break, or leave one out intentionally, or forgot the default, and what each case does is self documented with the good function names (not foo and bar obviously).
I did a calculator a few years ago when win 10 came out because their built in one was so ugly and annoying. Its exactly like yours.. a big switch statement with fat cases and the interface mixed in with the work -- and I know better, I just was terribly lazy about the style and all. If I had known I would use it for so many years... I treated it like a throw-away :(
Do NOT feel bad about any suggestions or criticisms etc... if it works, that is already a great start, and asking for suggestions to improve it is a rarely seen (great) attitude.
Good points, jonnin. Less compact code that separates the back-end logic from the UI is often better than compact code that clumps it all together.
And in real life, strings often need to be translated into multiple languages, so my solution would not extend well to that because it couples the function logic and the strings presented to the user too much.
KennyV2, a fun little project I would recommend is making your own command-line calculator that can handle order of operations, exponentiation, and parentheses. You can use the Shunting Yard algorithm as the basis for this. I find myself still using it when I want to do a small calculation.
that is correct, the human has to mentally adjust the input. you get used to it... my first calculator was RPN ... so its not even a thought anymore. Well, not counting a do-nothing one with an = button, that could only +-*/