Programming Abstractions In C Eric Roberts pdf download
Programming Abstractions In C Eric Roberts pdf download
download
https://ebookbell.com/product/programming-abstractions-in-c-eric-
roberts-5903396
https://ebookbell.com/product/programming-abstractions-in-c-
itebooks-23837786
https://ebookbell.com/product/programming-abstraction-in-c-1st-
edition-eric-roberts-5556274
https://ebookbell.com/product/programming-problem-solving-abstraction-
with-c-rev-ed-moffat-6694568
https://ebookbell.com/product/abstracting-away-the-machine-the-
history-of-the-fortran-programming-language-formula-translation-
lorenzo-26481178
Programming Languages And Systems 31st European Symposium On
Programming Esop 2022 Held As Part Of The European Joint Conferences
On Theory And Practice Of Software Etaps 2022 Munich Germany April 27
2022 Proceedings Ilya Sergey
https://ebookbell.com/product/programming-languages-and-systems-31st-
european-symposium-on-programming-esop-2022-held-as-part-of-the-
european-joint-conferences-on-theory-and-practice-of-software-
etaps-2022-munich-germany-april-27-2022-proceedings-ilya-
sergey-44887738
https://ebookbell.com/product/programming-101-learn-to-code-using-the-
processing-programming-language-2nd-edition-2nd-jeanine-meyer-46238180
Programming 101 The How And Why Of Programming Revealed Using The
Processing Programming Language Jeanine Meyer
https://ebookbell.com/product/programming-101-the-how-and-why-of-
programming-revealed-using-the-processing-programming-language-
jeanine-meyer-46318424
https://ebookbell.com/product/programming-and-gui-fundamentals-tcltk-
for-electronic-design-automation-suman-lata-tripathi-46318712
https://ebookbell.com/product/programming-with-openscad-a-beginners-
guide-to-coding-3dprintable-objects-1st-edition-justin-gohde-46410140
Programming
Abstractions in
C ++
Eric S. Roberts
Stanford University
Spring Quarter 2012
Foreword
This text represents a major revision of the course reader that we’ve been using at
Stanford for the last several years. The primary goal of the revision was to bring the
approach more closely in line with the way C++ is used in industry, which will in
turn make it easier to export Stanford’s approach to teaching data structures to a
larger fraction of schools. Even though this quarter’s draft is reasonably complete,
the text remains somewhat rough. In particular, these chapters have not yet had the
benefit of the wonderful copyediting service that my wife Lauren Rusk has provided
for all my books.
This textbook has had an interesting evolutionary history that in some ways
mirrors the genesis of the C++ language itself. Just as Bjarne Stroustrup’s first
version of C++ was implemented on top of a C language base, this reader began its
life as my textbook Programming Abstractions in C (Addison-Wesley, 1998). In
2002-03, Julie Zelenski updated it for use with the C++ programming language,
which we began using in CS106 B and CS106 X during that year. Although the
revised text worked fairly well at the outset, CS106 B and CS106 X have evolved in
recent years so that their structure no longer tracks the organization of the book. In
2009, I embarked on a comprehensive process of rewriting the book so that students
in these courses can use it as both a tutorial and a reference. As always, that process
takes a considerable amount of time, and there are almost certainly some sections of
the book that need a substantial rewrite.
I want to thank my colleagues at Stanford over the last several years, starting
with Julie Zelenski for her extensive work on the initial C++ revision. My
colleagues Keith Schwarz, Jerry Cain, Stephen Cooper, and Mehran Sahami have
all made important contributions to the revision. I also need to express my thanks to
several generations of section leaders and so many students over the years, all of
whom have helped make it so exciting to teach this wonderful material. Finally, I
want to thank the students in CS106 B in winter quarter 2011-12 who put up with a
partially finished reader and contributed many error reports and suggestions.
I’ve always believed that programming is one of the most challenging and
exciting intellectual activities that humans have ever discovered. By staying close
to the machine, C++ gives you all the freedom you need to build applications that
take advantage of the full power of modern computing. I hope you all enjoy the
ride.
i
Contents
1 Overview of C++ 1
1.1 Your first C++ program 2
1.2 The history of C++ 3
1.3 The structure of a C++ program 6
1.4 Variables 14
1.5 Data types 19
1.6 Expressions 26
1.7 Statements 36
1.8 The Stanford C++ libraries 48
Summary 49
Review questions 50
Exercises 52
3 Strings 125
3.1 Using strings as abstract values 126
3.2 String operations 129
3.3 The <cctype> library 137
3.4 Modifying the contents of a string 138
3.5 The legacy of C-style strings 139
3.6 Writing string applications 140
3.7 The strlib.h library 146
Summary 147
Review questions 148
Exercises 149
ii
4 Streams 159
4.1 Using strings as abstract values 160
4.2 Formatted input 165
4.3 Data files 167
4.4 Class hierarchies 180
4.5 Exploring the Stanford libraries 187
Summary 189
Review questions 190
Exercises 191
5 Collections 197
5.1 The Vector class 199
5.2 The Stack class 213
5.3 The Queue class 219
5.4 The Map class 228
5.5 The Set class 234
5.6 Iterating over a collection 238
Summary 245
Review questions 247
Exercises 248
iii
7 Introduction to Recursion 319
7.1 A simple example of recursion 320
7.2 The factorial function 322
7.3 The Fibonacci function 329
7.4 Checking palindromes 336
7.5 The binary search algorithm 339
7.6 Mutual recursion 340
7.7 Thinking recursively 342
Summary 344
Review questions 346
Exercises 348
iv
11 Pointers and Arrays 477
11.1 The structure of memory 478
11.2 Pointers 488
11.3 Arrays 498
11.4 Using functions as data values 508
Summary 515
Review questions 517
Exercises 520
v
15 Maps and Hashing 653
15.1 Implementing maps using arrays 654
15.2 Lookup tables 660
15.3 Hashing 663
Summary 675
Review questions 675
Exercises 677
16 Trees 681
16.1 Family trees 683
16.2 Binary search trees 685
16.3 Balanced trees 698
16.4 Implementing maps using BSTs 709
Summary 711
Review questions 712
Exercises 715
18 Sets 765
18.1 Sets as a mathematical abstraction 766
18.2 Expanding the set interface 770
18.3 Implementation strategies for sets 778
18.4 Optimizing sets of small integers 780
Summary 786
Review questions 787
Exercises 790
vi
19 Graphs 793
19.1 The structure of a graph 794
19.2 Representation strategies 798
19.3 A low-level graph abstraction 802
19.4 Graph traversals 809
19.5 Defining a Graph class 815
19.6 Finding shortest paths 824
19.7 Implementing priority queues 828
Summary 831
Review questions 833
Exercises 835
vii
A Library Interfaces 847
A-1 cmpfn.h 848
A-2 console.h 849
A-3 direction.h 850
A-4 error.h 852
A-5 filelib.h 853
A-6 foreach.h 859
A-7 gevents.h 860
A-8 graph.h 874
A-9 graphics.h 879
A-10 grid.h 887
A-11 gtypes.h 890
A-12 gwindow.h 895
A-13 hashmap.h 904
A-14 hashset.h 907
A-15 lexicon.h 913
A-16 map.h 916
A-17 point.h 919
A-18 pqueue.h 921
A-19 queue.h 924
A-20 random.h 927
A-21 set.h 928
A-22 simpio.h 933
A-23 sound.h 934
A-24 stack.h 936
A-25 strlib.h 938
A-26 thread.h 941
A-27 tokenscanner.h 945
A-28 vector.h 951
Index 955
viii
Chapter 1
An Overview of C++
In Lewis Carroll’s Alice’s Adventures in Wonderland, the King asks the White
Rabbit to “begin at the beginning and go on till you come to the end: then stop.”
Good advice, but only if you’re starting from the beginning. This book is designed
for a second course in computer science and therefore assumes that you have
already begun your study of programming. At the same time, because first courses
vary considerably in what they cover, it is difficult to rely on any specific material.
Some of you, for example, will already understand C++ control structures from
prior experience with closely related languages such as C or Java. For others,
however, the structure of C++ will seem unfamiliar. Because of this disparity in
background, the best approach is to adopt the King’s advice. This chapter therefore
“begins at the beginning” and introduces you to those parts of the C++ language
you will need to write simple programs.
If you were to rewrite it in C++, the “Hello World” program would end up looking
something like the code in Figure 1-1.
At this point, the important thing is not to understand exactly what all of the
lines in this program mean. There is plenty of time to master those details later.
Your mission—and you should decide to accept it—is to get the HelloWorld
program running. Type in the program exactly as it appears in Figure 1-1 and then
figure out what you need to do to make it work. The exact steps you need to use
depend on the programming environment you’re using to create and run C++
programs. If you are using this textbook for a class, your instructor will presumably
provide some reference material on the programming environments you are
1.1 Your first C++ program 3
/*
* File: HelloWorld.cpp
* --------------------
* This file is adapted from the example
* on page 1 of Kernighan and Ritchie's
* book The C Programming Language.
*/
#include <iostream>
using namespace std;
int main() {
cout << "hello, world" << endl;
return 0;
}
expected to use. If you are reading this book on your own, you’ll need to refer to
the documentation that comes with whatever programming environment you’re
using for C++.
When you get all of these details worked out, you should see the output from the
HelloWorld program on a window somewhere on your computer screen. On the
Apple Macintosh on which I prepared this book, that window looks like this:
HelloWorld
hello, world
On your computer, the window will probably have a somewhat different appearance
and may include additional status messages along with your program’s cheery
“hello, world” greeting. But the message will be there. And although it may not be
true that “everything else is comparatively easy” as Kernighan and Ritchie suggest,
you will have achieved a significant milestone.
machine language, which means that a program written for one machine will not run
on other types of hardware.
Since that time, many new programming languages have been invented, most of
which build on previous languages in an evolutionary way. C++ represents the
joining of two branches in that evolution. One of its ancestors is a language called
C, which was designed at Bell Laboratories by Dennis Ritchie in 1972 and then
later revised and standardized by the American National Standards Institute (ANSI)
in 1989. But C++ also descends from a family of languages designed to support a
different style of programming that has dramatically changed the nature of software
development in recent years.
The idea of object-oriented programming is not really all that new. The first
object-oriented language was SIMULA, a language for coding simulations designed
by the Scandinavian computer scientists Ole-Johan Dahl and Kristen Nygaard in
1967. With a design that was far ahead of its time, SIMULA anticipated many of
the concepts that later became commonplace in programming, including the concept
of abstract data types and much of the modern object-oriented paradigm. In fact,
much of the terminology used to describe object-oriented languages comes from the
original 1967 report on SIMULA.
1.2 The history of C++ 5
Unfortunately, SIMULA did not generate a great deal of interest in the years
after its introduction. The first object-oriented language to gain any significant
following within the computing profession was Smalltalk, which was developed at
the Xerox Palo Alto Research Center in the late 1970s. The purpose of Smalltalk,
which is described in the book Smalltalk-80: The Language and Its Implementation
by Adele Goldberg and David Robson, was to make programming accessible to a
wider audience. As such, Smalltalk was part of a larger effort at Xerox PARC that
gave rise to much of the modern user-interface technology that is now standard on
personal computers.
Despite many attractive features and a highly interactive user environment that
simplifies the programming process, Smalltalk never achieved much commercial
success. The profession as a whole took an interest in object-oriented programming
only when the central ideas were incorporated into variants of C, which had already
become an industry standard. Although there were several parallel efforts to design
an object-oriented language based on C, the most successful was the language C++,
which was developed by Bjarne Stroustrup at AT&T Bell Laboratories in the early
1980s. C++ includes standard C as a subset, which makes it possible to integrate
C++ code into existing C programs in a gradual, evolutionary way.
combining all the individual object files into an executable file is called linking.
The steps in the compilation process are illustrated in Figure 1-2.
executable file
10011111111000111100111011110100111101100
11010011011100101110111000111001111010100
11100000010000111000000110111110001010111
10001010111010010001000110011011100010010
11000100101011101001011011000101101111101
10110111110111011111101100110110111001110
11100111000111111101000111110001110111010
11110011111010111101110100001111011101010
11011101000011111101010011100101111011111
10111101111101011101111110100010101000000
11011110011011101000011100011111001010010
10101000011110011100101000100110111010111
10110101110111011101011110001001111110010
11111111110011111100100111011011010000100
linker 11010111001111110001101010010111101000010
10001100111001011101000000111110110100000
10111011111101011111111101001110100000111
10100111101011001110101100000101111010000
program. The HelloWorld program does none of these things. To illustrate more
of the features of C++, Figure 1-3 shows the code for a program that lists powers of
two along with some annotations that describe the various parts of the program.
/*
* File: PowersOfTwo.cpp
* ---------------------
* This program generates a list of the powers of Program comments
* two up to an exponent limit entered by the user.
*/
When you run the PowersOfTwo program shown in Figure 1-3, the computer
begins by asking you for an exponent limit, which specifies how many powers of
two the program should generate. If you type in 8, for example, the program will
generate a list of the powers of two up to 28, as follows:
PowersOfTwo
This program lists powers of two.
Enter exponent limit: 8
2 to the 0 = 1
2 to the 1 = 2
2 to the 2 = 4
2 to the 3 = 8
2 to the 4 = 16
2 to the 5 = 32
2 to the 6 = 64
2 to the 7 = 128
2 to the 8 = 256
This screen image shows what happens if you execute the PowersOfTwo program.
Such images are called sample runs. In each sample run, input from the user
appears in blue so that it is easy to distinguish input data from the output generated
by the program.
Comments
Much of the text in Figure 1-3 consists of English-language comments. A comment
is text that is ignored by the compiler but which nonetheless conveys information to
other programmers. A comment consists of text enclosed between the markers
/* and */ and may continue over several lines. Alternatively, you can also specify
single-line comments, which begin with the characters // and extend through the
end of the line. This book uses the multiline /* . . . */ comment form except when
the comment marks some part of a program that is not yet complete. Adopting that
strategy makes it easier to find unfinished parts of a program.
As you can see from Figure 1-3, the PowersOfTwo program includes a comment
at the beginning that describes the program as a whole and one before the definition
of raiseToPower that describes the operation of that function at a lower level of
detail. In addition, the program includes a couple of one-line comments that act like
section headings in English text.
Library inclusions
Modern programs are never written without using libraries, which are collections of
previously written tools that perform useful operations. C++ defines a number of
standard libraries, of which one of the most important is iostream. This library
defines a set of simple input and output operations based on a data structure called a
stream, which is a data structure used to manage the flow of information to or from
some data source, such as the console or a file.
To gain access to the iostream library, your program must contain the line
#include <iostream>
This line instructs the C++ compiler to read the relevant definitions from what is
called a header file. The angle brackets in this line indicate that the header file is a
system library that is part of standard C++. Beginning in Chapter 2, you will also
have occasion to use header files that you have written yourself or that come from
other libraries. Those header files typically end with the suffix .h and are enclosed
in quotation marks instead of angle brackets.
In C++, reading in a header file using #include is often not sufficient by itself
to use a system library. To ensure that the names defined in different parts of a
large system do not interfere with one another, the designers of C++ made it
possible to segment code into structures called namespaces, each of which keeps
track of its own set of names. The standard C++ libraries use a namespace called
std, which means that you cannot refer to the names defined in standard header
files like iostream unless you let the compiler know to which namespace those
definitions belong.
If you want to write code that looks like that of a professional, you can adopt this
style. For someone just learning the language, all those std:: tags make programs
harder to read, so this book instead adopts the convention of adding the line
at the end of the library inclusion section. At times—most importantly when you
start to define your own library interfaces in Chapter 2—you will need to remember
that the complete name of anything in the standard library namespace includes the
std:: prefix. For the moment, however, it is probably easiest to think of the
as one of the incantations that the C++ compiler requires to work its magic on your
code.
Function prototypes
Computation in a C++ program is carried out in the context of functions. A
function is a named section of code that performs a specific operation. The
PowersOfTwo program contains two functions—main and raiseToPower—each
of which is described in more detail in one of the sections that follow. Although the
definitions of these functions appear toward the end of the file, the PowersOfTwo
program provides a concise description of the raiseToPower function just after the
library inclusions. This concise form is called a prototype and makes it possible to
make calls to that function before its actual definition appears.
A C++ prototype consists of the first line of the function definition followed by a
semicolon, as illustrated by the prototype
This prototype tells the compiler everything it needs to know about how to call that
function when it appears in the code. As you will see in the expanded discussion of
functions in Chapter 2, the prototype for raiseToPower indicates that the function
takes two integers as arguments and returns an integer as its result.
You must provide the declaration or definition of each function before making
any calls to that function. C++ requires such prototype declarations so the compiler
can check whether calls to functions are compatible with the function definitions. If
you accidentally supply the wrong number of arguments or if the arguments are of
the wrong type, the compiler reports an error, which makes it easier to find such
problems in your code.
The first line of the main function in the PowersOfTwo program is an example
of a variable declaration, which reserves space for a value used by the program. In
this case, the line
int limit;
introduces a new variable named limit capable of holding a value of type int, the
standard type used to represent integers. The syntax of variable declarations is
discussed in more detail in the section on “Variables” later in this chapter. For now,
all you need to know is that this declaration creates space for an integer variable that
you can then use in the body of the main function.
This line has the same effect of the single statement in HelloWorld and sends a
message to the user indicating what the program does. The identifier cout refers to
the console output stream, which is one of the facilities defined by the iostream
interface. The effect of this statement is to take the characters enclosed in quotation
marks and send them to the cout stream, followed by the end-of-line sequence
endl, which ensures that next output operation will begin on a new line.
The next two lines are concerned with asking the user to provide a value for the
variable limit. The line
also prints a message to the cout stream, just as the first line did. The purpose of
this line is to let the user know what kind of input value is required. Such messages
are generally known as prompts.
When you print a prompt requesting input from the user, it is conventional to
omit the endl value so that the prompt appears on the same line as the user input.
When the computer executes this line of the program, it will display the prompt but
leaves the console cursor—the blinking vertical bar or square that marks the current
input position—at the end of the line, waiting for the user’s value, as follows:
PowersOfTwo
This program lists powers of two.
Enter exponent limit: |
12 Overview of C++
The identifier cin represents the console input stream, which is the counterpart to
cout for reading input from the user. This statement indicates that the next value
from the cin stream should be stored in the variable limit. Moreover, because
limit is declared as an integer variable, the >> operator automatically converts the
characters typed by the user into the appropriate integer. Thus, when the user types
8 and hits the RETURN key, the effect is to set limit to 8.
The next line of the main function is a for statement, which is used to repeat a
block of code. Like all control statements in C++, the for statement is divided into
a header line, which defines the nature of the control operation, and a body, which
indicates which statements are affected by the control operation. In this case, the
division looks like this:
The header line—which you will have a chance to understand in more detail in the
section on “The for statement” later in this chapter—indicates that the statements
in the body, whatever they are, should be repeated for each value of i beginning
with 0 and continuing up to and including the value of limit. Each execution of
the body of the loop prints a single line showing the value of 2i for the current value
of the variable i.
This statement illustrates a couple of points. First, statements can be split across
more than one line; it is the semicolon that marks the end of the statement, and not
simply the end of the line. Second, this statement showcases the ability of the cout
stream to chain different output values together and to convert numeric quantities
into a printable form. The first part of the output is the character sequence
2 to the
This output is then followed by the value of the variable i, an equal sign surrounded
by spaces, the value of the function call
raiseToPower(2, i)
1.3 The structure of a C++ program 13
and finally the end of line marker. The spaces in the strings ensure that the numeric
values do not run together.
Before the program can print the output line, however, it must invoke the
raiseToPower function to see what the value should be. Calling raiseToPower
suspends the execution of the main function, which then waits until the desired
value is returned.
As was true in the HelloWorld program as well, the final statement in main is
return 0;
This statement indicates that the value of the main function is 0. By convention,
C++ uses the value of the main function to report the status of the entire program.
A value of 0 indicates success; any other value is taken as an indication of failure.
Function definitions
Because large programs are difficult to understand in their entirety, most programs
are broken down into several smaller functions, each of which is easier to
understand. In the PowersOfTwo program, the raiseToPower function is used to
raise an integer to a power—an operation that is not built into C++ and must
therefore be defined explicitly.
int result = 1;
The next statement in the function is a for loop—similar to the one you’ve
already seen in the main program—that executes its body k times. The body of the
for loop consists of the line
14 Overview of C++
result *= n;
which is C++ shorthand for the English sentence “Multiply result by n.” Because
the function initializes the value of result to 1 and then multiplies result by n a
total of k times, the variable result ends up with the value nk.
return result;
which indicates that the function should return result as the value of the function.
1.4 Variables
Data values in a program are usually stored in variables, which are named locations
in memory capable of holding a particular data type. You have already seen
examples of variables in the PowersOfTwo program and are almost certainly
familiar with the basic concept from your earlier programming experience. The
purpose of this section is to outline the rules for using variables in C++.
Variable declarations
In C++, you must declare each variable before you use it. The primary function of
declaring a variable is to make an association between the name of the variable and
the type of value that variable contains. The placement of the declaration in a
program also determines the scope of the variable, which is the region in which that
variable is accessible.
type namelist;
where type indicates the data type and namelist is a list of variable names separated
by commas. In most cases, each declaration introduces a single variable name. For
example, the function main in PowersOfTwo begins with the line
int limit;
which declares the variable limit to be of type int. You can, however, declare
several variable names at once, as in the following declaration, which declares three
variables named n1, n2, and n3:
In this case, the variables are each declared to be of type double, which is the type
C++ uses to represent numbers that can have fractional parts. The name double is
1.4 Variables 15
short for double-precision floating-point, but there is no reason to worry about what
all those terms mean. This declaration appears in the AddThreeNumbers program
in Figure 1-4, which reads in three numbers and writes out their sum.
It is important to remember that both the name and the type of a variable remain
fixed throughout its lifetime but that the value of that variable will typically change
as the program runs. To emphasize the dynamic nature of the value of a variable, it
often helps to diagram variables as boxes in which the name appears outside as a
label on the box and the value appears on the inside. For example, you might
diagram the declaration of limit like this:
limit
Assigning a value to limit overwrites any previous contents of the box, but does
not change the name or the type.
In C++, the initial contents of a variable are undefined. If you want a variable to
have a particular value, you need to initialize it explicitly. To do so, all you need to
do is include an equal sign and a value after a variable name. Thus, the declaration
int result = 1;
/*
* File: AddThreeNumbers.cpp
* -------------------------
* This program adds three floating-point numbers and prints their sum.
*/
#include <iostream>
using namespace std;
int main() {
double n1, n2, n3;
cout << "This program adds three numbers." << endl;
cout << "1st number: ";
cin >> n1;
cout << "2nd number: ";
cin >> n2;
cout << "3rd number: ";
cin >> n3;
double sum = n1 + n2 + n3;
cout << "The sum is " << sum << endl;
return 0;
}
16 Overview of C++
is a shorthand for the following code, in which the declaration and assignment are
separate:
int result;
result = 1;
Naming conventions
The names used for variables, functions, types, constants, and so forth are
collectively known as identifiers. In C++, the rules for identifier formation are
1. The name must start with a letter or the underscore character (_).
2. All other characters in the name must be letters, digits, or the underscore. No
spaces or other special characters are permitted in names.
3. The name must not be one of the reserved keywords listed in Table 1-1.
each word to make the name easier to read. Because that strategy doesn’t work for
constants, programmers use the underscore character to mark the word boundaries.
Constants
As you write your programs, you will find that you often use the same constant
many times in a program. If, for example, you are performing geometrical
calculations that involve circles, the constant π comes up frequently. Moreover, if
those calculations require high precision, you might actually need all the digits that
fit into a value of type double, which means you would be working with the value
3.14159265358979323846. Writing that constant over and over again is tedious at
best, and likely to introduce errors if you type it in by hand each time instead of
cutting and pasting the value. It would be better if you could give this constant a
name and then refer to it by that name everywhere in the program. You could, of
course, simply declare it as a local variable by writing
double pi = 3.14159265358979323846;
but you would then be able to use it only within the method in which it was defined.
A better strategy is to declare it as a global constant like this:
The keyword const at the beginning of this declaration indicates that the value will
not change after the variable is initialized, thereby ensuring that the value remains
18 Overview of C++
constant. It would not be appropriate, after all, to change the value of π (despite the
fact that a bill was introduced in 1897 into the Indiana State Legislature attempting
to do just that). The rest of the declaration consists of the type, the name, and the
value, as before. The only difference is that the name is written entirely in
uppercase to be consistent with the C++ naming conventions for constants.
At some later point, however, the explosive growth of networking would force you
to raise this bound. That process would be relatively easy if you used named
constants in your programs. To raise the limit on the number of hosts to 1023, it
might well be sufficient to change this declaration so that it read
Note that the situation would be entirely different if you had used the numeric
constant 127 instead. In that case, you would need to search through the entire
program and change all instances of 127 used for this purpose to the larger value.
Some instances of 127 might well refer to other things than the limit on the number
of hosts, and it would be just as important not to change any of those values. In the
likely event that you made a mistake, you would have a very hard time tracking
down the bug.
1.5 Data types 19
and so on, up to the limits established by the hardware of the machine. The set of
operations applicable to values of type int includes, for example, the standard
arithmetic operations like addition and multiplication. Other types have a different
domain and set of operations.
As you will learn in the later chapters in this book, much of the power of modern
programming languages like C++ comes from the fact that you can define new data
types from existing ones. To get that process started, C++ includes several
fundamental types that are defined as part of the language. These types, which act
as the building blocks for the type system as a whole, are called atomic or
primitive types. These predefined types are grouped into five categories—integer,
floating-point, Boolean, character, and enumerated types—which are discussed in
the sections that follow.
Integer types
Although the concept of an integer seems like a simple one, C++ actually includes
several different data types for representing integer values. In most cases, all you
need to know is the type int, which corresponds to the standard representation of
an integer on the computer system you are using. In certain cases, however, you
need to be more careful. Like all data, values of type int are stored internally in
storage units that have a limited capacity. Those values therefore have a maximum
size, which limits the range of integers you can use. To get around this problem,
C++ defines three integer types—short, int, and long—distinguished from each
other by the size of their domains.
20 Overview of C++
Unfortunately, the language definition for C++ does not specify an exact range
for these three types. As a result, the range for the different integer types depends
on the machine and the compiler you’re using. In the early years of computing, the
maximum value of type int was typically 32,767, which is very small by today’s
standards. If you had wanted, for example, to perform a calculation involving the
number of seconds in a year, you could not use type int on those machines,
because that value (31,536,000) is considerably larger than 32,767. Modern
machines tend to support larger integers, but the only properties you can count on
are the following:
• The internal size of an integer cannot decrease as you move from short to int
to long. A compiler designer for C++ could, for example, decide to make
short and int the same size but could not make int smaller than short.
• The maximum value of type int must be at least 32,767 (215–1).
• The maximum value of type long must be at least 2,147,483,647 (231–1).
The designers of C++ could have chosen to define the allowable range of type
int more precisely. For example, they could have declared—as the designers of
Java did—that the maximum value of type int would be 231–1 on every machine.
Had they done so, it would be easier to move a program from one system to another
and have it behave in the same way. The ability to move a program between
different machines is called portability, which is an important consideration in the
design of a programming language.
In C++, each of the integer types int, long, and short may be preceded by the
keyword unsigned. Adding unsigned creates a new data type in which no
negative values are allowed. Unsigned values also offer twice the range of positive
values when compared to their signed counterparts. On modern machines, for
example, the maximum value of type int is typically 2,147,483,647, but the
maximum value of type unsigned int is 4,294,967,295. C++ allows the type
unsigned int to be abbreviated to unsigned, and most programmers who use
this type tend to follow this practice.
Floating-point types
Numbers that include a decimal fraction are called floating-point numbers, which
are used to approximate real numbers in mathematics. C++ defines three different
floating-point types: float, double, and long double. Although ANSI C++
does not specify the exact representation of these types, the way to think about the
difference is that the longer types—where long double is longer than double,
which is in turn longer than float—allow numbers to be represented with greater
precision at the cost of occupying more memory space. Unless you are doing
exacting scientific calculation, however, the differences between these types will
not make a great deal of difference. In keeping with a common convention among
C++ programmers, this text uses the type double as its standard floating-point
type.
Floating-point constants in C++ are written with a decimal point. Thus, if 2.0
appears in a program, the number is represented internally as a floating-point value;
if the programmer had written 2, this value would be an integer. Floating-point
values can also be written in a special programmer’s style of scientific notation, in
which the value is represented as a floating-point number multiplied by an integral
power of 10. To write a number using this style, you write a floating-point number
in standard notation, followed immediately by the letter E and an integer exponent,
optionally preceded by a + or - sign. For example, the speed of light in meters per
second can be written in C++ as
2.9979E+8
Boolean type
In the programs you write, it is often necessary to test a particular condition that
affects the subsequent behavior of your code. Typically, that condition is specified
using an expression whose value is either true or false. This data type—for which
the only legal values are the constants true and false—is called Boolean data,
after the mathematician George Boole, who developed an algebraic approach for
working with such values.
In C++, the Boolean type is called bool. You can declare variables of type
bool and manipulate them in the same way as other data objects. The operations
that apply to the type bool are described in detail in the section entitled “Boolean
operators” on page 34.
22 Overview of C++
Characters
In the early days, computers were designed to work only with numeric data and
were sometimes called number crunchers as a result. Modern computers, however,
work less with numeric data than they do with text data, that is, any information
composed of individual characters that appear on the keyboard and the screen. The
ability of modern computers to process text data has led to the development of word
processing systems, online reference libraries, electronic mail, social networks, and
a seemingly infinite supply of exciting applications.
The most primitive elements of text data are individual characters, which are
represented in C++ using the predefined data type char. The domain of type char
is the set of symbols that can be displayed on the screen or typed on the keyboard:
the letters, digits, punctuation marks, spacebar, RETURN key, and so forth.
Internally, these values are represented inside the computer by assigning each
character a numeric code. In most implementations of C++, the coding system used
to represent characters is called ASCII, which stands for the American Standard
Code for Information Interchange. The decimal values of the characters in the
ASCII set are shown in Table 1-2, where the ASCII code for any character is the
sum of the numbers at the beginning of its row and column.
0 1 2 3 4 5 6 7 8 9
0x \000 \001 \002 \003 \004 \005 \006 \a \b \t
1x \n \v \f \r \016 \017 \020 \021 \022 \023
2x \024 \025 \026 \027 \030 \031 \032 \033 \034 \035
3x \036 \037 space ! " # $ % & '
4x ( ) * + , - . / 0 1
5x 2 3 4 5 6 7 8 9 : ;
6x < = > ? @ A B C D E
7x F G H I J K L M N O
8x P Q R S T U V W X Y
9x Z [ \ ] ^ _ ‘ a b c
10 x d e f g h i j k l m
11 x n o p q r s t u v w
12 x x y z { | } ~ \177
1.5 Data types 23
to a particular character. When you type the letter A, the hardware logic built into
the keyboard automatically translates that character into the ASCII code 65, which
is then sent to the computer. Similarly, when the computer sends the ASCII code
65 to the screen, the letter A appears.
You can write a character constant in C++ by enclosing the character in single
quotes. Thus, the constant 'A' represents the internal code of the uppercase letter
A. In addition to the standard characters, C++ allows you to write special characters
in a multicharacter form beginning with a backward slash (\). This form is called
an escape sequence. Table 1-3 shows the escape sequences that C++ supports.
Strings
Characters are most useful when they are collected together into sequential units. In
programming, a sequence of characters is called a string. So far, the strings you’ve
seen in the HelloWorld and PowersOfTwo programs have been used simply to
display messages on the screen, but they have many more applications than that.
You write string constants in C++ by enclosing the characters contained within
the string in double quotes. As with character, C++ uses the escape sequences from
Table 1-3 to represent special characters. If two or more string constants appear
consecutively in a program, the compiler concatenates them together. The most
important implication of this rule is that you can break a long string over several
lines so that it doesn’t end up running past the right margin of your program.
T A B L E 1 - 3 Escape sequences
Given that they are essential to so many applications, all modern programming
languages include special features for working with strings. Unfortunately, C++
complicates the issue by defining two different string types: an older style inherited
from C and a more sophisticated string library that supports the object-oriented
paradigm. To minimize confusion, this text uses the string library wherever
possible, and you should—for the most part—feel free to ignore the fact that two
string models exist. The times when that complexity raises its ugly head are
outlined in Chapter 3, which covers the string library in more detail. For the
moment, you can simply imagine that C++ offers a built-in data type called string
whose domain is the set of all sequences of characters. You can declare variables of
type string and pass string values back and forth between functions as arguments
and results.
The fact that string is a library type and not a built-in feature does have a few
implications. If you use the type name string in a program, you need to add the
string library to the list of #include lines, like this:
#include <string>
Moreover, because the string type is part of the standard library namespace, the
compiler will recognize the type name only if you have included the line
at the beginning of the file, as the programs in this book invariably do.
Enumerated types
As the discussion of ASCII codes in the preceding section makes clear, computers
store character data in integer by assigning a number to each character. This idea of
encoding data as integers by numbering the elements of the domain is actually a
much more general principle. C++ allows you to define new types simply by listing
the elements in their domain. Such types are called enumerated types.
where typename is the name of the new type and namelist is a list of the constants in
the domain, separated by commas. In this book, all type names start with an
uppercase letter, and the names of the enumeration constants are written entirely in
uppercase. For example, the following definition introduces a new Direction
type whose values are the four compass directions:
When the C++ compiler encounters this definition, it assigns values to the constant
names by numbering them consecutively starting with 0. Thus, NORTH is assigned
the value 0, EAST is assigned the value 1, SOUTH is assigned the value 2, and WEST
is assigned the value 3.
C++ allows you to assign explicit underlying values to each of the constants of
an enumerated type. For example, the type declaration
enum Coin {
PENNY = 1,
NICKEL = 5,
DIME = 10,
QUARTER = 25,
HALF_DOLLAR = 50,
DOLLAR = 100
};
introduces an enumerated type for U.S. coinage in which each constant is defined to
equal the monetary value of that coin. If you supply values for some of the
constants but not others, the C++ compiler will automatically choose values for the
unassigned constants by numbering them consecutively after the last value you
supplied. Thus, the type declaration
enum Month {
JANUARY = 1,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER
};
introduces a type for the months of the year in which JANUARY has the value 1,
FEBRUARY has the value 2, and so forth up to DECEMBER, which has the value 12.
Compound types
The atomic types described in the preceding sections form the basis of a very rich
type system that allows you to create new types from existing ones. Moreover,
because C++ represents a synthesis of the object-oriented and procedural
26 Overview of C++
paradigms, the type system includes both objects and more traditional structures.
Learning how to define and manipulate these types is, to a large extent, the theme of
this entire book. It therefore does not make sense to squeeze a complete description
of these types into Chapter 1. That’s what the rest of the chapters are for.
Over the years of teaching this material at Stanford, we have discovered that you
are much more likely to master the concepts of object-oriented programming if the
details of defining classes and objects are presented after you have had a chance to
use them in a high-level way. This book adopts that strategy and postpones any
discussion of how to create your own objects until Chapter 6, at which point you
will have had plenty of time to discover just how useful objects can be.
1.6 Expressions
Whenever you want a program to perform calculations, you need to write an
expression that specifies the necessary operations in a form similar to that used for
expressions in mathematics. For example, suppose that you wanted to solve the
quadratic equation
ax2 + bx + c = 0
As you know from high-school mathematics, this equation has two solutions given
by the formula
- b + b 2 - 4ac
x =
2a
The first solution is obtained by using + in place of the ± symbol; the second is
obtained by using – instead. In C++, you could compute the first of these solutions
by writing the following expression:
subtraction. The precedence of the unary and binary versions of an operator are
different and are listed separately in the precedence table.
If two operators have the same precedence, they are applied in the order
specified by their associativity, which indicates whether that operator groups to the
left or to the right. Most operators in C++ are left-associative, which means that the
leftmost operator is evaluated first. A few operators—most notably the assignment
operator discussed in its own section later in this chapter—are right-associative,
which mean that they group from right to left. The associativity for each operator
appears in Table 1-4.
Without the parentheses, the division operator would be performed first because /
and * have the same precedence and associate to the left. This example illustrates
the use of the bug icon to mark code that is intentionally incorrect to make sure that
you don’t copy it into your own programs.
n + 1
is evaluated using integer arithmetic and produces a result of type int. The
expression
x + 1
however, is evaluated by converting the integer 1 to the floating-point value 1.0 and
adding the results together using double-precision floating-point arithmetic, which
results in a value of type double.
9 / 4
C++’s rules specify that the result of this operation must be an integer, because both
operands are of type int. When C++ evaluates this expression, it divides 9 by 4
and discards any remainder. Thus, the value of this expression in C++ is 2, not
2.25.
9.0 / 4
9 / 4.0
9.0 / 4.0
each produce the floating-point value 2.25. The decimal fraction is thrown away
only if both operands are of type int. The operation of discarding a decimal
fraction is called truncation.
The / operator in C++ is closely associated with the % operator, which returns
the remainder left over when the first operand is divided by the second. For
example, the value of
9 % 4
30 Overview of C++
is 1, since 4 goes into 9 twice, with 1 left over. The following are some other
examples of the % operator:
0 % 4 = 0 19 % 4 = 3
1 % 4 = 1 20 % 4 = 0
4 % 4 = 0 2001 % 4 = 1
It is, however, important to use caution if either or both of the operands to / and
% might be negative, because the results may differ from machine to machine. On
most machines, division truncates its result toward 0, but this behavior is not
actually guaranteed by the ANSI standard. In general, it is good programming
practice to avoid—as this book does—using these operators with negative values.
Type casts
In C++, you can specify explicit conversion by using what is called a type cast,
which specifies an explicit conversion from one type to another. In C++, type casts
are usually written by specifying the name of the desired type followed by the value
you wish to convert in parentheses. For example, if num and den are declared as
integers, you can compute the floating-point quotient by writing
The first step in evaluating the expression is to convert num to a double, after
which the division is performed using floating-point arithmetic as described in the
section on “Mixing types in an expression” earlier in this chapter.
As long as the conversion moves upward in the hierarchy shown in Table 1-5,
the conversion involves no loss of information. If, however, you convert a value of
a more precise type to a less precise one, some information may be lost. For
example, if you use a type cast to convert a value of type double to type int, any
decimal fraction is simply dropped. Thus, the value of the expression
int(1.9999)
is the integer 1.
operator is executed, the expression on the right-hand side is evaluated, and the
resulting value is then stored in the variable that appears on the left-hand side.
Thus, if you evaluate an expression like
result = 1
the effect is that the value 1 is assigned to the variable result. In most cases,
assignment expressions of this sort appear in the context of simple statements,
which are formed by adding a semicolon after the expression, as in the line
result = 1;
The assignment operator converts the type of the value on the right-hand side so
that it matches the declared type of the variable. Thus, if the variable total is
declared to be of type double, and you write the assignment statement
total = 0;
n = 3.14159265;
has the effect of setting n to 3, because the value is truncated to fit in the integer
variable.
z = (x = 6) + (y = 7)
has the effect of setting x to 6, y to 7, and z to 13. The parentheses are required in
this example because the = operator has a lower precedence than +. Assignments
that are written as part of larger expressions are called embedded assignments.
n1 = n2 = n3 = 0;
which has the effect of setting all three variables to 0. This statement works
because C++ evaluates assignment operators from right to left. The entire statement
is therefore equivalent to
is equivalent to
where the parentheses are included to emphasize that the entire expression is
evaluated before op is applied. Thus, the statement
balance += deposit;
is a shorthand for
Because this same shorthand applies to any binary operator in C++, you can
subtract the value of surcharge from balance by writing
balance -= surcharge;
x /= 10;
1.6 Expressions 33
x++;
x += 1;
x = x + 1;
Similarly,
y--;
y -= 1;
or
y = y - 1;
As it happens, these operators are more intricate than the previous examples
would suggest. To begin with, each of these operators can be written in two ways.
The operator can come after the operand to which it applies, as in
x++
++x
The first form, in which the operator follows the operand, is called the postfix form,
the second, the prefix form.
these operators as part of a larger expression. Then, like all operators, the ++
operator returns a value, but the value depends on where the operator is written
relative to the operand. The two cases are as follows:
x++ Calculates the value of x first, and then increments it. The value
returned to the surrounding expression is the original value before the
increment operation is performed.
++x Increments the value of x first, and then uses the new value as the
value of the ++ operation as a whole.
The -- operator behaves similarly, except that the value is decremented rather than
incremented.
You may wonder why would anyone use such an arcane feature. The ++ and --
operators are certainly not essential. Moreover, there are not many circumstances in
which programs that embed these operators in larger expressions are demonstrably
better than those that use a simpler approach. On the other hand, ++ and -- are
firmly entrenched in the historical tradition shared by the languages C, C++, and
Java. Programmers use them so frequently that they have become essential idioms
in these languages. In light of their widespread use in programs, you need to
understand these operators so that you can make sense of existing code.
Boolean operators
C++ defines three classes of operators that manipulate Boolean data: the relational
operators, the logical operators, and the ?: operator. The relational operators are
used to compare two values. C++ defines six relational operators, as follows:
== Equal
!= Not equal
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
When you write programs that test for equality, be careful to use the == operator,
which is composed of two equal signs. A single equal sign is the assignment
operator. Since the double equal sign violates conventional mathematical usage,
replacing it with a single equal sign is a particularly common mistake. This mistake
can also be very difficult to track down because the C++ compiler does not usually
catch it as an error. A single equal sign turns the expression into an embedded
assignment, which is perfectly legal in C++; it just isn’t at all what you want.
1.6 Expressions 35
The relational operators can be used to compare atomic data values like integers,
floating-point numbers, Boolean values, and characters, but those operators can also
be applied to many of the types supplied by libraries, such as string.
In addition to the relational operators, C++ defines three logical operators that
take Boolean operands and combine them to form other Boolean values:
Although the operators &&, ||, and ! closely resemble the English words and,
or, and not, it is important to remember that English can be somewhat imprecise
when it comes to logic. To avoid that imprecision, it is often helpful to think of
these operators in a more formal, mathematical way. Logicians define these
operators using truth tables, which show how the value of a Boolean expression
changes as the values of its operands change. The truth table in Table 1-6 illustrates
the result for each of the logical operators, given all possible values of the variables
p and q.
or
exp1 || exp2
the individual subexpressions are always evaluated from left to right, and evaluation
ends as soon as the result can be determined. For example, if exp1 is false in the
expression involving &&, there is no need to evaluate exp2 since the final result will
always be false. Similarly, in the example using ||, there is no need to evaluate
the second operand if the first operand is true. This style of evaluation, which
stops as soon as the result is known, is called short-circuit evaluation.
p q p && q p || q !p
false false false false true
false true false true true
true false false true false
true true true true false
36 Overview of C++
The parentheses are not technically required, but C++ programmers often include
them to emphasize the boundaries of the conditional test.
When a C++ program encounters the ?: operator, it first evaluates the condition.
If the condition turns out to be true, exp1 is evaluated and used as the value of the
entire expression; if the condition is false, the value is the result of evaluating
exp2. For example, you can use the ?: operator to assign to max either the value of
x or the value of y, whichever is greater, as follows:
max = (x > y) ? x : y;
1.7 Statements
Programs in C++ are composed of functions, which are made up in turn of
statements. As in most languages, statements in C++ fall into one of two principal
classifications: simple statements that perform some action and control statements
that affect the way in which other statements are executed. The sections that follow
review the principal statement forms available in C++, giving you the tools you
need to write your own programs.
Simple statements
The most common statement in C++ is the simple statement, which consists of an
expression followed by a semicolon:
expression;
Blocks
As C++ is defined, control statements typically apply to a single statement. When
you are writing a program, you often want a particular control statement to apply to
a whole group of statements. To indicate that a sequence of statements is part of a
coherent unit, you can assemble those statements into a block, which is a collection
of statements enclosed in curly braces, as follows:
1.7 Statements 37
{
statement1
statement2
. . .
statementn
}
When the C++ compiler encounters a block, it treats the entire block as a single
statement. Thus, whenever the notation statement appears in a pattern for one of the
control forms, you can substitute for it either a single statement or a block. To
emphasize that they are statements as far as the compiler is concerned, blocks are
sometimes referred to as compound statements. In C++, the statements in any
block may be preceded by declarations of variables.
The statements in the interior of a block are usually indented relative to the
enclosing context. The compiler ignores the indentation, but the visual effect is
extremely helpful to the human reader, because it makes the structure of the
program jump out at you from the format of the page. Empirical research has
shown that indenting three or four spaces at each new level makes the program
structure easiest to see; the programs in this text use three spaces for each new level.
Indentation is critical to good programming, so you should strive to develop a
consistent indentation style in your programs.
The if statement
In writing a program, you will often want to check whether some condition applies
and use the result of that check to control the subsequent execution of the program.
This type of program control is called conditional execution. The easiest way to
express conditional execution in C++ is by using the if statement, which comes in
two forms:
if (condition) statement
if (condition) statement else statement
You use the first form of the if statement when your solution strategy calls for a set
of statements to be executed only if a particular Boolean condition is true. If the
condition is false, the statements that form the body of the if statement are
simply skipped. You use the second form of the if statement for situations in
which the program must choose between two independent sets of actions based on
the result of a test. This statement form is illustrated by the following code, which
reports whether an integer n is even or odd.
38 Overview of C++
if (n % 2 == 0) {
cout << "That number is even." << endl;
} else {
cout << "That number is odd." << endl;
}
As with any control statement, the statements controlled by the if statement can
be either a single statement or a block. Even if the body of a control form is a single
statement, you are free to enclose it in a block if you decide that doing so improves
the readability of your code. The programs in this book enclose the body of every
control statement in a block unless the entire statement—both the control form and
its body—is so short that it fits on a single line.
switch (e) {
case c1:
statements
break;
case c2:
statements
break;
. . . more case clauses . . .
default:
statements
break;
}
The expression e is called the control expression. When the program executes a
switch statement, it evaluates the control expression and compares it against the
values c1, c2, and so forth, each of which must be a constant. If one of the constants
matches the value of the control expression, the statements in the associated case
clause are executed. When the program reaches the break statement at the end of
the clause, the operations specified by that clause are complete, and the program
continues with the statement that follows the entire switch statement.
1.7 Statements 39
The default clause is used to specify what action occurs if none of the
constants match the value of the control expression. The default clause, however,
is optional. If none of the cases match and there is no default clause, the program
simply continues on with the next statement after the switch statement without
taking any action at all. To avoid the possibility that the program might ignore an
unexpected case, it is good programming practice to include a default clause in
every switch statement unless you are certain you have enumerated all the
possibilities.
The code pattern I’ve used to illustrate the syntax of the switch statement
deliberately suggests that break statements are required at the end of each clause.
In fact, C++ is defined so that if the break statement is missing, the program starts
executing statements from the next clause after it finishes the selected one. While
this design can be useful in some cases, it causes many more problems than it
solves. To reinforce the importance of remembering to exit at the end of each case
clause, the programs in this text include a break or return statement in each such
clause.
The one exception to this rule is that multiple case lines specifying different
constants can appear together, one after another, before the same statement group.
For example, a switch statement might include the following code:
case 1:
case 2:
statements
break;
which indicates that the specified statements should be executed if the select
expression is either 1 or 2. The C++ compiler treats this construction as two case
clauses, the first of which is empty. Because the empty clause contains no break
statement, a program that selects the first path simply continues on with the second
clause. From a conceptual point of view, however, you are better off if you think of
this construction as a single case clause representing two possibilities.
which converts a Direction value to a string. The default clause returns "???"
if the internal value of dir does not match any of the Direction constants.
[4] Sans doute Copernic qui termina vers 1530 son livre De orbium
cœlestium revolutionibus, imprimé, en 1543, à Nuremberg, avec une
dédicace au pape Paul III. Dès 1540, une lettre de son disciple Rheticus fit
connaître le nouveau système.
[6] Il semble qu'on retrouve ces tristes pensées dans le beau portrait de
Luther mort, qui se trouve dans la collection du libraire Zimmer à Heidelberg;
ce portrait exprime aussi la continuation d'un long effort.
[7] Nom d'un village près duquel Luther possédait une petite terre.
[11] Mélanchton fait remarquer que saint Augustin n'exprime pas cette
opinion dans ses écrits de controverse.
RENVOIS
DU TOME TROISIÈME.
Livre III.—1529-1546 1
er
Chap. 1 . 1529-1532. Les Turcs.—Danger de l'Allemagne.—
Augsbourg, Smalkalde.—Danger du protestantisme. 1
Chap. II. 1534-1536. Anabaptistes de Münster. 28
Chap. III. 1536-1545. Dernières années de la vie de Luther.
—Polygamie du landgrave de Hesse, etc. 56
Livre IV.—1530-1546. 71
Chap. 1er. Conversations de Luther.—La famille, la femme,
les enfans.—La nature. 71
Chap. II. La Bible.—Les Pères.—Les scolastiques.—Le pape.
Les conciles. 85
Chap. III. Des écoles et universités et des arts libéraux. 100
Chap. IV. Drames.—Musique.—Astrologie.—Imprimerie.—
Banque, etc. 114
Chap. V. De la prédication.—Style de Luther.—Il avoue la
violence de son caractère. 123
Livre V.—Chap. 1er. Mort du père de Luther, de sa fille, etc. 131
Chap. II. De l'équité, de la Loi.—Opposition du théologien et
du juriste. 138
Chap. III. La foi; la loi. 144
Chap. IV. Des novateurs.—Mystiques, etc. 152
Chap. V. Tentations.—Regrets et doutes des amis, de la
femme; doutes de Luther lui-même. 163
Chap. VI. Le diable.—Tentations. 168
Chap. VII. Maladies.—Désir de la mort et du jugement.—
Mort, 1546. 200
Additions et Éclaircissemens. 223
Notes. 352
Renvois. 353
Au lecteur.
Ce livre électronique reproduit intégralement le texte original. Les erreurs
signalées par l'auteur (voir Errata) ont été corrigées. Elles sont indiquées par
(Err.) Quelques erreurs typographiques ont également été corrigées; la liste
de ces corrections se trouve ci-dessous. La ponctuation a été tacitement
corrigée par endroits.
Les notes de bas de page ont été renumérotées de 1 à 11 et regroupées à
la fin du livre. Les «Additions et éclaircissemens» ont été numérotés de a1 à
a79. Les «Renvois» ont été numérotés de r1 à r225. Additions et renvois ont
été signalés dans le texte.
Corrections.
Pages 3, 353, 355: «Cochlœus» remplacé par «Cochlæus».
Page 28: «compagnonage» remplacé par «compagnonnage» (Le mystique
compagnonnage allemand).
Page 36: «dor» par «d'or» (trente et un chevaux couverts de draps d'or).
Page 37: «cent» par «cents» (près de quatre mille deux cents).
Page 75: «de de» par «de» (Ne vous scandalisez pas de me voir).
Page 139: «barette» par «barrette» (doit ôter sa barrette devant la
théologie).
Page 209: «rassassié» remplacé par «rassasié» (On est rassasié de la parole
de Dieu).
Page 222: «sufffire» par «suffire» (que nous ayons pu y suffire).
Page 258: «deux» par «d'eux» (Que l'un d'eux avait commis un meurtre).
Page 315: «pomptement» par «promptement» (il exécute promptement).
Page 339: «Brandbourg» par «Brandebourg» (récemment introduite dans le
Brandebourg).
Page 340: «tintamare» par «tintamarre» (avec chant et tintamarre).
Page 353 «RENVOIS DU TOME TROISIÈME»: il faut sans doute lire «RENVOIS
DU TOME DEUXIÈME».
Page 360 (renvoi nº 160): ajouté «_Ibid._»
Page 361 (renvoi nº 176): au lieu de «Il sera si mauvais» il faut sans doute
lire «Il fera si mauvais»; ajouté «_Ibid._»
Page 366 Table des matières: au lieu de «TROISIÈME VOLUME» et «TOME
TROISIÈME» il faut sans doute lire «DEUXIÈME VOLUME» et «TOME
DEUXIÈME».
*** END OF THE PROJECT GUTENBERG EBOOK MÉMOIRES DE
LUTHER ÉCRITS PAR LUI-MÊME, TOME II ***
1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside
the United States, check the laws of your country in addition to
the terms of this agreement before downloading, copying,
displaying, performing, distributing or creating derivative works
based on this work or any other Project Gutenberg™ work. The
Foundation makes no representations concerning the copyright
status of any work in any country other than the United States.
1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if
you provide access to or distribute copies of a Project
Gutenberg™ work in a format other than “Plain Vanilla ASCII” or
other format used in the official version posted on the official
Project Gutenberg™ website (www.gutenberg.org), you must,
at no additional cost, fee or expense to the user, provide a copy,
a means of exporting a copy, or a means of obtaining a copy
upon request, of the work in its original “Plain Vanilla ASCII” or
other form. Any alternate format must include the full Project
Gutenberg™ License as specified in paragraph 1.E.1.
• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”
• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.
1.F.
Most people start at our website which has the main PG search
facility: www.gutenberg.org.
ebookbell.com