Você está na página 1de 33

Defining new data types in C++

Part 1: enums & structs

Enumerated types
An enumeration is a data type in which labels for all possible values of the type can be listed The type declaration consists of the keyword enum followed by the name of the new type and a block of code in which labels for all values of the type are listed Syntax:
enum NewTypeName {value1, value2, , valueN};

Enumeration constants
The value labels listed in an enumeration are called enumeration constants Enumeration constants must be valid C++ identifiers; they are not string or char literals Enumeration constants are stored in memory as integers; by default, the first is assigned the value 0, the second 1, etc. Thus the order of the listing determines the relative magnitude of enumeration constant values; the first is less than the second, which is less than the third, and so forth

Specifying different values in enumerations


By default, the first enumeration constant has the value 0, the second 1, the third 2, etc. The default behavior can be overridden by assigning explicit values to one or more of the constants The next several examples illustrate this option

Example 1 (enum)
The following enumeration uses explicit assignment to specify values for the symbols used in the Roman numeral system:
enum RomanNum { I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000};

Example 2 (enum)
The following enumeration type creates constants that stand for the months of the year:
enum MonthType {JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC};

Only the first constants value is specified; since it is 1, the second is 2, the third is 3, and so on until the last (DEC) with the value 12

Using enumerated types


Enumerations only create new data types; to actually store and use values of the the new types, you must declare variables Variables of each enum type can hold only those values specified by the enumeration For example, with the MonthType enumeration, you could declare variables and assign them values like the following:
MonthType thisMonth = APR; MonthType nextMonth = MAY; MonthType birthMonth = nextMonth;

Operations on enumerations
Since enumerations are not built-in data types, only some of the most common operations can be performed using variables of these types The allowable operations include:
logical comparison using the relational operators (<, >, <=, >=, ==, !=) simple arithmetic (but not arithmetic/assignment operations like ++ or --) enumerations can be parameters to, and/or return values from, functions enumerations can be used as switch expressions and/or case labels in switches example on next slide

MonthType thisMonth; switch ( thisMonth ) // using enum type switch expression { case JAN : case FEB : case MAR : cout << Winter quarter ; break ; case APR : case MAY : case JUN : cout << Spring quarter ; break ; case JUL : case AUG : case SEP : cout << Summer quarter ; break ; case OCT : case NOV : case DEC : cout << Fall quarter ; }

Incrementing enum variables using type cast mechanism


The operators ++ and -- are not available for use with enum-type variables, as previously noted However, enum-type variables can appear in mixed-type expressions with, for example, integers This provides a mechanism for increment/decrement of enumeration type variables

Using enum type Control Variable with for Loop


MonthType month ; for (month = JAN ; month <= DEC ; month = MonthType (month + 1 ) ) { // uses type cast to increment

. . .
}

Simple arithmetic with enumeration constants


Previously, we defined an enumeration of the symbols used in the Roman numeral system We will use this enumeration to illustrate arithmetic with enums, and see another example of type casting

Example
#include <iostream.h> #include <stdlib.h> enum RomanNum {I=1, V=5, X=10, L=50, C=100, M=1000}; int main() { cout << "Welcome to the world of Roman numerals!" << endl; int num = (int)(M + C + L + X + V + I); cout << "MCLXVI=" << num << endl; num = (int)((L-X) + (V-I)); cout << "XLIV=" << num << endl; system("PAUSE"); return 0; }

Enumerated types and I/O


The insertion (<<) and extraction (>>) operators are not defined for enum-type variables To perform input or output operations on user-defined types, you must provide your own functions

Databases
A database is a collection of information organized for ease of storage and retrieval A library catalog is a good example of a database; such a catalog contains information about each book in the librarys collection Although each book is unique, books share common characteristics, such as author, title, publisher, etc. We store information in the database based on these common characteristics

Database components
At the macroscopic level, a database consists of one or more files containing information The information in the files is stored in the form of records; in our example, each record would contain all of the information concerning a specific book Within the records, individual data items are stored in fields; for library books, each record would have separate fields for author, title, publisher, etc. All the records contain the same set of fields; they differ in the actual data stored in the fields

