hey I started learning programming about a month ago and i've been teaching myself in hopes that when i start college i will be above average. I wanted to make a simple calculator program to test myself so will you all give a review and maybe give me advice in how to make it better?
all replies are appreciated...thank you very much
#include <iostream>
#include <cmath>
//gives the number PI a value
#define PI 3.14159265
using namespace std;
//defines the 3 variables needed for the operations
long double x;
long double y;
int choice;
//void functions are called in if user needs them
void add()
{
cout << "\nPlease enter a number to add\n";
cin >> y;
//makes the result equal the previous result plus what you want to add to it
x = x + y;
//tells user the new base of operations (result)
cout << "\n\n" << x << "\n\n";
}
void sub()
{
cout << "\nPlease enter a number for the subtrahend\n";
cin >> y;
x = x - y;
cout << "\n\n" << x << "\n\n";
}
void mult()
{
cout << "\nPlease enter a number to multiply\n";
cin >> y;
x = x * y;
cout << "\n\n" << x << "\n\n";
}
void div()
{
cout << "\nPlease enter a number for the divisor\n";
cin >> y;
//doesn't allow zero to be used in denominator
if (y==0)
{
do
{
cout << "\nYou are not allowed to divide by zero, input a new number\n";
cin >> y;
}
while (y == 0);
}
x = x / y;
cout << "\n\n" << x << "\n\n";
}
void exp()
{
cout << "\nPlease enter a number for the power\n";
cin >> y;
//makes the number for y the exponent of x
x = pow(x,y);
cout << "\n\n" << x << "\n\n";
}
void trig()
{
//gives choices for which triogonometric function needs to be used
cout << "\nPlease choose the trigonometric function you wish to use\n";
cout << "1. sin\n2. cos\n3. tan\n4. inverse sin\n5. inverse cos\n6. inverse tan\n7. inverse tan with two numbers\n8. back\n";
cin >> choice;
switch (choice)
{
case 1:
x = sin (x * PI / 180);
cout << "\n\n" << x << "\n\n";
break;
case 2:
x = cos (x * PI / 180);
cout << "\n\n" << x << "\n\n";
break;
case 3:
x = tan (x * PI / 180);
cout << "\n\n" << x << "\n\n";
break;
case 4:
x = asin (x) * 180 / PI;
cout << "\n\n" << x << "\n\n";
break;
case 5:
x = acos (x) * 180 / PI;
cout << "\n\n" << x << "\n\n";
break;
case 6:
x = atan (x) * 180 / PI;
cout << "\n\n" << x << "\n\n";
break;
case 7:
cout << "\nPlease enter a second number\n";
cin >> y;
x = atan2 (x,y) * 180 / PI;
cout << "\n\n" << x << "\n\n";
case 8:
break;
}
}
void log()
{
//gives two types of logarithmic functions to be used
cout << "\nWhich do you want to find?\n1. natural logarithm\n2.log base 10\n3. back\n";
cin >> choice;
switch (choice)
{
case 1:
x = log (x);
cout << "\n\n" << x << "\n\n";
case 2:
x = log10 (x);
cout << "\n\n" << x << "\n\n";
case 3:
break;
}
}
void num()
{
//allows the user to assign a new number for the base of operations
cout << "\nPlease enter a new number to start the operations with\n";
cin >> x;
cout << "\n\n";
}
void help()
{
//gives minor help (i didn't put much effort in the help function, sorry
cout << "Welcome to the Calculator help function. This calculator allows you to do\n";
cout << "simple math through the use of multiple functions. The first number that\n";
cout << "you enter is the base of operations, and after you choose the operation\n";
cout << "desired, the base of operations is the result of the most recent operation.\n";
cout << "When choosing which operation you desire, always use just the number that\n";
cout << "identifies the operator you want. In the trigonometric and logarithmic\n";
cout << "functions, the same rule applies. Thank you for using this program, it is\n";
cout << "the first program that I have created.\n\n";
}
//the main function that is always used by the program
int main()
{
cout << "Welcome to the calculator! Please enter a number to begin.\n";
//x is the base of operations
cin >> x;
//causes a loop to allow multiple operations without reopening the program
do
{
cout << "\nSelect the corresponding operator!\n";
//tells user the choices he has for operations
cout << "1. addition\n2. subtraction\n3. multiplication\n4. division\n5. exponents\n6. trigonometric functions\n7. logarithmic functions\n8. choose a new number for operation\n9. help\n0. exit\n\n";
//accepts the users input to call the function needed
cin >> choice;
switch (choice)
{
case 1:
//calls upon the addition function to be used (see void add)
add();
break;
case 2:
//calls upon the subtraction function to be used (see void sub)
sub();
break;
case 3:
//calls upon the multiplication function to be used (see void mult)
mult();
break;
case 4:
//calls upon the division function to be used (see void div)
div();
break;
case 5:
//calls upon the exponent function to be used (see void exp)
exp();
break;
case 6:
//calls upon the trigonometric function list to be used (see void trig)
trig();
break;
case 7:
//calls upon the logarithmic function list to be used (see void log)
log();
break;
case 8:
//see void num for code in choosing a new base number
num();
break;
case 9:
//see void help
help();
break;
case 0:
//exits the program
cout << "thank you for using the calculator";
break;
}
}
while (choice != 0);
First, can you please use code tags - it's the <> button at the bottom or right of the screen under format. It makes the code much easier to read.
1 2
//gives the number PI a value
#define PI 3.14159265
You can just use M_PI which is defined in the maths header.
1 2 3
//defines the 3 variables needed for the operations
longdouble x;
longdouble y;
Is there any reason to use long doubles? ordinary doubles should be fine.
Normally, you declare your functions before main, and put the definitions after main.
Consider having a ShowMenu and ProcessMenu functions.
Be careful comparing doubles, as they often cannot be represented exactly. This code fails:
1 2
double a = 0.1; //cant be represented exactly
if (10 * a == 1.0) //always fails
Check out the use of numeric_limits<double>::epsilon()
Also, consider this basic design for a calculator:
1 2 3 4
// Get a number
//Get an Operator
//Get a number
//calc answer
I would have these things as functions. The GetNumber function should have error checking in it, so that you can fix bad input. The GetOperator function should call a IsOperator function.
If you do it that way you won't need a big menu to select each operation, as a switch can do the right operation based on what the operator is.
consider writing a DegToRadians function, so you don't have to do this everywhere:
(x * PI / 180)
Also RadiansToDeg function.
You also need range checking on some of the trig functions, and log functions.
If you are going to use a do loop, put the while part on the same line as the closing brace, so it doesn't cause all kinds of confusion because it looks like a while loop with a null statement.
Think about using a bool variable to help decide whether to continue the loop.
Well, there's some stuff to think about - Good Luck !! I look forward to helping more.
I recommend swapping this with a float/double constant. Doing so will provide the reader with more information regarding the literal than just a floating-point literal. Also, declaring literal-initialised constants is efficient since the compiler will not allocate memory for the constant. For instance:
1 2
float PI(3.14F); // The compiler will allocate memory for 'PI'
floatconst PI(3.14F); // The compiler will not allocate memory for 'PI'
bakerlandon wrote:
1 2 3
longdouble x;
longdouble y;
int choice;
I strongly recommend avoiding global variables/objects. Either place them inside a namespace, or, declare them local to main().
bakerlandon wrote:
void add()
I recommend passing whatever you want adding as arguments. By implementing add() using global variables, add() becomes dependant on something that may or may not be removed in the future. "Remove the support beams, and the building falls."
I recommend swapping this with a float/double constant
I see what you are saying about memory allocation - Just wondering why the OP can't use M_PI from the math header? Is that not one of the purposes of the math header, to have all kinds of constants defined already, so one doesn't have define them (one way or another) again?
Is the memory allocation going to matter for the OP for the program?
"Just wondering why the OP can't use M_PI from the math header?"
To be perfectly fair, I didn't know that M_PI existed until you said it did. I'm not really interested in the mathematical libraries, so I wouldn't know :)
TheIdeasMan wrote:
"Is the memory allocation going to matter for the OP for the program?"
If I review a piece of code, I'll consider efficiency, readability, portability, et cetera.
cout << " Contents of Element within Array is = " << letters << endl;
}
}
int main()
{
problem1();
cout << endl;
problem2();
cout << endl;
problem3();
cout << endl;
problem4(true);
cout << endl;
return 0;
}
// end program...
The program runs but with strange characters after the letters. Problem3 does not PRINT CONTENTS OF ARRAY and adding x to every other element .
I have changed the for loop to (int i = 1; i < sizeof(letters); ++i)
still no errors but no x is being added to every other element.