Home arrow C++ arrow Page 9 - More on Handling Basic Data Types
C++

More on Handling Basic Data Types


Have you ever wanted to learn how basic types of C++ variables interact in complex situations? Ivor Horton explains this, and also describes some interesting features of C++. This article is from chapter 3 of Ivor Horton's Beginning ANSC C++ The Complete Language (Apress, 2004; ISBN 1590592271).

Author Info:
By: Apress Publishing
Rating: 3 stars3 stars3 stars3 stars3 stars / 8
March 02, 2005
TABLE OF CONTENTS:
  1. · More on Handling Basic Data Types
  2. · Try It Out: Explicit Casting
  3. · Finding Out About Types
  4. · Try It Out: Finding the Sizes of Data Types
  5. · Using the Bitwise AND
  6. · Using the Bitwise Exclusive OR
  7. · Try It Out: Using the Bitwise Operators
  8. · More on Output Manipulators
  9. · Enumerated Data Types
  10. · Try It Out: Enumerated Data Types
  11. · The Lifetime of a Variable
  12. · Try It Out: The Scope Resolution Operator
  13. · Declaring External Variables

print this article
SEARCH DEVARTICLES

TOOLS YOU CAN USE

advertisement
More on Handling Basic Data Types - Enumerated Data Types
(Page 9 of 13 )

You’ll sometimes be faced with the need for variables that have a limited set of possible values that can be usefully referred to by name—the days of the week, for example, or the months of the year. There’s a specific facility, called an enumeration, in C++ to handle this situation. When you define an enumeration, you’re really creating a new type, so it’s also referred to as an enumerated data type. Let’s create an example using one of the ideas I just mentioned—a variable that can assume values corresponding to days of the week. You can define this as follows:

 enum Weekday { Monday, Tuesday, Wednesday, Thursday,
      Friday, Saturday, Sunday };

This declares an enumerated data type called Weekday, and variables of this type can only have values from the set that appears between the braces, Monday through Sunday. If you try to set a variable of type Weekday to a value that isn’t one of the values specified, it will cause an error. The symbolic names that are listed between the braces are called enumerators.

In fact, each of the names of the days will be automatically defined as representing a fixed integer value. The first name in the list, Monday, will have the value 0, Tuesday will be 1, and so on through to Sunday with the value 6. You can declare today as an instance of the enumeration type Weekday with the statement

Weekday today = Tuesday;

You use the Weekday type just like any of the basic types you’ve seen. This declaration for today also initializes the variable with the value Tuesday. If you output the value of today, the value 1 will be displayed.

By default, the value of each successive enumerator in the declaration of an enumeration is one larger than the value of the previous one, and the values begin at 0. If you would prefer the implicit numbering to start at a different value, a declaration like this one will make the enumerators equivalent to 1 through 7:

enum Weekday { Monday = 1, Tuesday, Wednesday, Thursday,
       Friday, Saturday, Sunday };

The enumerators don’t need to have unique values. You could define Monday and Mon as both having the value 1, for example, with this statement:

enum Weekday { Monday = 1, Mon = 1, Tuesday, Wednesday,
       Thursday, Friday, Saturday, Sunday };

This allows the possibility of using either Mon or Monday as the value for the first day of the week. A variable, yesterday, that you’ve declared as type Weekday could then be set with this statement:

yesterday = Mon;

You can also define the value of an enumerator in terms of a previous enumerator in the list. Throwing everything you’ve seen so far into a single example, you could declare the type Weekday as follows:

enum Weekday { Monday,                   Mon = Monday,
               Tuesday   = Monday + 2,   Tues = Tuesday,
               Wednesday = Tuesday + 2,  Wed = Wednesday,
               Thursday = Wednesday + 2, Thurs = Thursday,
               Friday = Thursday + 2,    Fri = Friday,
               Saturday = Friday + 2,    Sat = Saturday,
               Sunday = Saturday + 2,    Sun = Sunday
            };

Now, variables of type Weekday can have values from Monday to Sunday and from Mon to Sun, and the matching pairs of enumerators correspond to the integer values 0, 2, 4, 6, 8, 10, and 12.

If you’d like, you can assign explicit values to all the enumerators. For example, you could define this enumeration:

enum Punctuation { Comma = ',', Exclamation = '!',
     Question='?' };

