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

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: 4 stars4 stars4 stars4 stars4 stars / 10
March 02, 2005
  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

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

- 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++

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 

Developer Shed Affiliates


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