700 likes | 929 Views
CHAPTER 8 USER-DEFINED SIMPLE DATA TYPES, NAMESPACES, AND THE string TYPE. In this chapter, you will: Learn how to create and manipulate your own simple data type—called the enumeration type Become aware of the typedef statement Learn about the namespace mechanism
E N D
CHAPTER 8USER-DEFINED SIMPLE DATATYPES, NAMESPACES,AND THE string TYPE
In this chapter, you will: • Learn how to create and manipulate your own simple data type—called the enumeration type • Become aware of the typedefstatement • Learn about the namespacemechanism • Explore the string data type, and learn how to use the various string functions to manipulate strings
ENUMERATION TYPE • A data type is a set of values together with a set of operations on those values. • In order to define a new simple data type, called enumerationtype, we need three things: • A name for the data type. • A set of values for the data type. • A set of operations on the values. • C++ allows the user to define a new simple data type by specifying its name and the values, but not the operations. • The values that we specify for the data type must be identifiers.
The syntax for enumeration type is: enum typeName{value1, value2, ...}; where value1, value2, … are identifiers. • value1, value2, … are called enumerators. • value1 < value2 < value3 <... • In C++, enum is a reserved word. • Enumeration type is an ordered set of values.
Example 8-1 enum colors{brown, blue, red, green, yellow}; defines a new data type, called colors • The values belonging to this data type are brown, blue, red, green, and yellow. Example 8-2 enum standing{freshman, sophomore, junior, senior}; defines standing to be an enumeration type. • The values belonging to standing are freshman, sophomore, junior, and senior.
Example8-3 • The following are illegal enumeration types because none of the values is an identifier. //Illegal enumeration types enum grades{'A', 'B', 'C', 'D', 'F'}; enum places{1st, 2nd, 3rd, 4th}; • The following are legal enumeration types: enum grades{A, B, C, D, F}; enum places{first, second, third, fourth};
If a value has already been used in one enumeration type, it cannot be used by any other enumeration type in the same block. • The same rules apply to enumeration types declared outside of any blocks. Example 8-4 enum mathStudent{John, Bill, Cindy, Lisa, Ron}; enum compStudent{Susan, Cathy, John, William}; //Illegal • Suppose that these statements are in the same program in the same block. • The second enumeration type, compStudent, is not allowed because the value John was used in the previous enumeration type mathStudent.
Declaring Variables The syntax for declaring variables is the same as before, that is, dataType identifier, identifier,...; • The following statement defines an enumeration type sports enum sports{basketball, football, hockey, baseball, soccer,volleyball}; • The following statement declares variables of the type sports. sports popularSport, mySport;
Assignment • The statement popularSport = football; stores football in popularSport • The statement mySport = popularSport; copies the content of popularSport in mySport.
Operations on Enumeration Types • No arithmetic operation is allowed on enumeration type. • The following statements are illegal; mySport = popularSport + 2; //illegal popularSport = football + soccer; //illegal popularSport = popularSport * 2; // illegal • Also, the increment and decrement operations are not allowed on enumeration types. • The following statements are illegal; popularSport++; //illegal popularSport--; //illegal
To increment the value of popularSport by 1, we can use the cast operator as follows: popularSport = static_cast<sports>(popularSport + 1); • Consider the following statements: popularSport = football; popularSport = static_cast<sports>(popularSport + 1); • After the second statement, the value of popularSport will be hockey. • The following statements results in storing basketball in popularSport. popularSport = football; popularSport = static_cast<sports>(popularSport - 1);
Relational Operators Suppose we have the enumeration type sports and the variables popularSport and mySport as defined above. Then football <= soccer istrue hockey > basketball istrue baseball < football isfalse If popularSport = soccer; mySport = volleyball; then popularSport < mySport istrue
Enumeration Types and Loops Suppose mySport is a variable as declared above. for(mySport = basketball; mySport <= soccer; mySport = static_cast<sports>(mySport+1)) ... • This for loop executes 5 times.
Input/Output of Enumeration Types • Input and output are defined only for built-in data types such as int, char, double. • The enumeration type can be neither input nor output (directly). • You can input and output enumeration indirectly
Example 8-5 enum courses{algebra, basic, pascal, cpp, philosophy, analysis, chemistry, history}; courses registered; char ch1,ch2; cin>>ch1>>ch2; //read two characters switch(ch1) { case 'a': if(ch2 == 'l') 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; }
Enumeration type can be output indirectly as follows: 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 history: cout<<"history"; break; case pascal: cout<<"pascal"; break; case philosophy: cout<<"philosophy"; }
enum courses{algebra, basic, pascal, cpp, philosophy, analysis, chemistry, history}; courses registered; • If you try to output the value of an enumerator directly, the computer will output the value assigned to the enumerator. • Suppose that registered = algebra; • The following statement outputs the value 0 because the (default) value assigned to algebra is 0: cout<<registered<<endl; • The following statement outputs 4: cout<<philosophy<<endl;
Functions and Enumeration Types • Enumeration type can be passed as parameters to functions either by value or by reference. • A function can return a value of the enumeration type. courses readCourses() { courses registered; char ch1,ch2; cout<<"Enter the first two letters of the course: "<<endl; cin>>ch1>>ch2; switch(ch1) { case 'a': if(ch2 == 'l') 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 readCourses
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 history: cout<<history"; break; case pascal: cout<<"pascal"; break; case philosophy: cout<<"philosophy"; } //end switch } //end printEnum
Declaring Variables When Defining the Enumeration Type enum grades{A,B,C,D,F} courseGrade; enum coins{penny, nickel, dime, halfDollar, dollar} change, usCoins;
Anonymous Data Types • A data type in which values are directly specified in the variable declaration with no type name is called an anonymous type. enum {basketball, football, baseball, hockey} mysport; • Creating an anonymous type has drawbacks. • We cannot pass an anonymous type as a parameter to a function. • A function cannot return a value of an anonymous type. • Values used in one anonymous type can be used in another anonymous type, but variables of those types are treated differently. enum {English, French, Spanish, German, Russian} languages; enum {English, French, Spanish, German, Russian} foreignLanguages; languages = foreignLanguages; //illegal
The typedef Statement • In C++, you can create synonyms or aliases to a previously defined data type by using the typedef statement. • The general syntax of the typedef statement is typedef existingTypeName newTypeName; • In C++, typedef is a reserved word. • The typedef statement does not create any new data type; it creates only an alias to an existing data type.
Example 8-6 • The following statement creates an alias, integer, for the data type int. typedefint integer; • The following statement creates an alias, real, for the data type double. typedefdouble real; • The following statement creates an alias, decimal, for the data type double. typedefdouble decimal;
Example 8-7 typedefint Boolean; //Line 1 const Boolean True = 1; //Line 2 const Boolean False = 0; //Line 3 Boolean flag; //Line 4 • The statement at Line 1 creates an alias, Boolean, for the data type int. • The statements at Lines 2 and 3 declare the named constants True and False and initialize them to 1 and 0, respectively. • The statement at Line 4 declares flag to be a variable of the type Boolean. • Because flag is a variable of the type Boolean, the following statement is legal: flag = True;
In July 1998, ANSI/ISO standard C++ was officially approved. • Most of the recent compilers are also compatible with ANSI/ISO standard C++. • In previous chapters, we mainly dealt with standard C++ and briefly introduced the features of ANSI/ISO standard C++. • For most part the two standards are the same. In this chapter, we discuss some of the features of ANSI/ISO standard C++ language that are not available in standard C++.
Namespaces • When a header file, such as iostream, is included in a program, the global identifiers in the header file also become the global identifiers in the program. • If a global identifier in a program has the same name as one of the global identifiers in the header file, the compiler will generate syntax error (such as identifier redefined). • The same problem can occur if a program uses third party libraries. • To overcome this problem, third party vendors begin their global identifiers with a special symbol. • Since compiler vendors begin their global identifier with _ (under score), to avoid linking errors do not begin identifiers in your program with _ (under score). • ANSI/ISO standard C++ attempts to solve this problem of overlapping global identifier names with the namespace mechanism.
Syntax: namespace The syntax of the statement namespace is: namespace namespace_name { members } where a member is usually a variable declaration, a named constant, a function, or another namespace. • In C++, namespace is a reserved word.
Example 8-8 The statement namespace globalType { constint n = 10; const double rate = 7.50; int count = 0; void printResult(); } defines globalType to be a namespace with four members.
The scope of a namespace member is local to the namespace. • There are usually two ways a namespace member can be accessed outside the namespace. Syntax: Accessing a namespace Member namespace_name::identifier • To access the member rate of the namespaceglobalType, the following statement is required: globalType::rate • To access the member printResult (which is a function), the following statement is required: globalType::printResult();
To simplify the accessing of a namespace member, C++ provides the use of the statement using. Syntax: using (a) To simplify the accessing of all namespace members: using namespace namespace_name; (b) To simplify the accessing of a specific namespace member: using namespace_name::identifier;
The using statement using namespace globalType; simplifies the accessing of all members of the namespace globalType • The statement using globalType::rate; simplifies the accessing of the member rate of the namespaceglobalType. • In C++, using is a reserved word. • The using statement is usually put after the namespace declaration.
namespace globalType { const int n = 10; const double rate = 7.50; int count = 0; void printResult(); } using namespace globalType;
After the using statement, to access a namespace member it is not necessary to precede the namespace_name and the scope resolution operator before the namespace member. • If a namespace member and a global identifier in a program have the same name, to access this namespace member in the program, the namespace_name and the scope resolution operator must precede the namespace member. • If a namespace member and an identifier in a block have the same name, to access this namespace member in the block, the namespace_name and the scope resolution operator precedes the namespace member.
Example 8-9 #include <iostream> using namespace std; . . . int main() { . . . } . . . • In this example, we can refer to global identifiers of the header file iostream, such as cin, cout, and endl, without using the prefix std:: before the identifier name. • The obvious restriction is that the block (or the function) where the global identifier (of the header file iostream) is referred must not contain any identifier with the same name as this global identifier.
Example 8-10 #include <cmath> int main() { double x = 15.3; double y; y = std::pow(x,2); . . . } • In this example the function pow of the header file cmath is accessed
Example 8-11 #include <iostream> . . . int main() { using namespace std; . . . } . . . • In this example, the function main can refer to the global identifiers of the header file iostream without using the prefix std:: before the identifier name. • Since the using statement appears inside the function main, other functions (if any) should use the prefix std:: before the name of the global identifier of the header file iostream unless the function also has a similar using statement.
Example 8-12 #include <iostream> using namespace std; //Line 1 int t; //Line 2 double u; //Line 3 namespace exp { int x; //Line 4 char t; //Line 5 double u; //Line 6 void printResult(); //Line 7 } using namespace exp; int main() { int one; //Line 8 double t; //Line 9 double three; //Line 10 . . . }
void exp::printResult() { . . . } 1. To refer to the variable t at Line 2 in main, use the scope resolution operator (that is, refer to t as ::t) since the function main has a variable named t (declared at Line 5). 2. To refer to the member t (declared at Line 5) of the namespaceexp in main, use the prefix exp:: with t (that is, refer to t as exp::t) since there is a global variable named t (declared at Line 2) and there is also a variable named t in main. 3. To refer to the member u (declared at Line 6) of the namespaceexp in main, use the prefix exp:: with u (that is, refer to u as exp::u) since there is a global variable named u (declared at Line 3).
4. The member x (declared at Line 4) of the namespaceexp can be referenced in main either as x or exp::x since there is no global identifier named x and the function main does not contain any identifier named x. 5. The definition of the function that is a member of a namespace, such as printResult, is usually written outside the namespace as in the above program. To write the definition of the function printResult, in the function heading the name of the function can be either printresult or exp::printResult (because there is no other global identifier named printResult).
The string Type • To use the data type string, the program must include the header file string #include <string> • The statement string name = "William Jacob"; declares name to be string variable and also initializes name to "William Jacob". • The position of the first character, 'W', in name is 0, the position of the second character, 'i', is 1, and so on. • The variable name is capable of storing (just about) any size string.
Binary operator + (to allow the string concatenation operation), and the array index (subscript) operator [], have been defined for the data type string. Suppose we have the following declarations. string str1, str2, str3; The statement str1 = "Hello There"; stores the string "Hello There" in str1. The statement str2 = str1; copies the value of str1 into str2.
If str1 = "Sunny", the statement str2 = str1 + " Day"; stores the string "Sunny Day" into str2. • If str1 = "Hello" and str2 = "There". then str3 = str1 + " " + str2; stores "Hello There" into str3. • This statement is equivalent to the statement str3 = str1 + ' ' + str2;
The statement str1 = str1 + "Mickey"; updates the value of str1 by appending the string "Mickey" to its old value. • If str1 = "Hello there", the statement str1[6] = 'T'; replaces the character t with the character T.
The data type string has a data type, string::size_type, and a named constant, string::npos, associated with it. string::size_type An unsigned integer (data) type string::npos The maximum value of the (data) type string::size_type, a number such as 4294967295 on many machines
The length Function • 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.length() where strVar is variable of the type string. • The function length has no arguments.
Consider the following statements: string firstName; string name; string str; firstName = "Elizabeth"; name = firstName + " Jones"; str = "It is sunny."; Statement Effect cout<<firstName.length()<<endl; Outputs 9 cout<<name.length()<<endl; Outputs 15 cout<<str.length()<<endl; outputs 12
The function length returns an unsigned integer. • The value returned can be stored in an integer variable. • Since the data type string has the data type string::size_type associated with it, the variable to hold the value returned by the length function is usually of this type. string::size_type len; Statement Effect len =firstName.length(); The value of len is 9 len = name.length(); The value of len is 15 len =str.length(); The value of len is 12
The size Function • The function size is same as the function length. • Both these functionsreturn the same value. • The syntax to call the function size is: strVar.size() where strVar is variable of the type string. • As in the case of the function length, the function size has no arguments.