Here, you’ve defined the possible values for variables of type Punctuation as the numerical equivalents of the appropriate symbols. If you look in the ASCII table in Appendix A, you’ll see that the symbols are 44, 33, and 63, respectively, in decimal, which demonstrates that the values you assign don’t have to be in ascending order. If you don’t specify all of them explicitly, values will continue to be assigned by incrementing by 1 from the last specified value, as in the second Weekday example.

The values that you specify for enumerators must be compile-time constants— that is, constant expressions that the compiler can evaluate. Such expressions can only include literals, enumerators that have been defined previously, and variables that you’ve declared as const. You can’t use non-const variables, even if you’ve initialized them.

Anonymous Enumerations

By declaring variables at the same time as you define the enumeration, you can omit the enumeration type, provided that you don’t need to declare other variables of this type later on, for example:

enum { Monday, Tuesday, Wednesday, Thursday, Friday,
     Saturday, Sunday } yesterday, today, tomorrow;

Here, you declare three variables that can assume values from Monday to Sunday. Because the enumeration type isn’t specified, you can’t refer to it. You can’t declare other variables for this enumeration at all, because doing so would require you to name the enumeration type, which is simply not possible.

A common use of anonymous enumeration types is as an alternative way of defining integer constants, for example:

enum { feetPerYard = 3, inchesPerFoot = 12, yardsPerMile =
      1760 };

This enumeration contains three enumerators with explicit values assigned. Although you’ve declared no variables of this enumerated data type, you can still use the enumerators in arithmetic expressions. You could write this statement:

std::cout << std::endl << "Feet in 5 miles = " << 5 *
      feetPerYard * yardsPerMile;

The enumerators are converted to type int automatically. It may look as if little (if anything) is to be gained by using an enumeration to define integer constants, but you’ll see when you learn about classes that it provides a very useful way of including a constant within a class. For now, let’s look a little more closely at the conversion of enumerated data types.

Casting Between Integer and Enumeration Types

In addition to the enumerators themselves, you can use a variable of an enumeration type in a mixed arithmetic expression. An enumerated data type will be cast automatically to the appropriate type, but the reverse isn’t true; there’s no automatic conversion from an integer type to an enumeration type. If you’ve declared the variable today to be of type Weekday that you defined previously, you can write

 today = Tuesday;             // Assign an enumerator value
 int day_value = today + 1;   // Calculate with an
      enumerator type

The value of today is Tuesday, which corresponds to 1, so day_value will be set to 2. Although the enumerator Wednesday corresponds to the value 2, the following statement will not compile:

 today = day_value;          // Error – no conversion!

However, you can achieve the objective of this statement by putting in an explicit cast:

 today = static_cast<Weekday>(day_value); // OK

With an explicit cast, the integer value you’re casting must be within the range of the enumerators, or the result is undefined. This doesn’t mean that it must correspond to the value of an enumerator—just that it must be equal to or greater than the lowest enumerator, and less than or equal to the highest enumerator. For example, you could define an enumeration, Height, and declare a variable of that type with this statement:

 enum Height { Bottom, Top = 20 } position;

The enumerator Bottom corresponds to the value 0, and Top corresponds to the value 20. The range is therefore from 0 to 20, so you could assign a value to the variable position with this statement:

 position = static_cast<Height> (10);

The value assigned to position doesn’t correspond to either of the enumerators, but it’s nonetheless a legal value because it falls within the range of the minimum and maximum values of the enumerators. For a variable of the Punctuation type that you saw earlier, you could legally cast any integer from 33 to 63 to that type and store it, although in this instance it’s difficult to see what purpose it would serve.


This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.


blog comments powered by Disqus
C++ ARTICLES

- Intel Threading Building Blocks
- Threading Building Blocks with C++
- Video Memory Programming in Text Mode
- More Tricks to Gain Speed in Programming Con...
- Easy and Efficient Programming for Contests
- Preparing For Programming Contests
- Programming Contests: Why Bother?
- Polymorphism in C++
- Overview of Virtual Functions
- Inheritance in C++
- Extending the Basic Streams in C++
- Using Stringstreams in C++
- Custom Stream Manipulation in C++
- General Stream Manipulation in C++
- Serialize Your Class into Streams in C++

Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 



© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 10 - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials