cover next page > Cover title : Programming and Problem Solving With C++ 3Rd Ed. author : Dale, Nell B.; Weems, Chip.; Headington, Mark R. publisher : Jones & Bartlett Publishers, Inc. isbn10 | asin : 0763721034 print isbn13 : 9780763721039 ebook isbn13 : 9780585481692 language : English subject C (Computer program language) , C++ (Lenguaje de programación) publication date : 2002 lcc : QA76.73.C153D34 2002eb ddc : 005.13/3 subject : C (Computer program language) , C++ (Lenguaje de programación) cover next page > < previous page page_i next page > Page i Programming and Problem Solving with C++ Third Edition Nell Dale University of Texas, Austin Chip Weems University of Massachusetts, Amherst Mark Headington University of Wisconsin – La Crosse < previous page page_i next page > < previous page page_ii next page > Page ii World Headquarters Jones and Bartlett Publishers Jones and Bartlett Publishers Jones and Bartlett Publishers 40 Tall Pine Drive Canada International Sudbury, MA 01776 2406 Nikanna Road Barb House, Barb Mews 978-443-5000 Mississauga, ON L5C 2W6 London W6 7PA [email protected] CANADA UK www.jbpub.com Copyright © 2002 by Jones and Bartlett Publishers, Inc. Library of Congress Cataloging-in-Publication Data Dale, Nell B. Programming amd problem solving with C++ / Nell Dale, Chip Weems, Mark Headington.--3rd ed. p. cm. ISBN 0-7637-2103-4 1. C++ (Computer program language) I. Weems, Chip. II. Headington, Mark R. III. Title. QA76.73.C153 D34 2001 005.13'3–dc21 2001050447 All rights reserved. No part of the material protected by this copyright notice may be reproduced or utilized in any form, electronic or mechanical, including photocopying, recording, or any information storage or retrieval system, without written permission from the copyright owner. Chief Executive Officer: Clayton Jones Chief Operating Officer: Don W. Jones, Jr. Executive V.P. and Publisher: Robert Holland V.P., Managing Editor: Judith H. Hauck V.P., Design and Production: Anne Spencer V.P., Manufacturing and Inventory Control: Therese Bräuer Editor-in-Chief: J. Michael Stranz Development and Product Manager: Amy Rose Marketing Manager: Nathan Schultz Production Assistant: Tara McCormick Editorial Assistant: Theresa DiDonato Cover Design: Night &t Day Design Composition: Northeast Compositors, Inc. Text Design: Anne Spencer IT Manager: Nicole Healey Printing and Binding: Courier Westford Cover printing: John Pow Company, Inc. This book was typeset in Quark 4.1 on a Macintosh G4. The font families used were Rotis Sans Serif, Rotis Serif, and Prestige Elite. The first printing was printed on 40# Lighthouse Matte. Printed in the United States of America 05 04 03 02 01 10 9 8 7 6 5 4 3 2 1 < previous page page_ii next page > < previous page page_iii next page > Page iii To Al, my husband and best friend, and to our children and our children's children. N.D. To Lisa, Charlie, and Abby with love. C.W. To Professor John Dyer-Bennet, with great respect. M.H. < previous page page_iii next page > < previous page page_iv next page > Page iv To quote Mephistopheles, one of the chief devils, and tempter of Faust, ...My friend, I shall be pedagogic, And say you ought to start with Logic... ...Days will be spent to let you know That what you once did at one blow, Like eating and drinking so easy and free, Can only be done with One, Two, Three. Yet the web of thought has no such creases And is more like a weaver's masterpieces; One step, a thousand threads arise, Hither and thither shoots each shuttle, The threads flow on, unseen and subtle, Each blow effects a thousand ties. The philosopher comes with analysis And proves it had to be like this; The first was so, the second so, And hence the third and fourth was so, And were not the first and second here, Then the third and fourth could never appear. That is what all the students believe, But they have never learned to weave. J. W. von Goeth, Faust, Walter Kaufman trans., New York, 1963, 199. As you study this book, do not let the logic of algorithms bind your imagination, but rather make it your tool for weaving masterpieces of thought. < previous page page_iv next page > < previous page page_v next page > Page v Preface The first two editions of Programming and Problem Solving with C++ have consistently been among the best-selling computer science textbooks in the United States. Both editions, as well as the Pascal and Ada versions of the book, have been widely accepted as model textbooks for ACM/IEEE-recommended curricula for the CS1/C101 course and for the Advanced Placement A exam in computer science. Although this third edition incorporates new material, one thing has not changed: our commitment to the student. As always, our efforts are directed toward making the sometimes difficult concepts of computer science more accessible to all students. This edition of Programming and Problem Solving with C++ continues to reflect our experience that topics once considered too advanced can be taught in the first course. For example, we address metalanguages explicitly as the formal means of specifying programming language syntax. We introduce Big-O notation early and use it to compare algorithms in later chapters. We discuss modular design in terms of abstract steps, concrete steps, functional equivalence, and functional cohesion. Preconditions and postconditions are used in the context of the algorithm walk-through, in the development of testing strategies, and as interface documentation for user- written functions. The discussion of function interface design includes encapsulation, control abstraction, and communication complexity. Data abstraction and abstract data types (ADTs) are explained in conjunction with the C++ class mechanism, forming a natural lead-in to object-oriented programming. ISO/ANSI standard C++ is used throughout the book, including relevant portions of the new C++ standard library. However, readers with pre-standard C++ compilers are also supported. An appendix (both in the book and on the publisher's Web site) explains how to modify the textbook's programs to compile and run successfully with an earlier compiler. As in the second edition, C++ classes are introduced in Chapter 11 before arrays. This sequencing has several benefits. In their first exposure to composite types, many students find it easier to comprehend accessing a component by name rather than by position. With classes introduced in Chapter 11, Chapter 12 on arrays can rather easily introduce the idea of an array of class objects or an array of structs. Also, Chapter < previous page page_v next page > < previous page page_vi next page > Page vi 13, which deals with the list as an ADT, can implement a list by encapsulating both the data representation (an array) and the length variable within a class, rather than the alternative approach of using two loosely coupled variables (an array and a separate length variable) to represent the list. Finally, with three chapters' worth of exposure to classes and objects, students reading Chapter 14, ''Object- Oriented Software Development," can focus on the more difficult aspects of the chapter: inheritance, composition, and dynamic binding. Changes in the Third Edition The third edition incorporates the following changes: • A new chapter covering templates and exceptions. In response to feedback from our users and reviewers, we have added a new chapter covering the C++ template mechanism and language facilities for exception handling. These topics were not included in previous editions for two reasons. First, their implementations in prestandard compilers were often inconsistent and in some cases unstable. With the advent of the ISO/ANSI language standard, compilers that support these mechanisms are now readily available. Second, we have considered these topics to be more suitable for a second semester course than for CS1/C101. Many users of the second edition agree with this viewpoint, but others have expressed interest in seeing at least an introductory treatment of the topics. To accommodate the opinions of both groups, we have placed this new chapter near the end of the book, to be considered optional material along with the chapter on recursion. • More examples of complete programs within the chapter bodies. Again in response to requests from our users and reviewers, we have added 15 new complete programs beginning in Chapter 2. These are not case studies (which remain, as in previous editions, at the end of the chapters). Rather, they are programs included in the main text of the chapters to demonstrate language features or design issues that are under discussion. Although isolated code snippets continue to be used, the new programs provide students with enhanced visual context: Where does the loop fit into the entire function? Where are the secondary functions located with respect to the main function? Where are the #include directives placed? Clearly, such information is already visible in the case studies, but the intent is to increase the students' exposure to the "geographic"layout of programs without the overhead of problem-solving discussions as found in the case studies. To this end, we have ensured that every chapter after Chapter 1 has at least one complete program in the main text, with several chapters having three or four such programs. C++ and Object-Oriented Programming Some educators reject the C family of languages (C, C++, Java) as too permissive and too conducive to writing cryptic, unreadable programs. Our experience does not support this view, provided that the use of language features is modeled appropriately. The fact that the C family permits a terse, compact programming style cannot be labeled simply < previous page page_vi next page > < previous page page_vii next page > Page vii as ''good" or "bad." Almost any programming language can be used to write in a style that is too terse and clever to be easily understood. The C family may indeed be used in this manner more often than are other languages, but we have found that with careful instruction in software engineering and a programming style that is straightforward, disciplined, and free of intricate language features, students can learn to use C++ to produce clear, readable code. It must be emphasized that although we use C++ as a vehicle for teaching computer science concepts, the book is not a language manual and does not attempt to cover all of C++. Certain language features– operator overloading, default arguments, run-time type information, and mechanisms for advanced forms of inheritance, to name a few– are omitted in an effort not to overwhelm the beginning student with too much too fast. There are diverse opinions about when to introduce the topic of object-oriented programming (OOP). Some educators advocate an immersion in OOP from the very beginning, whereas others (for whom this book is intended) favor a more heterogeneous approach in which both functional decomposition and object-oriented design are presented as design tools. The chapter organization of Programming and Problem Solving with C++ reflects a transitional approach to OOP. Although we provide an early preview of object-oriented design in Chapter 4, we delay a focused discussion until Chapter 14 after the students have acquired a firm grounding in algorithm design, control abstraction, and data abstraction with classes. Synopsis Chapter 1 is designed to create a comfortable rapport between students and the subject. The basics of hardware and software are presented, issues in computer ethics are raised, and problem-solving techniques are introduced and reinforced in a Problem-Solving Case Study. Chapter 2, instead of overwhelming the student right away with the various numeric types available in C+ +, concentrates on two types only: char and string. (For the latter, we use the ISO/ANSI string class provided by the standard library.) With fewer data types to keep track of, students can focus on overall program structure and get an earlier start on creating and running a simple program. Chapter 3 then begins with a discussion of the C++ numeric types and proceeds with material on arithmetic expressions, function calls, and output. Unlike many books that detail all of the C++ data types and all of the C++ operators at once, these two chapters focus only on the int, float, char, and string types and the basic arithmetic operators. Details of the other data types and the more elaborate C++ operators are postponed until Chapter 10. The functional decomposition and object-oriented design methodologies are a major focus of Chapter 4, and the discussion is written with a healthy degree of formalism. This early in the book, the treatment of object-oriented design is more superficial than that of functional decomposition. However, students gain the perspective that there are two–not one–design methodologies in widespread use and that each serves a specific purpose. Chapter 4 also covers input and file I/O. The early introduction of files permits the assignment of programming problems that require the use of sample data files. Students learn to recognize functions in Chapters 1 and 2, and they learn to use standard library functions in Chapter 3. Chapter 4 reinforces the basic concepts of func- < previous page page_vii next page > < previous page page_viii next page > Page viii tion calls, argument passing, and function libraries. Chapter 4 also relates functions to the implementation of modular designs and begins the discussion of interface design that is essential to writing proper functions. Chapter 5 begins with Boolean data, but its main purpose is to introduce the concept of flow of control. Selection, using If-Then and If-Then-Else structures, is used to demonstrate the distinction between physical ordering of statements and logical ordering. We also develop the concept of nested control structures. Chapter 5 concludes with a lengthy Testing and Debugging section that expands on the modular design discussion by introducing preconditions and postconditions. The algorithm walk-through and code walk-through are introduced as means of preventing errors, and the execution trace is used to find errors that made it into the code. We also cover data validation and testing strategies extensively in this section. Chapter 6 is devoted to loop control strategies and looping operations using the syntax of the While statement. Rather than introducing multiple syntactical structures, our approach is to teach the concepts of looping using only the While statement. However, because many instructors have told us that they prefer to show students the syntax for all of C++'s looping statements at once, the discussion of For and Do-While statements in Chapter 9 can be covered optionally after Chapter 6. By Chapter 7, the students are already comfortable with breaking problems into modules and using library functions, and they are receptive to the idea of writing their own functions. Chapter 7 focuses on passing arguments by value and covers flow of control in function calls, arguments and parameters, local variables, and interface design. The last topic includes preconditions and postconditions in the interface documentation, control abstraction, encapsulation, and physical versus conceptual hiding of an implementation. Chapter 8 expands the discussion to include reference parameters, scope and lifetime, stubs and drivers, and more on interface design, including side effects. Chapter 9 covers the remaining ''ice cream and cake" control structures in C++ (Switch, Do-While, and For), along with the Break and Continue statements. Chapter 9 forms a natural ending point for the first quarter of a two-quarter introductory course sequence. Chapter 10 begins a transition between the control structures orientation of the first half of the book and the abstract data type orientation of the second half. We examine the built-in simple data types in terms of the set of values represented by each type and the allowable operations on those values. We introduce more C++ operators and discuss at length the problems of floating-point representation and precision. User-defined simple types, user-written header files, and type coercion are among the other topics covered in this chapter. We begin Chapter 11 with a discussion of simple versus structured data types. We introduce the record (struct in C++) as a heterogeneous data structure, describe the syntax for accessing its components, and demonstrate how to combine record types into a hierarchical record structure. From this base, we proceed to the concept of data abstraction and give a precise definition to the notion of an ADT, emphasizing the separation of specification from implementation. The C++ class mechanism is introduced as a programming language representation of an ADT. The concepts of encapsulation, information hiding, and public and private class members are stressed. We describe the < previous page page_viii next page > < previous page page_ix next page > Page ix separate compilation of program files, and students learn the technique of placing a class's declaration and implementation into two separate files: the specification (.h) file and the implementation file. In Chapter 12, the array is introduced as a homogeneous data structure whose components are accessed by position rather than by name. One-dimensional arrays are examined in depth, including arrays of structs and arrays of class objects. Material on multidimensional arrays completes the discussion. Chapter 13 integrates the material from Chapters 11 and 12 by defining the list as an ADT. Because we have already introduced classes and arrays, we can clearly distinguish between arrays and lists from the beginning. The array is a built-in, fixed-size data structure. The list is a user-defined, variable-size structure represented in this chapter as a length variable and an array of items, bound together in a class object. The elements in the list are those elements in the array from position 0 through position length - 1. In this chapter, we design C++ classes for unsorted and sorted list ADTs, and we code the list algorithms as class member functions. We use Big-O notation to compare the various searching and sorting algorithms developed for these ADTs. Finally, we examine C strings in order to give students some insight into how a higher-level abstraction (a string as a list of characters) might be implemented in terms of a lower-level abstraction (a null-terminated char array). Chapter 14 extends the concepts of data abstraction and C++ classes to an exploration of object-oriented software development. Object-oriented design, introduced briefly in Chapter 4, is revisited in greater depth. Students learn to distinguish between inheritance and composition relationships during the design phase, and C++'s derived classes are used to implement inheritance. This chapter also introduces C++ virtual functions, which support polymorphism in the form of run-time binding of operations to objects. Chapter 15 examines pointer and reference types. We present pointers as a way of making programs more efficient and of allowing the run-time allocation of program data. The coverage of dynamic data structures continues in Chapter 16, in which we present linked lists, linked-list algorithms, and alternative representations of linked lists. Chapter 17 introduces C++ templates and exception handling, and Chapter 18 concludes the text with coverage of recursion. There is no consensus as to the best place to introduce these subjects. We believe that it is better to wait until at least the second semester to cover them. However, we have included this material for those instructors who have requested it. Both chapters have been designed so that they can be assigned for reading along with earlier chapters. Below we suggest prerequisite reading for the topics in Chapters 17 and 18. Section(s) Topic Prerequisite 17.1 Template functions Chapter 10 17.2 Template classes Chapter 13 17.3 Exceptions Chapter 11 18.1-18.3 Recursion with simple variables Chapter 8 18.4 Recursion with arrays Chapter 12 18.5 Recursion with pointer variables Chapter 16 < previous page page_ix next page >