Record structures
If we wanted to create our own library database, we would want to consider how people use books, and what information they might want to look up We could come up with a preliminary list of fields to include, such as:
Author Title Subject(s) Call number (the Dewey Decimal or Library of Congress classification that determines where the book is shelved) ISBN (for those who delight in reading bar codes and many more, but this is enough to start with

Record structures in C++


The C++ mechanism for creating a record data type is the struct A struct consists of a block of code containing list of member variable declarations The member variables represent the fields where data can be stored when variables of the struct type are declared

Syntax for struct declaration


struct StructureName { dataType field1; dataType field2; . . . dataType fieldn; };
StructureName must be a valid identifier Member variable declaration looks the same as any other variable declaration but the struct declaration, including declaration of member variables, doesnt allocate any memory must declare variables of the new type to allocate memory

Example
struct BookRecord { string title; string author; string subject1, subject2, subject3; string callNo; string ISBN; };

Storing information in records


A struct declaration, like the previous example, just provides a blueprint for a record it doesnt allocate memory, so there isnt anyplace to store data To create an actual record, we need to declare a variable of the struct type; example:
BookType myBook, yourBook;

This statement allocates memory for two BookType records; the next step is to assign values to these variables

Assigning data to struct variables


In order to assign data to a struct variable, we must first access the individual member variables We do this by using the member-selection operator, or dot operator This is the same operator we use to call member functions, and for good reason: in both instances, we are accessing a member of a larger structure in order to perform some operation

Example
myBook.title = Seabiscuit; myBook.author = Hillenbrand, Laura; myBook.subject1 = Horse racing; myBook.subject2 = Great Depression 1929-1939, U.S.; myBook.subject3 = Biscuits, Aquatic; myBook.ISBN = 0-345-46508-3; myBook.callNo = 939.41 H42; yourBook.title = Geeks; yourBook.author = Katz, Jon; yourBook.subject1 = Computer technicians U.S. case studies; yourBook.subject2 = Electronic data processing personnel U.S. case studies; yourBook.ISBN = 0-375-50298-X; yourBook.callNo = TK7885.54 K38;

Memory allocation and structs


Memory for struct-type is allocated when a variable is declared Each struct variable contains all of the member variables listed in the struct declaration You can think of a struct variable as a single box with several compartments, each of which can contain a data item

Operations on struct variables


The operations that can be performed on individual member of a struct variable depend on the members data type For example, all of the following statements are valid for a BookType variable:
getline(cin, myBook.title); cout << yourBook.ISBN; myBook.subject1 = Water and its edible by-products;

Aggregate operations
An aggregate operation is an operation performed on an entire struct variable (as opposed to one of its member variables) The following are allowable aggregate operations on struct variables:
assignment to another struct variable of the same type (example: yourBook = myBook;) pass to a function as an argument (either by value or by reference) use as return value from a function

On the other hand, the following aggregate operations are NOT allowed: I/O, arithmetic, logical comparison

Notes on structs as parameters


As previously mentioned, we can pass a struct variable as a value parameter Although this operation is permitted, it is costly:
pass by value requires copying original argument to new memory location struct variables are rather large objects to copy

It is therefore much more common to pass struct variables by reference, because then only a single copy of the large object is held in memory

A third way: const reference parameters


The advantage of pass by value is the guarantee that an arguments value will not be changed by the action of a function Passing by reference could lend itself to side effects Fortunately, there is an alternative that combines the advantages of passing by value and passing by reference: passing by const reference

Using const reference parameters


To pass by const reference, label your parameter with the ampersand (&), as usual, but add the keyword const before the parameters data type For example, suppose you had a function for checking out books that took a BookType variable as its argument; this function could take either a value of const reference parameter:
void checkout (BookType b); // value parameter; must // copy whole object void checkout (BookType &b); // const ref parameter; // uses original memory, // but doesnt change it

Hierarchical structures
A struct can contain an enum type as one of its member variables It is also possible for a struct to contain a member variable of a struct type Such an arrangement makes possible a greater level of detail in each record

Example: struct MachineRec


Information about each machine in a shop contains:
an idNumber, a written description, the purchase date, the cost, and a history (including failure rate, number of days down, and date of last service).
31

struct { int int int };

DateType month ; day ; year ;

// Assume 1 . . 12 // Assume 1 . . 31 // Assume 1900 . . 2050

struct StatisticsType { float failRate ; DateType lastServiced ; int downDays ; };


struct MachineRec { int idNumber ; string description ; StatisticsType history ; DateType purchaseDate ; float cost ; };

// DateType is a struct type

// StatisticsType is a struct type

32

struct type variable machine


7000 5719 DRILLING 3 21 1995 8000.0

.02
.failrate

25 1999

.month .day .year

.lastServiced

.downdays .month .day .year

.idNumber .description . history

.purchaseDate

.cost

machine.history.lastServiced.year has value 1999


33

Você também pode gostar