Charles E. Oyibo
Recall from Ch 2 that a data type is a set of values together with a set of operations on them. We have thus far explore mostly int, bool, char, and double data types. We will now create our own simple data types known as the enumeration type.
To define an enumeration type, we need the following:
C++ allows us to define a new simple data type wherein we specify its name and value, but not the operations. Ostensibly, preventing users from creating their own operations avoids potential system failures.
The values that we specify for the data type must be identifiers.
The syntax for the enumeration type is
enum typeName {value1, value2, ...};
where value1, value2, ... are identifiers called enumerators.
By listing all of the values between the braces, we also specify an ordering between the values. That is, value1 < value2 < value3 < .... Thus, the enumeration type is an ordered set of values. Moreover, the default value assigned to these enumerators starts at 0.
Note that the enumerators value1, value2, ... are not variables.
The statement:
enum colors {brown, blue, red, green, yellow};
defines a new data type, called colors, and the values belonging to this data type are brown, blue, red, green, and yellow.
Similarly, the statement:
enum standing {freshman, sophomore, junior, senior};
defines standing to be an enumeration type. The values belonging to standing are freshman, sophomore, junior, and senior.
The typeNames (color
and standing) are analogous to the data type
names int, double,
and bool. The values (brown,
blue, ... and
freshman, sophomore,
...) are analogous to the range of values (...,
-3, -2, -1,
0, 1, 2,
3, ...) that
comprise integers for the data type int, and the
range of values that comprise decimal numbers for the data type double.
We have only two values for the bool data type:
true or false. (If
we wanted to define a data type like bool, calling
it "logical," we could say:
enum logical {true, false};
Again, both the typeNames and the values are identifiers, and both must meet C++'s requirement's for identifiers. They may consist of letter, digits, and the underscore character (_), and must begin with a letter or underscore. They may not however begin with a digit, and no symbols are permitted to form an identifier.
The following enumeration types are illegal because the typeName and/or values are not properly formed identifiers.
enum %grade {'A', 'B', 'C', 'D', 'F'}; // illegal
enum place {1st, 2nd, 3rd, 4th}; // illegal
Here they are, corrected.
enum grade {A, B, C, D, F};
enum place {first, second, third, fourth};
If a value has already been used in one enumeration type, it may not be used by any other enumeration type in the same block.
Once a data type is defined, we can declare variable of that type. The syntax for declaring variables of an enum type is the same as with the other data types:
dataType identifier, identifier, ...;
The statement
enum sports {basketball, football, hockey, baseball, soccer, volleyball};
defines an enumeration type, called sports. The statement
sports popularSport, mySport;
declares popularSport, and mySport to be variables of the type sports.
Once a variable is declared, we can store values in it.
In the following statements:
sports popularSport, mySport; popularSport = football; mySport = popularSport;
The first statement as we have said, declares popularSport, and mySport to be variables of the type sports. The second statement assigns the value football to popularSport. The third statement assigned the value of popularSport to mySport.
No arithmetic operations are allowed on the enumeration type. Further, the increment and decrement operations are not allowed on enumeration types.
If we would like to increment the value of popularSport by 1, we can use the cast operators as follows:
popularSport = static_cast<sports>(popularSport + 1);
so that during execution, the program advances the value of popularSport to the next value in the list. Since popularSport presently holds the value football, and hockey is the next value on the list, the value of popularSport is replaced by the value hockey.
Because an enumeration is an ordered set of values the relational operators can be used with the enumeration type. Based on our earlier definition, the following statements hold:
football <= soccer is true
hockey > basketball is true
baseball< football is false
Further, suppose that:
popularSport = soccer; mySport = volleyball;
Then,
popularSport < mySport is true
Recall: The enumeration type is an integral type; and, using the cast operator, we can increment, decrement, and compare the values of the enumeration type. Hence, we can use the enumeration type in loops.
Consider a variable of the type sports declared thus:
sports mySport;
We could have the following for loop:
for (mySport = basketball; mySport <= soccer; mySport = static_cast<sports>(mySport + 1))
Because input and output are defined for built-in data types such as int, char, double, etc., the enumeration data type can be neither input not output directly. We can, however, input and output enumeration indirectly.
Consider:
enum courses {algebra, basic, pascal, cpp, philosophy, analysis, chemistry, history};
courses registered;
The first statement defines the enumeration type, courses; the second declares a variable registered of the type courses. We can read (i.e. input) the enumeration type with the help of the char data type. To read the values (algebra, basic, etc) from, say, the keyboard, we read the first two charcters of each value (since some of the values begin with the same character) and then use a selection structure to assign the value to the variable registered. Hence, we need to declare two variable of the type char.
char ch1, ch2; cin >> ch1 >> ch2; //read two characters
The following switch statement assigns the appropriate value to the variable registered:
switch (ch1)
{
case 'a': if (ch2 == 'l') //
'l' as in lion.
registered = algebra;
else
registered = analysis;
break;
case 'b': registered = basic;
break;
case 'c': if (ch2 == 'h')
registered = chemistry;
else
registered = cpp;
break;
case 'h': registered = history;
break;
case 'p': if (ch2 == 'a')
registered = pascal;
else
registered = philosophy;
break;
default: cout << "Illegal input."
<< endl;
} // end switch
If we try to output the value of an enumerator directly, the computer will output the value assigned to the enumerator. Suppose that registered = algebra, for instance; the statement cout << registered << endl; will output the value 0 because the (default) value assigned to algebra is 0. Similarly, cout << philosophy << endl; will output 5.
We can pass the enumeration type as a parameter to functions just like any other simple data type--that is, either by value or reference. Also, like any other simple data type, a function can return a value of the enumeration type. Using this facility, we can use functions to input and output enumeration types.
The following function, based on the one above, inputs data from the keyboard and returns a value of the enumeration type. We assume that the enumeration type courses is defined as before:
courses readCourses()
{
courses registered; // declares a variable "registered"
of the (enumeration) type "courses"
char ch1, ch2;
cout << "Enter the first two letters of the course: " <<
endl;
cin >> ch1 >> ch2;
switch (ch1)
{
case 'a': if (ch2 == 'l') //
'l' as in lion.
registered = algebra;
else
registered = analysis;
break;
case 'b': registered = basic;
break;
case 'c': if (ch2 == 'h')
registered = chemistry;
else
registered = cpp;
break;
case 'h': registered = history;
break;
case 'p': if (ch2 == 'a')
registered = pascal;
else
registered = philosophy;
break;
default: cout << "Illegal input."
<< endl;
} // end switch
return registered;
} // end function readCourses
The following function outputs an enumeration type value:
void printEnum(courses, registered) { switch (registered) { case algebra: cout << "algebra"; break; case analysis: cout << "analysis"; break; case basic: cout << "basic"; break; case chemistry: cout << "chemistry"; break; case cpp: cout << "cpp"; break; case pascal: cout << "pascal"; break; case philosophy: cout << "philosophy"; break; default: cout << "Illegal input." << endl; } // end switch } // end function printEmun
C++ allows us to declare variables of the enumeration type when we define an enumeration type. For example, the statement,
enum grades {A, B, C, D, E, F} courseGrade;
defines an enumeration type grade, and declares a variable courseGrade of the type grade. The same explanation applies to the statement,
enum coins {penny, nickel, dime, halfDollar, dollar} change, usCoins;
An (enumeration) data type wherein we directly specify values in the variable declaration with no type name is called an anonymous type. The following statement creates an anonymous type:
enum {basketball, football, baseball, hockey} mySport;
...
Even though this facilities (Declaring Variables When Defining the Enumeration Type and Anonymous Data Types) are available, we are cautioned to use them with care. To avoid confusion, we should first define an enumeration type (with a type name) and then declare the variables.
...
...
The data type string is a programmer-defined type and is not part of the C++ language; the C++ standard library supplies it. Before using the data type string, the program must include the header file string, as follows:
#include <string>
Recall that, in C++, a string is a sequence of zero or more characters, and strings are enclosed in double quotation marks.
The statement:
string name = "Craig Martin";
declares name to be a string variable and initializes name to "Craig Martin". The position of the first character, C, is 0; the position of the second character, r, is 1; and so on.
The variable name can store about any size string.
See Ch3 and Ch4 for a discussion of I/O operations on the string type and relational operations on the string type, respectively.
Suppose we have the following definitions:
string str1, str2, str3;
The statement
str1 = "Hello there";
stores the string "Hello There" in str1. The statement
str2 = str1 + " Jerry";
stores the string "Hello there Jerry" to str2. (It appends the string " Jerry" to str1 and stores it in str2).
For the operator + to work with the string data type, one of the operands of + must be a string variable. The following, for example, are illegal.
str1 = "Hello " + "there"; //illegal str2 = "Sunny Day" + "!"; //illegal
If str1 = "Hello there", the statement
str1[6] = 'T'
replaces the character t with the character T.
In C++, [] is called the array subscript operator. Using the array subscript operator together with the position of the character, we can assess an individual character within a string.
The length function returns the number of characters currently in the string. The value returned is an unsigned integer. The syntax to call the length function is:
strVar.lenght()
where strVar is a variable of the type string. The length function as no arguments (thought we must still include the empty parenthesis). Furthermore, because length is a value returning function, the function call must appear in an expression, as in (assuming all data types are properly defined, and all variables declared):
cout << firstName.length() << endl; cout << name.length() << endl;
The size function is exactly the same function as the length function. The syntax:
strVar.size()
The find function searches a string to find the occurrence of a particular substring and returns an unsigned integer value (of the type string::size_type), giving the result of the search. The syntax to call the function find is:
strVar.find(strExp)
or
strVar.find(strExp, pos)
where strVar is a string variable and strExp is a string expression evaluating to a string. The string expressions, strExp, can also be a character. If the search is successful, the function find returns the position in strVar where the match begins. If the search is unsuccessful, the function returns the special value string::npos ("not a position within the string"). In the second form of the function find, pos specifies the position in the string where to begin the search.
The substr function returns a particular substring of a string. The syntax to call the function substr is:
strVar.substr(expr1, expr2)
where expr1 and expr2 are expressions evaluating to unsigned integers. The expression expr1 specifies a position within the string (the starting position of the substring); the expression expr2 specifies the length of the substring to be returned.
The swap function is used to swap--i.e. interchange--the contents of two string variables. The syntax to use the swap function is:
strVar1.swap(strVar2);
where strVar1 and strVar2 are string variables.
Additional string functions such as empty, clear, erase, insert, and replace, are provided in Appendix E of Malik.
Page Last Updated: Saturday February 12, 2005 10:21 AM