Electronic Review of Computer Books

[ ERCB Home | New | Feature | Brief | DDJ | Letters | Links ]

[an error occurred while processing this directive]

Vital Statistics

Title C++ Primer, Third Edition
Authors Stanley B. Lippman and Josée Lajoie
Publisher Addison-Wesley Longman
http://www.awl.com/
Copyright 1998
ISBN 0-201-82470-1
Pages 1237
Price $45.95


The Most Educational Path To Learning C++

That C++ is a complex programming language is a well-known fact. Its support for a wide spectrum of diverse programming paradigms (especially after the revamping occurred in the last circa five years period) and countless high- and low-level techniques are hardly recognizable in any other language with an equally strong grip on production projects at all levels in the industry. This wealth does not come without a price, however. And the price to pay is just that -- complexity and greater inclination to committing mistakes, ascribable to the reduced possibility for the compiler to recognize unknowingly incorrect semantics in the code written by the programmer. More limited languages offer less flexibility, but this also means that there is a less broad range of techniques expressible and, consequently, the development tool has higher odds of catching the unwanted mistakes.

During the last fifteen years, the power factor seems to have outperformed the complexity factor, marking the track for massive adoption of C++ in all sorts of serious application realms. Hundreds of books have been published covering every single aspect of the language, including its syntactic and semantic aspects, its effective adoption in small- and large-scale projects, and its most resounding features as well as its most worrying pitfalls.

In the lot, a pretty numerous subset aims at teaching the fundamentals of the language in course style, suitable for adoption as manuals in academic computer science classes, training sessions, and independent study endeavors. They generally assume only a basic knowledge of computer programming and possibly familiarity with another programming language (not necessarily C or an object-oriented one) and promise to walk the reader into discovering, understanding, and harnessing the full power of C++. Of the many in this category, C++ Primer is by far my favorite.

Am I being heretic by dethroning the universally embraced bible of C++, Bjarne Stroustrup's The C++ Programming Language? Yes and no. Both are very valuable texts, with the main difference lying in the usage instructions. C++ Primer is a book you can read and learn from nearly cover to cover, whereas The C++ Programming Language is a reference with which you can look up limited chunks of information on an as-needed basis, consciously putting your trust in the creator of the language, but you will hardly digest it all at once. Which one is preferable as a companion to a C++-intensive course? If the course aims at actually teaching the C++ language inside out, Lippman and Lajoie's text makes for more useful reading and will surely help the students refreshing the modules of the course with a descriptive tone and an equilibrate pace. If the course aims at perfecting the skills of an already solid C++ developer, the punctuality and authority of Stroustrup seems to me a better fit.

Concentrating both completeness and readability in a single resource, C++ Primer sits at the top of my personal ranking for the most educational C++ books. It is one of the few very thick books that I really like and in which the remarkable number of pages actually makes sense, as they allow the authors to offer clear down-to-earth explanations and examples of every bit, thereby guiding the reader into mastering the fundamentals of C++, starting from the most basic elements (data types, statements, expressions, functions) and up to a discreet level of complication (classes, template programming, inheritance, and polymorphism). Basically nothing is given for granted, every concept and piece of information flows progressively and is described with all of its surrounding context. I was gladly surprised by seeing how the authors have managed to furnish some useful bits of C++ design considerations (e.g. glancing at the most important programming paradigms supported by the language, ranging from procedural to object-oriented to template-driven approaches), which, whilst not deep or particularly original, will likely come in handy to C++ neophytes.

On the other hand, this is not an advanced book -- the word "primer" in the title is a sign of the honesty of the authors, who are keen to admitting the inappropriateness of this book for already seasoned C++ users. Despite this, the presentation of such complex topics as the Standard Template Library and the portion on the generic algorithms, now an integral part of the language, are sufficiently complete and readable for the needs of the average programmer.

If you are looking at studying C++ from the ground floor rather than mastering its most intricate peculiarities, C++ Primer will turn out to be a choice you won't regret -- and very good value for your time and money.

