views:

309

answers:

5

I do not understand how to use enumeration types. I understand what they are, but I don't quite get their purpose.

I have made a program that inputs three sides of a triangle and outputs whether or not they are isosceles, scalene, or equilateral. I'm suppose to incorporate the enumeration type somewhere, but don't get where and how to use them. Any help would be appreciated.

#include <iostream>

using namespace std;

enum triangleType {scalene, isosceles, equilateral, noTriangle};

triangleType triangleShape(double x, double y, double z);
void printTriangleShape(triangleType shape);

int main()
{
    double x, y, z;
    triangleType scalene, isosceles, equilateral, noTriangle;

    cout << "Please enter the three sides of a triangle:" << endl;
    cout << "Enter side 1: ";
    cin >> x;
    cout << endl;
    cout << "Enter side 2: ";
    cin >> y;
    cout << endl;
    cout << "Enter side 3: ";
    cin >> z;
    cout << endl;

    triangleType t = triangleShape(x, y, z); 
printTriangleShape(t);

    return 0;
}

triangleType triangleShape(double x, double y, double z)
{
   triangleType scalene, isoceles, equilateral, noTriangle;
    if (((x+y) > z) && ((x+z) > y) && ((y+z) > x))
    {
        cout << "You have a triangle!" << endl;
            if (x == y && y == z)
               return equilateral;
            else if (x == y || x == z || y == z)
                 return isosceles;
            else
               return scalene;
    }
    else if ((x+y) <= z || ((x+z) <= y) || ((y+z) <= x))
        return noTriangle;  
} 
void printTriangleShape(triangleType shape)
{
    switch (shape)
    {
    case scalene: cout << "Your triangle is Scalene!" << endl;
        break;
    case isosceles: cout << "Your triangle is an isosceles!" << endl;
        break;
    case equilateral: cout << "Your triangle is an equilateral!" << endl;
        break;

    }
}
+7  A: 

It's a value, and you probably want to return it from your function.

Try:

triangleType triangleShape(double x, double y, double z) {
  if (...) {
    return scalene;
  } else if (...) {
    return isosceles.
  } else if (...) {
    return equilateral
  } else {
    return noTriangle;
  } 
}

Note, you can print the result, but it will print as an integer: scalene = 0, isosceles = 1, ...

Edit, for printing you may want to do this:

void printTriangleShape(triangleType shape) {
   switch (shape) {
     case scalene:
       cout << "Your triangle is Scalene!" << endl;
       break;
     case isosceles:
       cout << "Your triangle is isosceles!" << endl;
       break;
     ...;
   }
}
Stephen
I thought about this way, but wouldn't returning just return values of 0-3? What do I do after returning them as scalene or iso or equilateral?
Sagistic
Yep, pretty much. But to the compiler it's a special identifier for type safety.
Stephen
So, how is it possible to display some sort of message when it returns scalene? I'm suppose to prompt the user the shape of the triangle
Sagistic
see edit. does that answer your question?
Stephen
Thank you Stephen. I guess when I tried to do the same way using cases, I didn't set the parameters correctly.
Sagistic
Ah, I'm not the only one who forgets the `break` at the end of switch cases... ;)
Troubadour
Ooooopsies, thanks Troubadour.
Stephen
@Sagistic an enum is just an integer with a restricted range of values. when the program is compiled the names disapear and are replaced with the numbers - there is no way of getting the name of the enum back.
Martin Beckett
I've edited the code, but now I'm not sure how to implement the returned values of the voidTriangleShape into the cases? Where do you get the switch (shape<---)
Sagistic
You don't return "double" from triangleShape. "double" is a type with values 1,2,3.... You want to return triangleType, which is a type with values scalene,isosceles,equilateral,noTriangle. So you don't need to declare these values inside the function either, just return them.
Stephen
You can simply say "triangleType t = triangleShape(x, y, z); printTriangleShape(t);"
Stephen
@Stephen: Thank you!!!!!
Sagistic
Sorry, last question before I'm done with this. I initialized triangleType scalene, isosceles, equilateral, noTriangle; in the function triangleShape because thats where the return values were, but it didn't work. Why do I declare them in the main?
Sagistic
You don't need to do it at all. They're declared by the "enum triangleType { scalene, ... };" line.
Stephen
A: 

An enumeration can be used to identify 'types' of objects, as you are in your case.

For example, your triangle shape method could return a triangleType and that way you could do all of the cout << "..." in your main method and separate the display logic from the triangle object.

TJB
A: 

The idea is to replace using numbers (1,2,3...) that don't explain their meaning with tags that do have meaning (red, green, blue...). Numbers used in code that only you understand the meaning of are called "magic numbers" and should be avoided since it keeps others from understanding your code.

Peter
A: 

An enum is a new type in c++. Using this type creates additional type safety as you are only allowed to use the values that are defined for that enum. Enum values will get numbered automatically unless you specify a value yourself, which should be rarely needed. An example:

enum Color { Red, Green, Blue }; // Red = 0, Green = 1, Blue = 2
enum Shape { Circle, Square };   // Circle = 0, Square = 1

int printColor(Color c)
{
    // do something with the color here, for example print it.
    switch(c)
    {
        case Red:
            cout << "Red";
            break;
        case Green:
            cout << "Green";
            break;
        case Blue:
            cout << "Blue";
            break;
    }
}

int main(int argc, char* argv[])
{
    printColor(Red); // works
    printColor(0);   // will give an error or warning in C++.
                     // However, C does less type checking and allows this.

    printColor(Circle);
                     // error, the type is wrong even if the values are identical.
}

You get added type safety in the printColor(0) call -- c++ does additional type checking here, so you can't mistakenly put an invalid number in the call. You can of course achieve the same result with using #define for the values or even put them directly, but in that case the compiler won't be able to warn you if you put in invalid values.

bluebrother
+1  A: 

In C enums make debugging easier because often debuggers print the name value rather than a numeric value. They also allow the compiler to enforce places where it can determine that an invalid value is being stored into an enum variable.

In C++ there is also another benifit, which is that you can use enum types in overloads. For instance, you could:

ostream & operator<<(ostream & ostr, triangleType t) {
     string s;
     switch (t) {
          case scalene:
             s = "scalene";
             break;
          case isosceles:
             s = "isosclese";
             break;
          case equilateral:
             s = "equilateral";
             break;
          case noTriangle:
             s = "noTriangle";
             break;
          default:
             s = "error bad triangle type";
             break;
       }
       return cout << s;
}

and then in main do

cout << "Your triangle is" << t << endl;
nategoose
IMHO, a table of [enum, text] would be better than a `switch` statement.
Thomas Matthews
Many compilers are smart enough to make this happen. Plus using an array means that whoever wrote this function would have to know what the integer values of the enum was to populate that array, and it would have to be consistent across all implementations of the triangle code that the printing function used. That being said, it would be probably have been better if I had written a cast to string operator that the output operator used.
nategoose