Chapter 1—Introduction to Computers and C++
Programming—discusses what computers are, how they work and how
they are programmed. It introduces the notion of structured programming
and explains why these techniques have fostered a revolution in the way
programs are written. The chapter gives a brief history of the
development of programming languages from machine languages, to
assembly languages, to high-level languages. The origin of the C++
programming language is discussed. The chapter introduces a typical C++
programming environment and gives a concise introduction to writing C++
programs. A detailed treatment of decision making and arithmetic
operations in C++ is presented. We have introduced a new, more open,
easier to read "look and feel" for our C++ source programs, most
notably using syntax coloring to highlight keywords, comments and
regular program text and to make programs more readable. We have also
introduced a new background highlight to focus readers’ attention on
the new features presented in each program. After studying this
chapter, the student will understand how to write simple, but complete,
C++ programs. We discuss the explosion of interest in the Internet that
has occurred with the advent of the World Wide Web. We discuss
namespaces and the using statements. Readers
plunge right into object-orientation in the "Thinking About Objects"
section that introduces the basic terminology of object technology.
Chapter 2—Control Structures—introduces
the notion of algorithms (procedures) for solving problems. It explains
the importance of using control structures effectively in producing
programs that are understandable, debuggable, maintainable and more
likely to work properly on the first try. It introduces the sequence
structure, selection structures (if, if/else and switch) and repetition structures (while,
do/while
and for). It examines repetition in detail
and compares counter-controlled loops and sentinel-controlled loops. It
explains the technique of top-down, stepwise refinement that is
critical to the production of properly structured programs and presents
the popular program design aid, pseudocode. The methods and approaches
used in Chapter are applicable to effective use of control
structures in any programming language (not just C++). This chapter
helps the student develop good programming habits in preparation for
dealing with the more substantial programming tasks in the remainder of
the text. The chapter concludes with a discussion of logical operators—&& (and), || (or)
and ! (not). We introduce the static_cast operator, which is safer than using the
old-style casting C++ inherited from C. We added the "Peter Minuit"
exercise, so students can see the wonders of compound interest—with the
computer doing most of the work! We discuss the scoping rules for loop
counters in for-loops. In the optional
"Thinking About Objects" section, we begin the first phase of an
object-oriented design (OOD) for the elevator simulator—identifying the
classes needed to implement the simulator. We also introduce the UML
use case, class and object diagrams and discuss the concepts of
associations, multiplicity, composition, roles and links.
Chapter 3—Functions—discusses the
design and construction of program modules. C++’s function-related
capabilities include standard-library functions, programmer-defined
functions, recursion, call-by-value and call-by-reference capabilities.
The techniques presented in Chapter are essential to the
production of properly structured programs, especially the kinds of
larger programs and software that system programmers and application
programmers are likely to develop in real-world applications. The
"divide and conquer" strategy is presented as an effective means for
solving complex problems by dividing them into simpler interacting
components. Students enjoy the treatment of random numbers and
simulation, and they appreciate the discussion of the dice game of
craps, which makes elegant use of control structures. The chapter
offers a solid introduction to recursion and includes a table
summarizing the dozens of recursion examples and exercises distributed
throughout the remainder of the book. Some texts leave recursion for a
chapter late in the book; we feel this topic is best covered gradually
throughout the text. The extensive collection of 60 exercises at the
end of the chapter includes several classic recursion problems such as
the Towers of Hanoi. The chapter discusses the so-called "C++
enhancements to C," including inline
functions, reference parameters, default arguments, the unary scope
resolution operator, function overloading and function templates. The
header files table introduces many of the header files that the reader
will use throughout the book. In the optional "Thinking About Objects"
section, we determine many of the class attributes needed to implement
the elevator simulator. We also introduce the UML statechart and
activity diagrams and the concepts of events and actions as they relate
to these diagrams.
Chapter 4—Arrays—discusses the
structuring of data into arrays, or groups, of related data items of
the same type. The chapter presents numerous examples of both
single-subscripted arrays and double-subscripted arrays. It is widely
recognized that structuring data properly is just as important as using
control structures effectively in the development of properly
structured programs. Examples in the chapter investigate various common
array manipulations, printing histograms, sorting data, passing arrays
to functions and an introduction to the field of survey data analysis
(with simple statistics). A feature of this chapter is the discussion
of elementary sorting and searching techniques and the presentation of
binary searching as a dramatic improvement over linear searching. The
121 end-of-chapter exercises include a variety of interesting and
challenging problems, such as improved sorting techniques, the design
of a simple airline-reservations system, an introduction to the concept
of turtle graphics (made famous in the LOGO language) and the Knight’s
Tour and Eight Queens problems that introduce the notion of heuristic
programming so widely employed in the field of artificial intelligence.
The exercises conclude with many recursion problems including the
selection sort, palindromes, linear search, binary search, the Eight
Queens, printing an array, printing a string backwards and finding the
minimum value in an array. This chapter still uses C-style arrays,
which, as you will see in Chapter , are really pointers to the
array contents in memory. In the "Thinking About Objects" section of
Chapter , we determine many of the operations (behaviors) of the
classes in the elevator simulation. We also introduce the UML sequence
diagram and the concept of messages that objects can send to each other.
Chapter 5—Pointers and Strings—presents
one of the most powerful and difficult-to-master features of the C++
language—pointers. The chapter provides detailed explanations of
pointer operators, call by reference, pointer expressions, pointer
arithmetic, the relationship between pointers and arrays, arrays of
pointers and pointers to functions. There is an intimate relationship
between pointers, arrays and strings in C++, so we introduce basic
string-manipulation concepts and discuss of some of the most popular
string-handling functions, such as getline
(input a line of text), strcpy and strncpy (copy a string), strcat
and strncat (concatenate two strings), strcmp and strncmp
(compare two strings), strtok ("tokenize" a
string into its pieces) and strlen (compute
the length of a string). The 134 chapter exercises include a simulation
of the classic race between the tortoise and the hare, card-shuffling
and dealing algorithms, recursive quicksort and recursive maze
traversals. A special section entitled "Building Your Own Computer"
also is included. This section explains machine-language programming
and proceeds with a project involving the design and implementation of
a computer simulator that allows the reader to write and run
machine-language programs. This unique feature of the text will be
especially useful to the reader who wants to understand how computers
really work. Our students enjoy this project and often implement
substantial enhancements, many of which are suggested in the exercises.
In Chapter , another special section guides the reader through
building a compiler; the machine language produced by the compiler then
is executed on the machine language simulator produced in the
Chapter exercises. Information is communicated from the compiler
to the simulator in sequential files, which we discuss in Chapter
. A second special section includes challenging string-manipulation
exercises related to text analysis, word processing, printing dates in
various formats, check protection, writing the word equivalent of a
check amount, Morse Code and metric-to-English conversions. The reader
will want to revisit these string-manipulation exercises after studying
class string in Chapter . Many people
find that the topic of pointers is, by far, the most difficult part of
an introductory programming course. In C and "raw C++" arrays and
strings are pointers to array and string contents in memory (even
function names are pointers). Studying this chapter carefully should
reward you with a deep understanding of the complex topic of pointers.
Again, we cover arrays and strings as full-fledged objects later in the
book. In Chapter , we use operator overloading to craft
customized Array and String
classes. Chapter also introduces Standard Library classes string and vector for
manipulating strings and arrays as objects. These classes are explained
in detail in Chapter and Chapter , respectively.
Chapter is loaded with challenging exercises. Please be sure to
try the Special Section: Building Your Own Computer. In the
"Thinking About Objects" section, we determine many of the
collaborations (interactions among objects in the system) needed to
implement the elevator system and represent these collaborations using
the UML collaboration diagram. We also include a bibliography and a
list of Internet and World Wide Web resources that contain the UML
specifications and other reference materials, general resources,
tutorials, FAQs, articles, whitepapers and software.
Chapter 6—Classes and Data Abstraction—begins
our discussion of object-based programming. The chapter represents a
wonderful opportunity for teaching data abstraction the "right
way"—through a language (C++) expressly devoted to implementing
abstract data types (ADTs). In recent years, data abstraction has
become a major topic in introductory computing courses. Chapter
–Chapter include a solid treatment of data abstraction.
Chapter discusses implementing ADTs as C++-style classes and why this approach is superior to using structs, accessing class
members, separating interface from implementation, using access
functions and utility functions, initializing objects with
constructors, destroying objects with destructors, assignment by
default memberwise copy and software reusability. The chapter exercises
challenge the student to develop classes for complex numbers, rational
numbers, times, dates, rectangles, huge integers and playing
tic-tac-toe. Students generally enjoy game-playing programs.
Mathematically inclined readers will enjoy the exercises on creating
class Complex (for complex numbers), class Rational (for rational numbers) and class HugeInteger (for arbitrarily large integers). The
"Thinking About Objects" section asks you to write a class header file
for each of the classes in your elevator simulator. In the "Thinking
About Objects" section, we use the UML class diagram developed in
previous sections to outline the C++ header files that define our
classes. We also introduce the concept of handles to objects, and we
begin to study how to implement handles in C++.
Chapter 7—Classes Part II—continues the
study of classes and data abstraction. The chapter discusses declaring
and using constant objects, constant member functions, composition—the
process of building classes that have objects of other classes as
members, friend functions and friend classes that have special access rights to
the private and protected
members of classes, the this pointer, which
enables an object to know its own address, dynamic memory allocation, static class members for containing and
manipulating class-wide data, examples of popular abstract data types
(arrays, strings and queues), container classes and iterators. The
chapter exercises ask the student to develop a savings-account class
and a class for holding sets of integers. In our discussion of const objects, we briefly mention keyword mutable which, as we will see in Chapter ,
is used in a subtle manner to enable modification of "non-visible"
implementation in const objects. We discuss
dynamic memory allocation using new and delete. When new fails,
the program terminates by default because new
"throws an exception" in standard C++. Chapter discusses catching
and handling exceptions. We motivate the discussion of static class members with a video-game-based
example. We emphasize how important it is to hide implementation
details from clients of a class; then, we show private
data in our class headers, which certainly reveals implementation. We
discuss proxy classes, which provide a means of hiding implementation
from clients of a class. The "Thinking About Objects" section asks you
to incorporate dynamic memory management and composition into your
elevator simulator. Students will enjoy the exercise creating class IntegerSet. This motivates the treatment of
operator overloading in Chapter . In the "Thinking About Objects"
section, we present a complete elevator simulator C++ program
(approximately 1,250 lines of code) and a detailed code walkthrough.
The code follows directly from the UML-based design created in previous
sections and employs our good programming practices, including the
proper use of static and const data members and functions. We also
discuss dynamic-memory allocation, composition and object interaction
via handles, and how to use forward declarations to avoid the
"circular-include" problem.
Chapter 8—Operator Overloading; String
and Array Objects—presents one of the most popular topics in our
C++ courses. Students really enjoy this material. They find it a
perfect match with the discussion of abstract data types in
Chapter and Chapter . Operator overloading enables the
programmer to tell the compiler how to use existing operators with
objects of new types. C++ already knows how to use these operators with
objects of built-in types, such as integers, floats and characters. But
suppose that we create a new string
class—what would the plus sign mean when used between string objects?
Many programmers use plus with strings to mean concatenation. In
Chapter , the programmer will learn how to "overload" the plus
sign, so when it is written between two string objects in an
expression, the compiler will generate a function call to an "operator
function" that will concatenate the two strings. The chapter discusses
the fundamentals of operator overloading, restrictions in operator
overloading, overloading with class member functions vs. with nonmember
functions, overloading unary and binary operators and converting
between types. A feature of the chapter is the collection of
substantial case studies including an array class, a string class, a
date class, a huge integer class and a complex numbers class (the last
two appear with full source code in the exercises). Mathematically
inclined students will enjoy creating the polynomial
class in the exercises. This material is different from what you do in
most programming languages and courses. Operator overloading is a
complex topic, but an enriching one. Using operator overloading wisely
helps you add that extra "polish" to your classes. The discussions of
class Array and class String
are particularly valuable to students who will go on to use the
standard library classes string and vector, which are introduced with test programs
that use string and vector
to mimic the capabilities shown in the String
and Array examples. Introducing string and vector here
gives students valuable experience with software reuse by using
existing classes, rather than "reinventing the wheel." With the
techniques of Chapter –Chapter , it is possible to craft a Date class that, if we had been using it for the
last two decades, could easily have eliminated a major portion of the
so-called "Year 2000 (or Y2K) Problem." The exercises encourage the
student to add operator overloading to classes Complex,
Rational and HugeInteger
to enable convenient manipulation of objects of these classes with
operator symbols—as in mathematics—rather than with function calls as
the student did in the Chapter exercises.
Chapter 9—Object-Oriented Programming:
Inheritance—introduces one of the most fundamental capabilities of
object-oriented programming languages. Inheritance is a form of
software reusability in which programmers create classes that absorb an
existing class’s data and behaviors and enhance them with new
capabilities. The chapter discusses the notions of base classes and
derived classes, protected members, public inheritance, protected
inheritance, private inheritance, direct base
classes, indirect base classes, constructors and destructors in base
classes and derived classes, and software engineering with inheritance.
The chapter compares inheritance ("is a" relationships) with
composition ("has a" relationships) and introduces "uses-a" and
"knows-a" relationships. A feature of the chapter is the example that
implements a point, circle, cylinder class hierarchy. Using this
"mechanical" example, we examine the relationship between base classes
and derived classes, then show how derived classes use inherited data
members and member functions. In the "Thinking About Objects" section,
we update the elevator simulation design and implementation to
incorporate inheritance. We also suggest further modifications that the
student may design and implement.
Chapter 10—Object-Oriented Programming:
Polymorphism—deals with another fundamental capability of
object-oriented programming, namely polymorphic behavior. When many
classes are related to a common base class through inheritance, each
derived-class object may be treated as a base-class object. This
enables programs to be written in a general manner independent of the
specific types of the derived-class objects. New kinds of objects can
be handled by the same program, thus making systems more extensible.
Polymorphism enables programs to eliminate complex
switch logic in favor of simpler "straight-line" logic. A screen
manager of a video game, for example, can send a draw message to every
object in a linked list of objects to be drawn. Each object knows how
to draw itself. An object of a new class can be added to the program
without modifying that program (as long as that new object also knows
how to draw itself). This style of programming is typically used to
implement today’s popular graphical user interfaces (GUIs). The chapter
discusses the mechanics of achieving polymorphic behavior via virtual functions. It distinguishes between
abstract classes (from which objects cannot be instantiated) and
concrete classes (from which objects can be instantiated). Abstract
classes are useful for providing an inheritable interface to classes
throughout the hierarchy. We demonstrate abstract classes and
polymorphic behavior by revisiting the point, circle, cylinder
hierarchy of Chapter . We introduce an abstract Shape
base class, from which class Point inherits
directly and classes Circle and Cylinder inherit indirectly. In response to this
hierarchy, our professional audiences insisted that we provide a deeper
explanation that shows precisely how polymorphism is implemented in
C++, and hence, precisely what execution time and memory "costs" are
incurred when programming with this powerful capability. We responded
by developing an illustration and a precision explanation of the vtables
(virtual function tables) that the C++
compiler builds automatically to support polymorphism. To conclude
Chapter , we introduce run-time type information (RTTI) and
dynamic casting, which enable a program to determine an object’s type
at execution time, then act on that object accordingly. We show this in
the context of a more "natural" inheritance hierarchy—several classes
derived from an abstract Employee base class,
in which each employee has a common earnings
function to calculate an employee’s weekly pay. Using RTTI and dynamic
casting, we give a 10% pay increase to employees of a specific type,
then calculate the earnings for such employees. For all other employee
types, we calculate their earnings.
Chapter 11—Templates—discusses one of
the more recent additions to C++. Function templates were introduced in
Chapter . Chapter presents an additional function template
example. Class templates enable the programmer to capture the essence
of an abstract data type (such as a stack, an array, or a queue) and
create—with minimal additional code—versions of that ADT for particular
types (such as a queue of int, a queue of float, a queue of strings, etc.) and to provide
specific type information as a parameter when creating an instance of
that ADT. For this reason, class templates often are called
parameterized types. The chapter discusses using type parameters and
nontype parameters and considers the interaction among templates and
other C++ concepts, such as inheritance, friends
and static members. The exercises challenge
the student to write a variety of function templates and class
templates and to employ these in complete programs. We greatly enhance
the treatment of templates in our discussion of the Standard Template
Library (STL) containers, iterators and algorithms in Chapter .
Chapter 12 —C++ Stream Input/Output—contains
a comprehensive treatment of standard C++ object-oriented input/output.
The chapter discusses the various I/O capabilities of C++, including
output with the stream insertion operator, input with
the stream-extraction operator, type-safe I/O, formatted I/O,
unformatted I/O (for performance), stream manipulators for controlling
the numeric base (decimal, octal, or hexadecimal),
floating-point-number formatting, controlling field widths,
user-defined manipulators, stream format states, stream error states,
I/O of objects of user-defined types and tying output streams to input
streams (to ensure that prompts appear before the user is expected to
enter responses).
Chapter 13—Exception Handling—discusses
how exception handling enables programmers to write programs that are
robust, fault tolerant and appropriate for business-critical and
mission-critical environments. The chapter discusses when exception
handling is appropriate; introduces the basic capabilities of exception
handling with try blocks, throw statements and catch
blocks; indicates how and when to rethrow an exception; explains how to
write an exception specification and process unexpected exceptions; and
discusses the important ties between exceptions and constructors,
destructors and inheritance. The exercises in this chapter show the
student the diversity and power of C++’s exception-handling
capabilities. We discuss rethrowing an exception, and we illustrate
both ways new can fail when memory
is exhausted. Prior to the C++ draft standard, new
failed by returning 0, much as malloc fails in C by returning a NULL
pointer value.We show the new style of new
failing by throwing a bad_alloc (bad
allocation) exception. We illustrate how to use set_new_handler
to specify a custom function to be called to deal with
memory-exhaustion situations. We discuss how to use the auto_ptr class template to delete
dynamically allocated memory implicitly, thus avoiding memory leaks. To
conclude this chapter, we present the standard library exception
hierarchy.
Chapter 14—File Processing—discusses
techniques for processing text files with sequential access and random
access. The chapter begins with an introduction to the data hierarchy
from bits, to bytes, to fields, to records and to files. Next, we
present the C++ view of files and streams. We discuss sequential-access
files and build programs that show how to open and close files, how to
store data sequentially in a file and how to read data sequentially
from a file. We then discuss random-access files and build programs
that show how to create a file for random access, how to read and write
data to a file with random access and how to read data sequentially
from a randomly accessed file. The fourth random-access program
combines the techniques of accessing files both sequentially and
randomly into a complete transaction-processing program. Students in
our industry seminars have mentioned that, after studying the material
on file processing, they were able to produce substantial
file-processing programs that were immediately useful in their
organizations. The exercises ask the student to implement a variety of
programs that build and process both sequential-access files and
random-access files.
Chapter 15—Class string
and String Stream Processing—The chapter also discusses C++’s
capabilities for inputting data from strings in memory and outputting
data to strings in memory; these capabilities often are referred to as
in-core formatting or string-stream processing. Class string
is a required component of the standard library. We preserved the
treatment of C-like strings in Chapter and later for several
reasons. First, it strengthens the reader’s understanding of pointers.
Second, for the next decade or so, C++ programmers will need to be able
to read and modify the enormous amounts of C legacy code that has
accumulated over the last quarter of a century—this code processes
strings as pointers, as does a large portion of the C++ code that has
been written in industry over the last many years. In Chapter we
discuss string assignment, concatenation and
comparison. We show how to determine various string
characteristics such as a string’s size,
capacity and whether or not it is empty. We discuss how to resize a string. We consider the various find
functions that enable us to find a substring in a string
(searching the string either forwards or
backwards), and we show how to find either the first occurrence or last
occurrence of a character selected from a string
of characters, and how to find the first occurrence or last occurrence
of a character that is not in a selected string
of characters. We show how to replace, erase and insert characters in a
string. We show how to convert a string object to a C-style char
* string.
Chapter 16—Web Programming with CGI—This
new chapter has everything you need to begin developing your own
Web-based applications that will really run on the Internet! You will
learn how to build so-called n-tier applications, in which the
functionality provided by each tier can be distributed to separate
computers across the Internet or executed on the same computer. In
particular, we build a three-tier online bookstore application. The
bookstore's information is stored in the application's bottom tier,
also called the data tier. In industrial-strength applications, the
data tier is typically a database such as Oracle, Microsoft®
SQL Server or MySQL. For simplicity, we use text files and employ the
file-processing techniques of Chapter 14 to access these files. The
user enters requests and receives responses at the application's top
tier, also called the user-interface tier or the client tier, which is
typically a computer running a popular Web browser such as Microsoft
Internet Explorer or Netscape®. Web browsers, of course,
know how to communicate with Web sites throughout the Internet. The
middle tier, also called the business-logic tier, contains both a Web
server and an application specific C++ program (e.g., our bookstore
application). The Web server communicates with the C++ program (and
vice versa) via the CGI (Common Gateway Interface) protocol. This
program is referred to as a CGI script. We use the popular Apache Web
server, which is available free for download from the Apache Web site, www.apache.org.
Apache Installation instructions for many popular platforms, including
Linux and Windows systems, are available at that site and at www.deitel.com
and www.prenhall.com/deitel.
The Web server knows how to talk to the client tier across the Internet
using a protocol called HTTP (Hypertext Transfer Protocol). We discuss
the two most popular HTTP methods for sending data to a Web server—GET and POST. We then
discuss the crucial role of the Web server in Web programming and
provide a simple example that requests an Extensible HyperText Markup
Language (XHTML) document from a Web server. We discuss CGI and how it
allows a Web server to communicate with the top tier and CGI
applications. We provide a simple example that gets the server’s time
and renders it in a browser. Other examples demonstrate how to process
form-based user input via the string processing techniques introduced
in Chapter 15. In our forms-based examples we use buttons, password
fields, check boxes and text fields. We present an example of an
interactive portal for a travel company that displays airfares to
various cities. Travel-club members can log in and view discounted
airfares. We also discuss various methods of storing client-specific
data, which include hidden fields (i.e., information stored in a Web
page but not rendered by the Web browser) and cookies—small text files
that the browser stores on the client’s machine. The chapter examples
conclude with a case study of an online book store that allows users to
add books to a shopping cart. This case study contains several CGI
scripts that interact to form a complete application. The online book
store is password protected, so users first must log in to gain access.
The chapter’s Web resources include information about the CGI
specification, C++ CGI libraries and Web sites related to the Apache
Web server.
Chapter 17—Data Structures—discusses the
techniques used to create and manipulate dynamic data structures. The
chapter begins with discussions of self-referential classes and dynamic
memory allocation, then proceeds with a discussion of how to create and
maintain various dynamic data structures, including linked lists,
queues (or waiting lines), stacks and trees. For each type of data
structure, we present complete, working programs and show sample
outputs. The chapter also helps the student master pointers. The
chapter includes abundant examples that use indirection and double
indirection—particularly difficult concepts. One problem when working
with pointers is that students have trouble visualizing the data
structures and how their nodes are linked together. We have included
illustrations that show the links and the sequence in which they are
created. The binary-tree example is a superb capstone for the study of
pointers and dynamic data structures. This example creates a binary
tree, enforces duplicate elimination and introduces recursive preorder,
inorder and postorder tree traversals. Students have a genuine sense of
accomplishment when they study and implement this example. They
particularly appreciate seeing that the inorder traversal prints the
node values in sorted order. We include a substantial collection of
exercises. A highlight of the exercises is the special section
"Building Your Own Compiler." The exercises walk the student through
the development of an infix-to-postfix-conversion program and a
postfix-expression-evaluation program. We then modify the
postfix-evaluation algorithm to generate machine-language code. The
compiler places this code in a file (using the techniques of
Chapter ). Students then run the machine language produced by
their compilers on the software simulators they built in the exercises
of Chapter . The 47 exercises include recursively searching a
list, recursively printing a list backwards, binary-tree node deletion,
level-order traversal of a binary tree, printing trees, writing a
portion of an optimizing compiler, writing an interpreter,
inserting/deleting anywhere in a linked list, implementing lists and
queues without tail pointers, analyzing the performance of binary-tree
searching and sorting, implementing an indexed-list class and a
supermarket simulation that uses queueing. After studying Chapter
, the reader is prepared for the treatment of STL containers, iterators
and algorithms in Chapter . The STL containers are pre-packaged,
templatized data structures that most programmers will find sufficient
for the vast majority of applications they will need to implement. STL
is a giant leap forward in achieving the vision of reuse.
Chapter 18—Bits, Characters, Strings and Structures—presents
a variety of important features. C++’s powerful bit-manipulation
capabilities enable programmers to write programs that exercise
lower-level hardware capabilities. This helps programs process bit
strings, set individual bits and store information more compactly. Such
capabilities, often found only in low-level assembly languages, are
valued by programmers writing system software, such as operating
systems and networking software. As you recall, we introduced C-style char * string
manipulation in Chapter and presented the most popular
string-manipulation functions. In Chapter , we continue our
presentation of characters and C-style char * strings. We present the various
character-manipulation capabilities of the <cctype>
library—these include the ability to test a character to determine
whether it is a digit, an alphabetic character, an alphanumeric
character, a hexadecimal digit, a lowercase letter or an uppercase
letter. We present the remaining string-manipulation functions of
the various string-related libraries; as always, every function is
presented in the context of a complete, working C++ program. Structures
in C++ are like records in other languages— they aggregate data items
of various types. A feature of the chapter is its high-performance
card-shuffling and dealing simulation. This is an excellent opportunity
for the instructor to emphasize the quality of algorithms. The 91
exercises encourage the student to try out most of the capabilities
discussed in the chapter. The feature exercise leads the student
through the development of a spelling-checker program. Chapter
–Chapter and Chapter –Chapter are mostly the "C
legacy" portion of C++. In particular, this chapter presents a deeper
treatment of C-like, char *
strings for the benefit of C++ programmers who are likely to work with
C legacy code. Again, Chapter discusses class string
and discusses manipulating strings as full-fledged objects.
Chapter 19—Preprocessor—provides detailed
discussions of the preprocessor directives. The chapter includes more
complete information on the #include
directive, which causes a copy of a specified file to be included in
place of the directive before the file is compiled and the #define directive that creates symbolic constants
and macros. The chapter explains conditional compilation for enabling
the programmer to control the execution of preprocessor directives and
the compilation of program code. The #
operator that converts its operand to a string and the ## operator that concatenates two tokens
are discussed. The various predefined preprocessor symbolic constants (__LINE__, __FILE__, __DATE__, __STDC__, __TIME__ and __TIMESTAMP__)
are presented. Finally, macro assert of the
header file <cassert> is discussed,
which is valuable in program testing, debugging, verification and
validation.
Chapter 20—C Legacy-Code Topics—presents
additional topics including several advanced topics not ordinarily
covered in introductory courses. We show how to redirect program input
to come from a file, redirect program output to be placed in a file,
redirect the output of one program to be the input of another program
(piping) and append the output of a program to an existing file. We
develop functions that use variable-length argument lists and show how
to pass command-line arguments to function main
and use them in a program. We discuss how to compile programs whose
components are spread across multiple files, register functions with atexit to be executed at program termination and
terminate program execution with function exit.
We also discuss the const and volatile type qualifiers, specifying the type of a
numeric constant using the integer and floating-point suffixes, using
the signal-handling library to trap unexpected events, creating and
using dynamic arrays with calloc and realloc, using unions as
a space-saving technique and using linkage specifications when C++
programs are to be linked with legacy C code. As the title suggests,
this chapter is intended primarily for C++ programmers who will be
working with C legacy code.
Chapter 21—Standard Template Library (STL)—Throughout
this book, we discuss the importance of software reuse. Recognizing
that many data structures and algorithms commonly were used by C++
programmers, the C++ standard committee added the Standard Template
Library (STL) to the C++ Standard Library. The STL defines powerful,
template-based, reusable components that implement many common data
structures and algorithms used to process those data structures. The
STL offers proof of concept for generic programming with
templates—introduced in Chapter and demonstrated in detail in
Chapter . This chapter introduces the STL and discusses its three
key components— containers (popular templatized data structures),
iterators and algorithms. The STL containers are data structures
capable of storing objects of any data type. We will see that there are
three container categories—first-class containers, adapters and near
containers. STL iterators, which have similar properties to pointers,
are used by programs to manipulate the STL-container elements. In fact,
standard arrays can be manipulated as STL containers, using standard
pointers as iterators. We will see that manipulating containers with
iterators is convenient and provides tremendous expressive power when
combined with STL algorithms—in some cases, reducing many lines of code
to a single statement. STL algorithms are functions that perform common
data manipulations such as searching, sorting, comparing elements (or
entire data structures), etc. There are approximately 70 algorithms
implemented in the STL. Most of these algorithms use iterators to
access container elements. We will see that each first-class container
supports specific iterator types, some of which are more powerful than
others. A container’s supported iterator type determines whether the
container can be used with a specific algorithm. Iterators encapsulate
the mechanism used to access container elements. This encapsulation
enables many of the STL algorithms to be applied to several containers
without regard for the underlying container implementation. As long as
a container’s iterators support the minimum requirements of the
algorithm, then the algorithm can process that container’s elements.
This also enables programmers to create algorithms that can process the
elements of multiple different container types. Chapter discusses
how to implement data structures with pointers, classes and dynamic
memory. Pointer-based code is complex, and the slightest omission or
oversight can lead to serious memory-access violations and memory-leak
errors with no compiler complaints. Implementing additional data
structures such as deques, priority queues, sets, maps, etc. requires
substantial additional work. In addition, if many programmers on a
large project implement similar containers and algorithms for different
tasks, the code becomes difficult to modify, maintain and debug. An
advantage of the STL is that programmers can reuse the STL containers,
iterators and algorithms to implement common data representations and
manipulations. This reuse results in substantial development-time and
resource savings. This chapter is meant to be an introduction to the
STL. It is neither complete nor comprehensive. However, it is a
friendly, accessible chapter that should convince you of the value of
the STL and encourage further study. This might be one of the most
important chapters in the book in terms of your appreciation of
software reuse.
Chapter 22—Other Topics—is a collection of
miscellaneous C++ topics. This chapter discusses two cast operators—const_cast and reinterpret_cast.
These operators, along with static_cast
(Chapter ) and dynamic_cast
(Chapter ), provide a more robust mechanism for converting
between types than do the original cast operators C++ inherited from C.
We discuss namespaces, a feature particularly crucial for software
developers who build substantial systems, especially for those who
build systems from class libraries. Namespaces prevent naming
collisions, which can hinder such large software efforts. We discuss
the operator keywords, which are useful for programmers who do not like
cryptic operator symbols. The primary use of these symbols is in
international markets, where certain characters are not always
available on local keyboards. We discuss keyword explicit,
which prevents the compiler from invoking conversion constructors in
undesirable situations; explicit-conversion
constructors can be invoked only through constructor syntax, not
through implicit conversions. We discuss keyword mutable,
which allows a member of a const object to be
changed. Previously, this was accomplished by "casting away const-ness", which is considered a dangerous
practice. We also discuss pointer-to-member operators .*
and ->*, multiple inheritance (including
the problem of "diamond inheritance") and virtual
base classes.
Appendix A—Operator Precedence Chart—presents
the complete set of C++ operator symbols, in which each operator
appears on a line by itself with the operator symbol, its name and its
associativity.
Appendix B—ASCII Character Set—All the
programs in this book use the ASCII character set, which is presented
in this appendix
Appendix C—Number Systems—discusses the
binary, octal, decimal and hexadecimal number systems. It considers how
to convert numbers between bases and explains the one’s complement and
two’s complement binary representations.
Appendix D—C++ Internet and Web Resources—contains
a listing of valuable C++ resources, such as demos, information about
popular compilers (including "freebies"), books, articles, conferences,
job banks, journals, magazines, help, tutorials, FAQs (frequently asked
questions), newsgroups, Web-based courses, product news and C++
development tools.
Appendix E—Introduction to XHTML—provides an
introduction to XHTML—a markup language for describing the elements of
a Web page so that a browser, such as Microsoft Internet Explorer or
Netscape, can render that page. The reader should be familiar with the
contents of this appendix before studying Chapter , Web
Programming with CGI. This appendix does not contain any C++
programming. Some key topics covered include incorporating text and
images in an XHTML document, linking to other XHTML documents,
incorporating special characters (such as copyright and trademark
symbols) into an XHTML document, separating parts of an XHTML document
with horizontal lines (called horizontal rules), presenting
information in lists and tables, and collecting information from users
browsing a site.
Appendix F—XHTML Special Characters—lists many
commonly used XHTML special characters, called character entity
references.
Bibliography—over 100 books and articles to
encourage the student to do further reading on C++ and OOP.
Index—The book contains a comprehensive index to
enable the reader to locate by keyword any term or concept throughout
the text.
[ top ]
|