-- Davide Marcato (marcato@programmers.net or http://www.DavideMarcato.com)


Table of Contents


Excerpts from C++ Primer

("Chapter 3 -- The C++ Data Types"), page 88

"Every pointer has an associated type. The difference between pointers of different data types is neither in the representation of the pointer nor in the values (addresses) the pointers may hold -- these are generally the same for all data pointers. The difference, rather, is in the type of the object being addressed. The type of a pointer instructs the compiler how to interpret the memory found at a particular address as well as how much memory that interpretation should span.

  • · An int pointer addressing memory location 1000 on a 32-bit machine spans the address space 1000-1003.

    · A double pointer addressing memory location 1000 on a 32-bit machine spans the address space 1000-1007.

  • Here are some examples of pointer definitions:

    […]

    A pointer is defined by prefixing the identifier with the dereference operator (*). In a comma-separated definition list, the dereference operator must precede each identifier intended to serve as a pointer. In the following example, lp is intended as a pointer to an object of type long, and lp2 is interpreted as a data object of type long and not as a pointer:

    long *lp, lp2;

    In this next example, fp is interpreted as a data object of type float and fp2 is interpreted as a pointer to a float:

    float fp, *fp2;

    For clarity, it is preferable to write

    string *ps;

    rather than

    string* ps;

    The possibility is that the programmer, later wishing to define a second string pointer, may incorrectly modify this definition as follows:

    //oops: ps2 is not a string pointer

    string* ps, ps2;

    A pointer can hold a value of 0, indicating that it points to no object, or the address of a data object of the same type.

    […]"

     

    ("Chapter 12 -- The Generic Algorithms"), page 603

    "The first two arguments to all the generic algorithms (with the necessary fistful of exceptions that make the rule) are a pair of iterators, generally referred to as first and last, marking the range of elements within the container or built-in array over which to operate. The element range notation (sometimes called a left-inclusive interval) is usually written as

    // to be read as: includes first and

    // each element up to but not including last

    [first, last)

    indicating that the range begins with first and ends with but does not include last. When

    first == last

    the range is said to be empty.

    A requirement of the iterator pair is that it must be possible to reach last beginning with first through repeated application of the increment operator. However, the compiler cannot itself enforce this; failure to meet this requirement results in undefined run-time behavior -- usually an eventual core dump of the program.

    Each algorithm's declaration indicates the minimum category of iterator support it requires (see Section 12.4 for a brief discussion of the five iterator categories). find(), for example -- which implements a one-pass, read-only traversal over a container -- minimally requires an InputIterator. It can also be passed a Forward-, Bidirectional-, or RandomAccessIterator. Passing it an OutputIterator results in a error. Errors in passing an invalid category of iterator to an algorithm are not guaranteed to be caught at compile-time, because the iterator categories are not actual types. Rather, they are type parameters passed to the function template.

    Some algorithms support multiple versions; one uses a built-in operator, and a second accepts either a function object or a pointer to function providing an alternative implementation of that operator. unique(), for example, by default compares two adjacent elements using the equality operator of the underlying element type of the container. If, however, the underlying element type does not provide an equality operator or if we wish to define element equality differently, we can pass either a function object or a pointer to a function that provides the intended semantics. Other algorithms, however, are separated into two uniquely named instances, the predicate instance in each case ending with the suffix if, as in find_if(). […]


    Quick Rating

    Readability Star Star Star HalfStar
    Originality Star Star Star
    Organization Star Star Star HalfStar
    Accuracy Star Star Star
    Consistency Star Star Star
    Depth Star Star HalfStar
    Timeliness Star Star Star
    Editing Star Star Star
    Design Star Star Star
    Overall Value Star Star Star HalfStar

    Explanation of ERCB rating scale: No stars = unacceptable, 1 Star = marginal, 2 Stars = average, 3 Stars = above average, 4 Stars = exceptional.


    Copyright ©1999 Electronic Review of Computer Books
    Created 6/25/1999 / Last modified 6/25/1999 / webmaster@ercb.com