0% found this document useful (0 votes)
18 views76 pages

Introducing C For Scientists Engineers and Mathematicians 2nd Edition Derek Capper Download

The document introduces the second edition of 'Introducing C for Scientists, Engineers and Mathematicians' by Derek Capper, which covers fundamental concepts of the C++ programming language. It includes various topics such as control structures, functions, pointers, arrays, and classes, aimed at helping professionals in scientific and engineering fields. The document also provides links to additional related ebooks and resources.

Uploaded by

joojomay
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views76 pages

Introducing C For Scientists Engineers and Mathematicians 2nd Edition Derek Capper Download

The document introduces the second edition of 'Introducing C for Scientists, Engineers and Mathematicians' by Derek Capper, which covers fundamental concepts of the C++ programming language. It includes various topics such as control structures, functions, pointers, arrays, and classes, aimed at helping professionals in scientific and engineering fields. The document also provides links to additional related ebooks and resources.

Uploaded by

joojomay
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 76

Introducing C For Scientists Engineers And

Mathematicians 2nd Edition Derek Capper download

https://ebookbell.com/product/introducing-c-for-scientists-
engineers-and-mathematicians-2nd-edition-derek-capper-38548008

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Introducing Philosophy For Canadians A Text With Integrative Readings


1st Edition Robert C Solomon

https://ebookbell.com/product/introducing-philosophy-for-canadians-a-
text-with-integrative-readings-1st-edition-robert-c-solomon-46248138

Introducing Functional Programming Using C Leveraging A New


Perspective For Oop Developers 1st Edition Vaskaran Sarcar

https://ebookbell.com/product/introducing-functional-programming-
using-c-leveraging-a-new-perspective-for-oop-developers-1st-edition-
vaskaran-sarcar-52166254

Introducing Functional Programming Using C Leveraging A New


Perspective For Oop Developers Vaskaran Sarcar

https://ebookbell.com/product/introducing-functional-programming-
using-c-leveraging-a-new-perspective-for-oop-developers-vaskaran-
sarcar-52181446

Introducing Qt 6 Learn To Build Fun Apps Games For Mobile Desktop In C


1st Ed Ben Coepp

https://ebookbell.com/product/introducing-qt-6-learn-to-build-fun-
apps-games-for-mobile-desktop-in-c-1st-ed-ben-coepp-36665958
Introducing Psychology For Nurses And Healthcare Professionals 2nd
Edition Dominic Upton

https://ebookbell.com/product/introducing-psychology-for-nurses-and-
healthcare-professionals-2nd-edition-dominic-upton-48467806

Introducing Pharmacology For Nursing Healthcare Roger Mcfadden

https://ebookbell.com/product/introducing-pharmacology-for-nursing-
healthcare-roger-mcfadden-2345084

Introducing Psychology For Nurses Healthcare Professionals Dominic


Upton

https://ebookbell.com/product/introducing-psychology-for-nurses-
healthcare-professionals-dominic-upton-2397962

Introducing Net For Apache Spark Distributed Processing For Massive


Datasets 1st Edition Ed Elliott

https://ebookbell.com/product/introducing-net-for-apache-spark-
distributed-processing-for-massive-datasets-1st-edition-ed-
elliott-24015384

Introducing English For Research Publication Purposes 1st Edition John


Flowerdew Pejman Habibie

https://ebookbell.com/product/introducing-english-for-research-
publication-purposes-1st-edition-john-flowerdew-pejman-
habibie-34809146
Introducing Engineers and Mathematicians
Springer-Verlag London Ltd.
Derek Capper

Introducing c++ for


Scientists, Engineers
and Mathematicians
Second Edition

i Springer
Derek Capper

British Library Cataloguing in Publication Data


Capper, D.M. (Derek M.)
Introducing C++ for Scientists, engineers and mathematicians. - 2nd ed.
1. C++ (Computer program language)
1. Title II. C++ for scientists, engineers and mathematicians
005.1'33
ISBN 978-1-85233-488-8

Library of Congress Cataloging-in-Publication Data


Capper, D.M. (Derek M.), 1947
Introducing C++ for scientists, engineers and mathematicians / Derek Capper.-2nd ed.
p.cm.
Rev. ed. of: The C++ programming language for scientists, engineers and
mathematicians. 1994.
Includes bibliographical references and index.
ISBN 978-1-85233-488-8 (alk. paper)
1. C++ (Computer program language) 1. Capper, D.M. (Derek M.). 1947-. C++
programming language for scientists, engineers and mathematicians. Il. Title
QA76.73.CI53 C36 2001
005.13'3-dc21
2001034207

Apart from any fair dealing for the purposes of research or private study, or criticism or review, as permitted under
the Copyright, Designs and Patents Act 1988, this publicat ion may only be reproduced, stored or transmitted, in any
form or by any means, with the prior permis sion in writing of the publishers, or in the case of reprographic
reproduction in accordance with the terms of licences issued by the Copyright Licensing Agency. Enquiries concerning
reproduction outside those terms should be sent to the publishers.

ISBN 978-1-85233-488-8 ISBN 978-1-4471-0267-0 (eBook)


DOI 10.1007/978-1-4471-0267-0
http://www.springer.co.uk

© Springer-Verlag London 2001


Originally published by Springer-Verlag London Berlin Heidelberg in 2001

First published 1994


Second edition 2001

AII trademarks found in this book are acknowledged. This acknowledgement includes:
Linus Torvalds: Linux
Microsoft Corporation: MS-DOS, Windows
XlOpen Company Limited: UNIX

The use of registered names, trademarks etc. in this publication does not imply, even in the absence of a specific
statement, that such names are exempt from the relevant laws and regulations and therefore free for general use.

The publisher makes no representation, express or implied, with regard to the accuracy of the information contained
in this book and cannot accept any legal responsibility or liability for any errors or omissions that may be made.

Typeset by the author using U\'!EX


34/3830-543210 Printed on acid-free paper SPIN 10834582
Contents

Preface to the Second Edition xiii

Preface to the First Edition xiii

Structure of this Book xiv

Acknowledgements xvi

1 Introduction 1
1.1 Getting Started . . . . . . . . 1
1.2 Solving a Quadratic Equation 3
1.3 An Object-oriented Example 4
1.4 Why Object-oriented? 6
1.5 Summary. 7
1. 6 Exercises........ 7

2 The Lexical Basis of C++ 9


2.1 Characters and Tokens 9
2.2 Comments and White Space 10
2.3 Identifiers 11
2.4 Keywords . . . . . . . . . 12
2.5 Constants . . . . . . . . 13
2.5.1 Integer Constants 13
2.5.2 Boolean Constants. 14
2.5.3 Floating Point Constants 14
2.5.4 Character Constants. 14
2.5.5 String Constants. 15
2.6 Operators . . . . . 16
2.7 Programming Style 16
2.8 Summary. 17
2.9 Exercises . . . . . . 18

3 Fundamental Types and Basic Operators 19


3.1 Integral Data Types . . . . . 20
3.1.1 Type int . . . . . . . 20
3.1.2 Integer Multiplication 23

v
vi CONTENTS

3.l.3 Integer Division . . . . . . . . . . . . . . 23


3.l.4 Integer Modulus or Remainder Operator 23
3.l.5 Increment and Decrement Operators . . . 25
3.l.6 Associativity and Precedence of Integer Operators 26
3.l.7 Long Integers . . . 28
3.l.8 Short Integers .. 29
3.l.9 Unsigned Integers 29
3.l.10 Booleans . . . . . 30
3.l.11 Character Types. 31
3.2 Floating Point Data Types 32
3.2.1 Type double . . . . 32
3.2.2 Type float . . . . . 34
3.2.3 Type long double 34
3.3 Changing Types . . . . . . 35
3.3.1 Type Promotion and Conversion 35
3.3.2 Casts . . . . . . . . . 36
3.4 Some Basic Operations . . . 36
3.4.1 The sizeof Operator 37
3.4.2 Initialization . . . . . 38
3.4.3 Assignment Operators . 39
3.5 const . . . 40
3.6 typedef . 41
3.7 Summary. 42
3.8 Exercises . 42

4 Control Structure 45
4.1 Relational Operators 45
4.2 Logical Operators 47
4.3 Equal and Not Equal Operators 48
4.4 Blocks and Scope 50
4.5 Branch Statements 52
4.5.1 if Statement . 52
4.5.2 i f else Statement 54
4.5.3 switch Statement 57
4.6 Iteration Statements 59
4.6.1 while Statement . 60
4.6.2 f or Statement 61
4.6.3 do Statement . 64
4.7 break and continue Statements. 66
4.8 goto Statement 67
4.9 Comma Operator 69
4.10 Null Statement 70
4.11 Conditional Expression Operator 71
4.12 Order of Evaluation of Operands. 71
4.13 The Preprocessor 72
4.13.1 include Directive 72
4.13.2 define Directive. 74
CONTENTS vii

4.13.3 Conditional Compilation 75


4.14 Enumerations 77
4.15 Summary. 79
4.16 Exercises 81

5 Functions 85
5.1 Introducing Functions . . . . . . . . . . 85
5.l.1 Defining and Calling Functions. 85
5.l.2 Return Type . . . . . . . . . . . 88
5.l.3 Function Declarations . . . . . . 90
5.l.4 Functions Cannot Declare Functions. 90
5.l.5 Unused Arguments 92
5.l.6 Default Arguments 93
5.l.7 Ignoring the Return Value 95
5.2 Recursion.... . . . 95
5.3 Inline Functions . . . 96
5.4 More on Scope Rules 97
5.5 Storage Class static 99
5.6 Overloading Function Names. 101
5.6.1 Ambiguity Resolution 103
5.7 Function main () . 104
5.8 Standard Library .. 104
5.9 Using Functions . . . 107
5.9.1 A Benchmark 107
5.9.2 Root Finding by Bisection 109
5.10 Summary. 112
5.11 Exercises . . . . 114

6 Pointers and Arrays 119


6.1 Memory, Addressing and Pointers . . . . . . 119
6.l.1 Address-of Operator . . . . . . . . . . 120
6.l.2 Dereferencing or Indirection Operator 120
6.l.3 Pointers....... . . . . . . . . 121
6.l.4 Pointers Do Not Declare Memory 125
6.l.5 Null Pointer . . . . . . . . . . . . 126
6.2 One-dimensional Arrays. . . . . . . . . . 127
6.2.1 Pointers and One-dimensional Arrays 129
6.3 Type void* . . . . . . . . 135
6.4 Pointer Conversions . . . . . . . . . . . . . . 135
6.5 Multi-dimensional Arrays. . . . . . . . . .. 136
6.5.1 Pointers and Multi-dimensional Arrays 138
6.6 Initializing Arrays 140
6.7 Size of Arrays . . . . . . . 141
6.8 Arrays of Pointers . . . . . 142
6.9 Using Pointers and Arrays 144
6.9.1 Fitting Data to a Straight Line. 145
6.9.2 Ragged Arrays 147
6.10 Summary. 148
viii CONTENTS

6.ll Exercises . . . . . . . . . 151

7 Further Pointer Techniques 153


7.1 Strings . . . . . . . . . . . . . . . . . . 153
7.2 Pointers as FUnction Arguments . . . . 157
7.3 Passing Arrays as Function Arguments 158
7.3.1 One-dimensional Arrays. 158
7.3.2 Multi-dimensional Arrays 160
7.4 Arguments to main 0 . . . . . . 163
7.5 Pointers to FUnctions . . . . . . 166
7.6 Dynamic Memory Management 171
7.6.1 Allocating Memory . . . 172
7.6.2 Deallocating Memory .. 177
7.7 Pass by Reference and Reference Variables 179
7.7.1 Reference Arguments .. 179
7.7.2 Reference Return Values .. 182
7.7.3 Reference Variables . . . . . 183
7.8 Using Pointers, Arrays and Strings 184
7.8.1 Matrix Addition .. 185
7.8.2 An Alphabetic Sort 189
7.9 Summary. 193
7.10 Exercises 195

8 Classes 197
8.1 Declaring Classes 197
8.2 Class Access Specifiers 199
8.3 Accessing Members .. 199
8.4 Assigning Objects .. . 201
8.5 FUnctions and Classes . 202
8.6 Data Hiding . . . . . 206
8.7 Returning an Object 209
8.8 Reference Arguments 2ll
8.9 Pointers to Members 2ll
8.10 Pointer-to-Member Operators 213
8.ll Scope and Data Protection . 217
8.12 Static Members . . . . . . . . 219
8.12.1 Static Data Members 219
8.12.2 Static Member FUnctions 221
8.13 Constructor Functions . . . . . 223
8.14 Accessing const Class Objects. 229
8.15 Friend Functions . . . . . . . 231
8.16 Program Structure and Style 233
8.16.1 Separate Compilation 233
8.16.2 Header Files 235
8.17 Using Classes 236
8.18 Summary. 241
8.19 Exercises . .. 244
CONTENTS ix

9 Operator Overloading 245


9.1 Introducing Overloaded Operators . . . . . . . 245
9.1.1 Overloading the Assignment Operator. 246
9.1.2 The this Pointer . . . . . . . . . . . . 247
9.1.3 Overloading the Addition Operator .. 249
9.1.4 Overloading the Unary Minus Operator 251
9.2 User-defined Conversions . . . . . . 253
9.2.1 Conversion by Constructors. 254
9.2.2 Conversion Functions 256
9.2.3 Implicit Conversions. 260
9.3 Operator Function Calls .. 262
9.3.1 Binary Operators .. 263
9.3.2 Prefix Unary Operators 264
9.3.3 Postfix Unary Operators 267
9.4 Some Special Binary Operators 269
9.4.1 Overloading the Subscripting Operator 269
9.4.2 Overloading the Function Call Operator . 271
9.5 Defining Overloaded Operators. 273
9.6 Using Overloaded Operators 274
9.6.1 Complex Arithmetic. 274
9.6.2 Strings 279
9.7 Summary. 284
9.8 Exercises . . . 286

10 Constructors and Destructors 287


10.1 More on Constructor Functions 288
10.1.1 Dynamic Memory Management 288
10.1.2 Assignment and Initialization .. 290
10.1.3 Member Objects with Constructors 292
10.2 Destructor Functions . . . . . . . . 293
10.3 Using Constructors and Destructors 295
10.3.1 Singly Linked Lists 295
10.3.2 Doubly Linked Lists 300
10.4 Summary. 305
10.5 Exercises... . . . . . . . 305

11 Bitwise Operations 307


11.1 Bitwise Operators . . . . . . 307
11.1.1 Bitwise Complement. 308
11.1.2 Bitwise AND . . . . . 308
11.1.3 Bitwise Exclusive OR 308
11.1.4 Bitwise Inclusive OR 309
11.1.5 Shift Operators . . . 309
11.1.6 Bitwise Assignment Operators 310
11.2 Bit-fields . . . . . . . . . 310
11.3 Unions . . . . . . . . . . 312
11.4 Using Bitwise Operators 315
11.4.1 A Bit Array Class 315
x CONTENTS

11.4.2 The Sieve of Eratosthenes . . . . . . . . . . . 320


11.4.3 Bit Representation of Integral Types . . . . . 323
11.4.4 Bit Representation of Floating Point Types. 325
11.5 Summary. 328
11.6 Exercises... 329

12 Single Inheritance 331


12.1 Derived Classes 331
12.2 virtual Functions 336
12.3 Abstract Classes .. 340
12.4 Class Hierarchies . 346
12.5 Constructors and Destructors 352
12.6 Member Access and Inheritance 355
12.6.1 Access Specifiers . . . . . 355
12.6.2 Friendship and Derivation. 357
12.7 Using Single Inheritance . . . . . 358
12.7.1 A Bounds Checked Array Class 358
12.7.2 A Menu Class 363
12.8 Summary. 371
12.9 Exercises..... 373

13 Multiple Inheritance 375


13.1 Derived Classes . 375
13.2 Virtual Base Classes . . . . . . 381
13.3 Constructors and Destructors 385
13.4 Member Access Ambiguities 386
13.5 Using Multiple Inheritance 389
13.6 Summary. 398
13.7 Exercises 399

14 Namespaces 401
14.1 N arne Clashes ......... 401
14.2 Creating a Namespace . . . . . 403
14.3 Accessing Namespace Members 404
14.4 More on Creating Namespaces 405
14.5 Namespace Aliases .. 406
14.6 The using Directive .. 407
14.7 The using Declaration 409
14.8 The Standard Library. 411
14.9 Unnamed Names paces 412
14.10 Using Namespaces . 413
14.11 Summary. 417
14.12 Exercises . . . . . . 419
CONTENTS xi

15 Exception Handling 421


15.1 Errors . . . . . . . . . . . . . . . . . 421
15.2 Introducing throw, try and catch. 423
15.3 Throwing a Fundamental Type . . . 426
15.4 Extracting Information from a catch 427
15.5 Catching Everything .. 430
15.6 Derived Error Classes .. 432
15.7 Exception Specifications 434
15.8 Uncaught Exceptions .. 436
15.9 Dynamic Memory Allocation. 436
15.10 Using Exception Handling 438
15.11 Summary. 444
15.12 Exercises 448

16 Templates 449
16.1 Function Templates 449
16.2 Class Templates .. 453
16.3 Static Members .. 456
16.4 Class Templates and Functions. 457
16.5 Function Template Arguments 459
16.6 Template Parameters 459
16.7 Templates and Friends . . . . 460
16.8 Specialized Templates . . . . . 462
16.9 Member Function Specialization 465
16.10 Program Structure 466
16.11 Using Templates. 467
16.12 Summary. 469
16.13 Exercises . . . 471

17 Standard Library 473


17.1 Introduction ..... . 473
17.2 Library Categories . . . . 474
17.2.1 Language Support 475
17.2.2 Diagnostics . . . 475
17.2.3 General Utilities 476
17.2.4 Strings . . . 476
17.2.5 Localization 477
17.2.6 Containers 477
17.2.7 Iterators 478
17.2.8 Algorithms 478
17.2.9 Numerics 479
17.3 Using the Standard Library 479
17.3.1 Complex Arithmetic. 479
17.3.2 Boolean Arrays. 482
17.4 Summary. 486
17.5 Exercises.... . . . . 486
Xll CONTENTS

18 Input and Output 489


18.1 Introduction . . . . . . . . 489
18.2 Input and Output Classes 489
18.3 Output . . . . . . . . . . . 492
18.3.1 Unformatted Output 493
18.4 Input . . . . . . . . . . . . . 494
18.4.1 Unformatted Input . 495
18.5 Flags, Manipulators and Formatting. 500
18.6 File Input and Output 502
18.7 Assigning Streams. 506
18.8 Stream Condition . . . 507
18.9 User-defined Types .. 509
18.10 Using Input and Output 510
18.11 Summary. 514
18.12 Exercises . . . . . . . . . 517

Appendix-A The ASCII Character Codes 519

Appendix-B Operators 521

Appendix-C Differences between C and C++ 525

Bibliography 529

Index 531
Preface to the Second Edition

Since the first edition of C++ for Scientists, Engineers and Mathematicians, many
things have changed. Perhaps the most important is that the ANSI C++ Standard
was approved in 1998. The first edition of this book was incompatible with some parts
of the Standard and every effort has been made to rectify this. The facilities offered
by the C++ language have also grown enormously since the first edition. It is not just
the language itself that has grown, but the ANSI Standard also defines an extensive
range of library facilities.
I have also made two changes in emphasis since the first edition. Firstly, since there
is so much important material to cover, some less important features of the language
have been removed. The second change is to try to illustrate the language by means
of complete programs, rather than code fragments. Hopefully, this will give you more
confidence in applying new techniques.
Finally, although C++ is a bigger language than it was, it is even more fun to use.
So, enjoy it!

Preface to the First Edition


Computers are being used to solve problems of ever increasing complexity in science
and engineering. Although some problems can be solved by means of "off the shelf"
packages, many applications would benefit greatly from using a sophisticated modern
programming language. Without such a language, it is difficult to develop and main-
tain complex software and the difficulties are considerably worse for multi-processor
systems. Of the many possible languages, C is being increasingly used in scientific ap-
plications, but it has some dangers and disadvantages owing to its system programming
origins. These drawbacks have largely been overcome by the introduction of C++, an
object-oriented version of C, which was developed at AT & T Bell Laboratories by
Bjarne Stroustrup.
C++ has proved to be an enormously popular language, but most of the available
books assume a prior knowledge of C. Unfortunately, most books on C (in common
with those on C++) are not specifically intended for scientists or engineers and, for
instance, often use manipulation of character strings as the basis for examples. To the

xiii
xiv STRUCTURE OF THIS BOOK

scientist struggling to solve a non-linear differential equation, rather than writing a


text editor, such examples may not be very illuminating. C programmers also seem to
revel in writing very terse code, which can be difficult for the non-expert to penetrate.
This book is specifically intended for scientists, engineers and mathematicians who
want to learn C++ from scratch by means of examples and detailed applications, rather
than a formal language definition. The examples used are deliberately numerical in
character and many other topics of possible interest (such as databases, computer
algebra and graph algorithms) are left untouched. For someone with little or no pro-
gramming experience there is much to be gained by learning C++ rather than C.
Instead of becoming a good C programmer and then converting to an object-oriented
language, the reader can progressively use those aspects of C++ that are both relevant
and accessible. For instance inline functions instead of macros, together with function
name overloading and data hiding by means of classes, are all useful programming tech-
niques that can be introduced at an early stage. Another advantage is that in many
ways C++ is a safer language than C and encourages better programming practices.
No prior knowledge of any programming language is assumed and the approach
is to learn by means of relevant examples. The mathematical techniques involved in
these examples have been kept deliberately simple and are fundamental to any serious
numerical application of computers. For any reader not familiar with a particular tech-
nique, the explanations given in the text should be sufficient and additional background
material can be found in the bibliography. This bibliography is annotated to provide
the reader with a guide to parallel reading whilst studying this book and to suggest
pathways through the literature for more advanced study. In particular, we do not
dwell on those aspects of C++ that only provide backward compatibility with C. Such
features of the language may well be important to readers wishing to integrate existing
C code into a C++ program and help can be obtained from the bibliography. Since our
approach is to learn by example, rather than by formal definition, the bibliography (in
particular [10] and [1]) should also be consulted if a precise definition of the language
is required.

Structure of this Book

It is very unlikely that any application will need every C++ feature described in this
book. However, with the exception of Chapter 18, the order in which material is pre-
sented means that you can progress as far as necessary in order to meet your particular
needs, without working through the entire book. Even if a fairly complete under-
standing of C++ is required, it is worth studying the language in deliberate stages,
interspersed with projects from your own field of interest. The following stages are
suggested:

1. Chapters 1 to 5 introduce the basics of C++, including control structures and


functions. These features are common to most languages that have found nu-
STRUCTURE OF THIS BOOK xv

merical application and are essential for writing any significant program. Most
applications would also need an understanding of Chapter 6, which introduces
arrays. This stage is roughly equivalent to what you would have in a language
such as FORTRAN. Most C++ programs make considerable use of pointers and,
although this topic is introduced in Chapter 6, it is developed further in the
following chapter. Here you will also find a description of strings and dynamic
memory management.

2. Classes, objects, data hiding and member functions are introduced in Chapter 8,
and Chapters 9 and 10 are devoted to operator overloading, constructors and
destructors. Although by themselves such techniques are not sufficient to consti-
tute object-oriented programming, they should enable you to write safer code for
fairly large applications. After working through these chapters you should also
be able to use C++ class libraries, such as matrix algebra, complex arithmetic,
strings etc. However, you will not be able to use inheritance to extend existing
classes to meet any special needs of your own specific applications.

3. Bitwise operations are described in Chapter 11. Such operations may not be
central to your interests and you could decide to omit this chapter. However,
an understanding of how numbers are stored in memory is very useful and you
would miss the neat application to the Sieve of Eratosthenes.

4. Chapter 12 describes single inheritance. At this stage you can truly claim to be
doing object-oriented programming with the ability to construct your own classes
and to extend existing classes.

5. Multiple inheritance is introduced in Chapter 13. Although many experts would


claim that multiple inheritance is an essential part of object-oriented program-
ming, you will probably be developing quite large applications before using such
techniques.

6. Chapters 14, 16 and 15 are about namespaces, templates and exception handling.
Namespaces are useful for avoiding potential name clashes in large projects and
templates provide a way of reusing code. Exception handling provides techniques
for dealing with errors, and is particularly important for errors that are detected
by library facilities. All three chapters are prerequisites for the penultimate
chapter.

7. The ANSI C++ Standard defines an important and extensive set of library fa-
cilities. Chapter 17 provides an overview of this Standard Library. Chapter 18
describes input and output, which is actually part of the Standard Library. This
means that many details of input and output are not covered until this final chap-
ter. For example, file I/O is not introduced until this stage, although you may
have applications that lead you to consult this chapter before working through
the preceding chapters. The reason for leaving details of input and output until
Chapter 18 is that it involves classes, operator overloading, constructors, destruc-
tors, inheritance, templates, exception handling etc. In fact the I/O facilities
offered by the Standard Library employ just about every idea of the preceeding
chapters. However, don't despair! If you do need facilities such as file I/O at an
XVI ACKNOWLEDGEMENTS

early stage, then you should be able to extract the necessary information without
working through the entire book!

If used as an undergraduate text, it is likely that the material contained in all


eighteen chapters would be too much for a single course of lectures. Rather it is
envisaged that Chapters 1 to 9 would be used in a first course, with the following
chapters being suitable for a subsequent course.
This book introduces some advanced features of C++ that could be omitted if a
complete knowledge of the language is not required. The following techniques are used
to identify such features:

1. Items that fit naturally into a particular chapter, but could reasonably be post-
poned until later, are marked by a single dagger (t). You would probably have to
return to such sections in order to understand later chapters and you may have to
postpone attempting some of the exercises. A typical example is Section 4.13.3
on Conditional Compilation; you will probably need to use this information some-
time, but skipping the section on a first reading will not do any harm.

2. There are two kinds of section which are sufficiently self-contained that they
can be omitted altogether without any loss of continuity and these are marked
by double daggers (tt). Some sections are only intended for reference. Other
sections will only be of importance to particular applications; for example, bitwise
operations (Chapter 11) could be crucial for a number theory application but of
no relevance to solving a differential equation.

Lack of space prevents the inclusion of a chapter on object-oriented design in the


context of numerical applications. However, this is a topic which deserves an entire
book to itself and some recompense may be obtained by consulting the bibliography
([2], [7J and [10]).

Acknowledgements

I would like to thank Helen Arthan for conscientiously working through the various
drafts of the first edition of this book and Mark Burton for removing many technical
errors. Peter Dew and Ian Robson both provided inspiration for some of the applica-
tions.
Above all I wish to thank my wife, Janet, for her constant support, without which
neither edition of this book would have been completed.
Chapter 1

Introduction

1.1 Getting Started


Probably the most frustrating stage in learning any language is getting started. Our
first steps need to be modest and we start by simply sending a one-line message to the
output device. Very few assumptions are made in this book, but it is assumed that
you have access to a C++ compiler and that you know how to use an editor.1 Suppose
the following lines of code are entered into a file by means of an editor:

II A simple C++ program:

#include <iostream>
using namespace std;

int mainO
{
cout « "This is our first C++ program.\n";
return(O);
}

This complete C++ program must go through a two-stage process before it can be
run. First of all the code needs to be compiled in order to generate instructions that
can be understood by our computer and then this collection of instructions must be
linked with libraries. 2 The exact way in which the compilation and linking is carried
out will depend on the details of the particular system. Typically, if this first program
is in the file example. cxx, then both stages may be accomplished by entering:

g++ -0 example example.cxx


1 Word processors put undesirable characters in their output files. However, those that can be
persuaded to output plain text files could also be used to edit C++ code. Alternatively, you may
have access to an IDE (Integrated Development Environment) that has an integrated editor and C++
compiler.
2 A library consists of a collection of compiled code that performs tasks that are not intrinsic to the
language. Typical examples are input, output and the mathematical functions (square root, logarithm
etc.).

1
D. Capper, Introducing C++ for Scientists, Engineers and Mathematicians
© Springer-Verlag London 2001
2 CHAPTER 1. INTRODUCTION

This command is consistent with the GNU C++ compiler running under Linux. 3 How-
ever, it may be conventional on your system to use a different extension for source code
(such as . cc, . cpp, . C or . c++) and the compile and link command may be different
(perhaps CC or gxx). You may also have to use <iostream.h> in place of <iostream>.
The -0 example part of the compile and link command results in the executable code
being placed in a file called example. You should then be able to execute this file by
entering the command:

example

If you omit -0 example from the compile and link command, then the GNU compiler
will put the executable code in the file a. out. However, with other compilers the file
in which the executable code is placed may be different; for example, on an MS-DOS
or Microsoft Windows system it may be example. exe.
If you have overcome all of the system-dependent hurdles, the following output
should appear:

This is our first C++ program.

The lines of code that produce this output require a few words of explanation.
The first line is a comment since any code following / / on a line is ignored. A larger
program would normally be introduced by a more significant comment. The third
non-blank line is the start of a function definition. Every complete C++ program
must contain a function called main and in our example, main is the only function.
The function name is preceded by the type specifier, int, since main should return
an integer. Parentheses, (), follow the name and are used to indicate that main is a
function. In some circumstances these parentheses may contain variables, known as
arguments.
The function, main () , contains two statements; the end of each statement is denoted
by a semicolon, sometimes known as a statement terminator. The first statement
outputs a message and the second statement effectively returns control to the operating
system. The standard output stream (usually the screen) is known as cout and the «
operator is used to send a string of characters to this stream, the group of characters
between the double quotes, " ", being known as a string. In our example, the string
ends with \n, which is used to denote a new line. This technique of sending character
strings to the output stream is not strictly part of the C++ language, but is part
of a library and is one of many standard functions that are available with any C++
compiler.
Since our program is compiled before it is linked to code for the output stream, we
need to supply information about the interface to couto This information is contained
in the file, iostream, which is made available to the compiler by the instruction:

#include <iostream>

The consequence of this instruction is that the iostream file is copied (that is included)
at this point. Files such as <iostream> are usually known as header files and are
described in more detail in Section 4.13.1. The < > notation is not part of the file
3This is the environment that was used to test the code given in this book, although the code
should work with little modification in other environments .
1.2. SOLVING A QUADRATIC EQUATION 3

name, but rather an indication that the file exists in a special place known to the
compiler.
The statement:

using namespace std;


makes certain names that belong to what is known as the Standard Library visible to
the program. The Standard Library is introduced in Chapter 17 and namespaces are
described in Chapter 14. Until Section 14.8, the above statement will appear in every
file that includes header files with the < > notation. In Section 14.8 we explain how to
avoid using the statement.

1.2 Solving a Quadratic Equation


No doubt our interests are more numerical than simply outputting lines of text, so our
second example consists of solving a quadratic equation:

ax2 + bx + c = 0

The solutions are, of course, given by:

-b± Vb 2 - 4ac
x=
2a
which can be implemented by the following (not very robust) program:

II Solves the quadratic equation:


II a * x * x + b * x + C = 0

#include <iostream>
#include <cmath> II For sqrt() function.
using namespace std;

int mainO
{
double rootl, root2, a, b, c, root;

cout « "Enter the coefficients a, b, c: ";


cin » a » b » c;
root = sqrt(b * b - 4.0 * a * c);
rootl = 0.5 * (root - b) I a;
root2 = - 0.5 * (root + b) I a;
cout « "The solutions are " « rootl « " and " « root2 «

return(O);
}

This program introduces floating point variables, which can store numbers that
include a decimal point, such a8 0.5. Notice that we use 0.5 in the above code, rather
4 CHAPTER 1. INTRODUCTION

than divide by 2.0, since multiplication is usually faster then division. The variables
root 1, root2, a, band c are defined to be floating point numbers by virtue of the type
specifier, double.
The program first uses the cout stream to send text to the output device, instructing
the user to input three coefficients. Values for a, b, and c are read from the input
stream, cin, which is usually the keyboard. For example, you could try typing:

1 -3 2

and then hit the enter key. Having obtained the values for a, b, and c, the code makes
use of the assignment, =, multiplication, *, addition, +, and subtraction, -, operators
in self-evident ways.
In general, solving a quadratic equation involves finding the square root of a number.
This is achieved by invoking the sqrt 0 function,4 which is defined for us in a system-
supplied mathematics library. Since our program is first compiled and then linked with
compiled code for the libraries, we must also include the header file, <cmath>, which
contains a function declaration for the sqrt 0 function, specifying the argument and
return types (in this case double). Notice that we really do mean <cmath>, rather
than <math>, since the sqrtO function was originally part of the C, rather than C++,
libraries. 5
On some systems it may be necessary to specify that this example requires the
mathematics library for linking. A typical form of the compile and link command in
such cases is:

g++ -0 example example.cxx -1m

but you may need to consult the compiler reference manual for your particular system.

1.3 An Object-oriented Example


The techniques illustrated by our examples so far have not differed much from other
languages, such as FORTRAN, BASIC or Pascal. Now consider (but don't try to
compile) the following program, which multiplies two matrices and lists the result:

II Program to test matrix multiplication:

#include "matrix.h"
using namespace std;

int maine)
{
int i, j;
matrix A(6, 4), B(4, 6), C(6, 6);
4Within the text we write a function with an empty pair of parentheses following the name. This
is to emphasize that we really do mean a function, but does not necessarily imply that the function
takes no arguments. Within a segment of code, any necessary arguments are, of course, included.
5C++ is an extension of C, a language which was invented by Kernighan and Ritchie [5] and then
adopted by ANSI (the American National Standards Institute). C++ has also been adopted by an
ANSI committee. (See [1].)
1.3. AN OBJECT-ORIENTED EXAMPLE 5

II Assign some numbers to the elements of A:


for (i = 1; i <= 6; ++i)
for (j = 1; j <= 4; ++j)
A(i,j)=i*j;

II Assign some numbers to the elements of B:


for (i = 1; i <= 4; ++i)
for (j = 1; j <= 6; ++j)
B(i,j)=i*j;

II Multiply A and B:
C = A * B;

II Output the result:


Gout « C;

return(O);
}

This program uses some features of C++ to perform operations on matrices. The
statement:

matrix A(6, 4), B(4, 6), C(6, 6);

defines matrices, A, B, C, which are of order 6 x 4, 4 x 6 and 6 x 6 respectively. The


important point to notice about the next seven lines of code is that A(i, j) and
B(i, j) are used to access the ij elements of the matrices A and B. Notice that the
included file matrix. h has a . h extension and also double quotes are used rather than
the < > notation. This is the convention when such files are not provided by the system
and is covered in more detail in Section 4.13.l.
The program first assigns integers to the elements of two non-square matrices. The
statement that then multiplies these two matrices is wonderfully simple:

C = A * B;

Notice how the code closely parallels the mathematics and is not obscured by function
calls. Moreover, if we make a mistake and write:

C = B * A;
which incorrectly attempts to assign a 4 x 4 matrix to a 6 x 6 matrix, then an error
message results.
Finally, the statement:

Gout « C;

is all that is required to list the matrix, C:


6 CHAPTER 1. INTRODUCTION

30 60 90 120 150 180

60 120 180 240 300 360

90 180 270 360 450 540

120 240 360 480 600 720

150 300 450 600 750 900

180 360 540 720 900 1080

Matrices are not part of the C++ language, but are an example of a user-defined
type, or class, which can be tailored to meet the exact needs of the application. 6 For
instance, some applications may be restricted to real matrix elements, whilst others may
be complex. In some circumstances bounds-checking may be an intolerable overhead,
whereas in others it may be essential. An application may even require that matrix
elements are themselves matrices. We will learn how to construct such classes. We will
also learn how to build on existing classes in order to create new classes, thus enabling
us to reuse software without understanding its detailed design.
The three matrices, A, Band C, are instances of the matrix class and are known
as objects. This example only skims the surface of object-oriented techniques, but
the essential idea is that a matrix is considered as an entity on which we perform
operations. A matrix object encapsulates details of how the data is stored, the value
of each element, the numbers of rows and columns, etc. Moreover, the matrix class
also shields the application programmer from details of how matrix operations, such
as multiplication, are implemented.

1.4 Why Object-oriented?


Solving realistic problems can require programs of ten or even a hundred thousand
lines. Such programs may be in use for many years and have been written by many
different programmers. Three key requirements are that programs are maintainable,
reusable and efficient.
A program must be maintainable because it may need modifying when hardware,
software or requirements change, or when errors in the code are inevitably discov-
ered. Developers of a program are frequently not involved in maintenance and, in any
case, the changes may be made long after the program was written. Throughout this
book you will therefore come across techniques that encourage maintainability, such as
readability, modularity, type-safe, self-documenting etc. These techniques are in turn
facilitated by object-oriented programming.
The code for a complicated application may involve many years of effort, so it
makes sense to be able to reuse as much of this work as possible. Functions can
aid re-usability to a limited extent; instead of implementing a cosine every time it is
6The phrase "user-defined" refers to a user of the C++ language as distinct from a user of a
program. Unfortunately, this potentially confusing terminology is well-entrenched in the literature.
1.5. SUMMARY 7

required, we can use a function. But a function to perform other operations may be
less straightforward. For instance, a function to invert a matrix needs information on
how the matrix is stored, its size and type. It would be much easier to reuse a matrix
inversion function if it simply operated on matrices as objects, which encapsulated
details of storage, size etc. Also, rather than simply reusing the matrix class, we may
want to modify it (perhaps to introduce bounds-checking) and ideally we should be able
to make changes without tampering with the original code. Object-oriented techniques
enable us to do all of these things.
Scientists and engineers are often working at the leading edge of what is computa-
tionally possible and are also well aware that inefficiency costs money. It might seem
that efficiency is incompatible with the requirements of maintainable and reusable
code. It is also true that object-oriented techniques usually introduce a slight run-time
overhead when compared with traditional methods. However, the key to efficiency is
identifying the appropriate objects. For example, if an application manipulates matri-
ces, then it should be written in terms of matrix objects, rather than matrix elements.
The details of matrix multiplication, addition etc. are then hidden from the application
programmer. Moreover, since the details are hidden, the implementation can be made
as efficient as possible. Such increases in efficiency far outweigh any run-time overhead
due to using object-oriented techniques.

1.5 Summary
• Every program must have one (and only one) function called main () .

• Compiling and linking a program is system dependent. In this book we use the
GNU C++ compiler and the command line

g++ -0 example example.cxx

gives example as the executable file. Using

g++ example.cxx

gives a. out as the executable file.

• cout « x sends the value of x to the output stream.

• cin » i reads the value of i from the input stream.

• The object-oriented features of C++ enable us to write reusable code in a way


that is natural for the particular application.

1.6 Exercises
1. Our program to solve a quadratic equation is not very robust. Try to make the
program fail in as many different ways as possible. What would you like to do to
improve the program? (We haven't covered the techniques required to actually
carry out the necessary improvements yet.)
8 CHAPTER 1. INTRODUCTION

2. Using the quadratic equation program as a guide, write a short program that
reads a, band c from the keyboard and lists the results for a+b, b*c and a/c.
Again, you should be able to input data that causes your program to fail.
Chapter 2

The Lexical Basis of C++

The most basic study of any language is lexical; without knowing the rules for con-
structing words, we cannot begin to write books, or even to construct a single sentence.
Communication is impossible. Likewise, before we can write a meaningful C++ pro-
gram, we must learn the rules for constructing "words", or more correctly tokens.

2.1 Characters and Tokens

A C++ program consists of one or more files, which contain a series of characters. The
details of how characters are represented internally are dependent on the C++ compiler,
but one byte per character is normal and one of the most popular representations, the
ASCII character set, is given in Appendix A.I The allowed characters are shown in
Table 2.1. A compiler resolves (or parses) the C++ program into a series of tokens.
There are five types of token: identifiers, keywords, constants, operators and other
separators.

upper case letters: ABCD ... XYZ


lower case letters: abcd ... xyz
digits: 0123456789
special characters: ! " %- & * ( ) [ ] { }- - +
1\< , > . ? / - # :
non printing characters: blank, carriage return,
new line etc.

Table 2.1: Permissible characters.

1 A byte is the smallest addressable element of memory and is usually eight bits. Indeed, throughout
this book a byte is assumed to be synonymous with eight bits. A bit is the smallest element of memory
and can only take the values 0 and 1. Bits and bytes are considered in more detail in Chapter 11.

9
D. Capper, Introducing C++ for Scientists, Engineers and Mathematicians
© Springer-Verlag London 2001
10 CHAPTER 2. THE LEXICAL BASIS OF C++

2.2 Comments and White Space


Comments are an essential feature of good programming practice. In C++ there are
two ways of denoting comments. Two forward slashes, I I, indicate the start of a
comment that continues until the end of a line:

II This is a comment.
x = 1; II The first part of this line is not a comment.
An alternative technique is to use 1* to indicate the start of a comment that continues
until *1 is encountered. Such comments can continue over many lines:

1* This is a comment *1
1* This
is
a
longer
comment *1

The 1* *1 technique may also include one or more I I style of comments:

1* This is a comment. II This is a second comment


and this is a continuation. *1

However, the 1* *1 style of comments cannot themselves be nested:

1* 1* This comment should not get past the compiler.


If it does then the compiler does not conform
with the ANSI C++ Standard.
Such extensions are best avoided. *1 *1

This restriction is a minor nuisance, since temporarily commenting out sections of code
by means of 1* *1 is very convenient, but cannot be used if the code already contains
1* *1 style comments. This is a good reason for only using the I I style of comment
in new code. However, an alternative technique for making the compiler temporarily
ignore sections of code is given in Section 4.13.3.
Notice that blanks are not allowed within the tokens defining either style of com-
ment:

I * This is not a valid comment. * I


I I Neither is this.

and that an incomplete 1* *1 style of comment can lead to errors:

1* Get the coefficients of the equation:


cout « "Enter the coefficients a, b, c: ";
cin » a » b » c;
1* Now find the roots: *1
root = sqrt(b * b - 4.0 * a * c);
2.3. IDENTIFIERS 11

In this example, everything between the first 1* and *1 is taken as a comment and, as
a result, a, band c have arbitrary values.
Comments, blanks, vertical and horizontal tabs, form feeds and new lines are col-
lectively known as white space. White space is not allowed in any token, except in
character or string constants. The compiler ignores any white space that occurs be-
tween tokens. Such white space is effectively a separator.

2.3 Identifiers
An identifier is a sequence of some combination of letters, digits and the underscore
symbol, _. Both upper and lower case characters are valid and are distinct. However, it
isn't a very good idea to rely on the case being the only distinguishing feature between
identifiers. In both C and C++ there is a tradition of using mainly lower case, except
where some special significance is being highlighted, as with a global constant. This
tradition makes for easily readable code.
The ANSI C++ Standard doesn't impose any maximum limit on the number of
characters in an identifier. Since real computers have finite resources your computer
will have some limit, but this is very unlikely to prove a problem.
An important restriction on identifiers is that they must start with a character or
underscore rather than a digit. Some examples of valid identifiers are:

main
cout
position_l
initial_velocity

whereas invalid identifiers include:

velocity$ II $ is not a digit, letter, or


lvelocity II Identifiers cannot start with a number.
vel 0 c i t y II White space is not allowed.
initial-velocity II Don't confuse - with
Oxygen_level II Don't confuse 0 with o.

Other examples of valid identifiers include those with a leading underscore:

_velocity

or embedded double underscores:

initial __ velocity

Both of these combinations are best avoided, since leading underscores and embedded
double underscores are often generated internally by compilers or used in libraries.
Likewise, it is worth avoiding trailing underscores:

velocity_

Apart from these minor restrictions, it is good programming practice to employ names
that are meaningful in the context in which they are used, such as:
12 CHAPTER 2. THE LEXICAL BASIS OF C++

water_temperature

instead of:

T12

Meaningful names make the code self-documenting and avoid the need for excessive
and distracting comments. While some programmers use an underscore to distinguish
different parts of an identifier, others prefer to use an upper case letter:

waterTemperature

You will probably find that you like one particular style and loath the other.

2.4 Keywords
Keywords are special identifiers that have a significance defined by the language rather
than the programmer. A complete but, at this stage, rather impenetrable list is given
in Table 2.2. You are not expected to memorize this list, rather it is given in order to
warn you to only use these keywords in ways that are defined by the language. 2

asm else new this


auto enum operator throw
bool explicit private true
break export protected try
case extern public typedef
catch false register typeid
char float reinterpret_cast typename
class for return union
const friend short unsigned
const_cast goto signed using
continue if sizeof virtual
default inline static void
delete int static-cast volatile
do long struct wchar_t
double mutable switch while
dynamic-cast namespace template

Table 2.2: C++ keywords.

There are also some alternative representations of C++ operators. These are given
in Table 2.3 and should only be used as defined by the language. For reference, the
operators that they represent together with the section where they are introduced in
this book are also given.
A few other keywords that may be reserved for some compilers are:

ada fortran pascal overload


huge near far
2Not all of these keywords are described in this book.
2.5. CONSTANTS 13

I Representation I Operator I Section Defined I


and && 4.2
and_eq &= 11.1.6
bitand & 11.1.2
bitor I 11.1.4
compl - 11.1.1
not ! 4.2
not_eq != 4.3
or II 4.2
or _eq 1= 11.1.6
xor - 11.1.3
xor_eq -= 11.1.6

Table 2.3: Alternative representations of C++ operators.

and these are best avoided as user-defined identifiers in order to ensure portability.
For some compilers such keywords may have a leading underscore, as in -.near.
Examples of the valid use of keywords are:

int i; II The keyword int declares i


II to be an integer variable.
char c; II The keyword char declares c
II to be a character variable.

However, the following are invalid:

int switch; II
Attempts to declare switch to be
II
an integer variable.
char class; II
Attempts to declare class to be
II
a character variable.
i n t i; II
White space is not allowed.
INT i', II Keywords must be lower case.

2.5 Constants
Constants, which are also known as literals, can be integer, Boolean, floating point,
character or string. More details of these four types are given in the next chapter, but
they are introduced here.

2.5.1 Integer Constants


Integer constants consist of a sequence of digits, such as:

14768

but not:
14 CHAPTER 2. THE LEXICAL BASIS OF C++

14,768 II An embedded comma is not allowed.


14 768 II Embedded white space is not allowed.
-14768 II This is an integer expression.
Notice that a negative integer is actually an integer constant expression rather than an
integer constant. Integer constants are usually given in decimal (base ten) notation,
but octal and hexadecimal constants are also possible. Octal (base eight) constants
start with 0 and cannot include the digits 8 or 9. An example of an octal constant is:

024

Hexadecimal (base sixteen) integer constants start with Ox (or OX) and may include
the letters a to f (or A to F, the case is not significant) as, for example:

Ox7a1f

2.5.2 Boolean Constants


There are two Boolean constants, namely true and false and these have their obvious
meanings. Further details are given in Section 3.1.10.

2.5.3 Floating Point Constants


Floating point constants include a decimal point or an exponent, or both. Some ex-
amples are:

2500.1 2.5001e3 25001E-1

where the value following e (or E) is the exponent. Negative floating point numbers,
such as

-2500.1 -2.5001e3 -25001e-1

are actually floating point constant expressions, rather than constants.

2.5.4 Character Constants


A character inside single quotes, such as:

'a' '1 '


, ,

is a character constant and is usually represented internally by one byte. Note that' l'
is not equal to the integer 1; for instance in the ASCII character set, '1' is actually
represented by 49. (See Appendix A for more detail.) Notice also that a character
constant has the form 'a', rather than 'a'.
Certain hard to get at characters are represented by using an escape sequence,
starting with a backslash; for instance '\n' signifies a new line. The complete list of
all such sequences is given in Table 2.4. The generalized escape sequence consists of
up to three octal or as many hexadecimal digits as are required. For instance, '\61'
and '\x31' both represent the character, '1'.
2.5. CONSTANTS 15

new line \n backslash \\


horizontal tab \t question mark \?
vertical tab \v single quote \'
backspace \b double quote \"
carriage return \r octal number \032
form feed \f hex. number \Ox32
alert (bell) \a

Table 2.4: Escape sequences.

Exercise 3
To demonstrate that both' \61' and' \x31' represent the same character,
try the following simple program:

#include <iostream>
using namespace std;

int maine)
{
char a, b;
a = '\61';
b = '\x31';
cout « a « ' , « b « '\n';
return(O);
}

and then modify it to sound your terminal bell by means of a suitable


hexadecimal escape sequence.

2.5.5 String Constants


String constants are sequences of characters between double quotes, as in:
"Hello world"
Notice that the double quote is a single character, ", rather than, ", and that white
space is significant in string constants so that "Hello world" is not the same as
"Helloworld". Internally a string is represented by an array of characters. This
means that "Hello world" is actually twelve characters since the escape sequence,
'\0' , is used after the last character to denote the end of a string. 4 Consequently' C'
is not the same as "C"; whereas the first consists of one character, the second consists
of two.
Adjacent string constants are concatenated, so that:
cout « "Hello" " World";
30ccasionally we include simple, un-numbered exercises in the text. You should do these as you
come across them. You are also encouraged to attempt the exercises at the end of each chapter!
4, \ 0' is sometimes known as the null character or the end-of-string character.
16 CHAPTER 2. THE LEXICAL BASIS OF C++

produces the output:

Hello World

2.6 Operators
An operator is a language-defined token, consisting of one or more characters, that
instructs the computer to perform some well-defined action. An example is the assign-
ment operator, =, used in the following:

i = l', II Assign 1 to the memory location


II holding the value of i.
A complete list of operators is given below:

0 [] -> typeid
->* & * dynamic_cast
++ I % static_cast
+ .* « » < reinterpret_cast
<= > >= != const cast
&& II 7: throw
+= *= 1= new
%= «= »= &= delete
1= sizeof

Notice that some keywords are also operators and that multi-character operators form
a single token. Once again it should be emphasized that white space is not allowed
within a token, meaning, for instance, that + = is not a valid operator, unlike +=.
However, in contrast to some languages, two operators can follow in succession; for
instance x * -1 is equivalent to x * (-1). More detail on most of these operators will
be given later in this book.

2.7 Programming Style


There is no enforced programming style in C++. White space is ignored (except within
tokens), there is no restriction to typing statements in certain columns (as in Fortran),
there is no required indentation (as in occam) and statements can flow across many
lines. Consequently it is possibly to produce code that is very difficult to read, as in:

#include <iostream>
#include <cmath>
using namespace std;int main(){double xl,x2,a,b,c,root;cout
«"Enter the coefficients a, b, c: ";cin»a»b»c;root=
sqrt(b*b-4.0*a*c);xl=O.5*(root-b)/a;x2=-O.5*(root+b)/a;cout
«"The solutions are "«xl«" and "«x2«"\n";return(O);}

However, it is up to the programmer to adopt a clear style that can easily be understood
by others. There is no unique good style, but it is worth adopting something similar
2.8. SUMMARY 17

to that used in this book. In particular it is a good idea to keep to one statement
per line (except in special circumstances) and to indent by one tab to denote blocks
of code. With this in mind, it is worth adjusting the tab on your editor to four (or
perhaps three) characters per tab position. If you don't do this, your code will march
across the page too quickly. Further hints on style will be given when more of the C++
language has been introduced.
There is one final point that should be made in this chapter. Very occasionally there
may appear to be be an ambiguity as to how one or more lines of code are resolved
by the compiler into tokens. For instance, given that both -- and - are valid C++
operators, how should

x = y---z; II x = (y--) - z; or x = y - (--z);

be read? The compiler resolves this ambiguity by adopting a maximal munch strategy;5
the parsing stage of the compilation process bites off the largest sequence of characters
that form a valid token. So the example above really does mean:

x = (y--) - z;

It is a good idea to resolve such apparent ambiguities by using white space or paren-
theses.

2.8 Summary
• A C++ source file consists of a sequence of tokens that are made up of one or
more characters.

• White space (including blanks, new lines, tabs etc.) is not allowed within tokens.

• There are five types of token: identifiers, keywords, constants, operators and
other separators.

• Use meaningful names for user-defined identifiers, such as flow_rate.

• Identifiers with language-defined significance are known as keywords, examples


of which are int, class, if, etc. The significance of keywords cannot be altered
by the programmer.

• Constants can be integer, Boolean, floating point, character or string. Examples


are:

10 true 2.01 'a' "Hello"

• Operators are tokens representing operations, such as assignment, =, addition, +,


multiplication, *.

5S ee [6].
18 CHAPTER 2. THE LEXICAL BASIS OF C++

2.9 Exercises
1. How many different types of token are there? Classify the following tokens:

new -> >


() i friend
int pressure 14 *[]
1.4 '\n' public

2. What is wrong with the following statements:

(a) speed$of$light = 186000;


(b) initial velocity = 0.0;
(c) #zero = 10;
(d) 180_degrees = 3.1415926535897932;
(e) -x = 360.0;
(f) void = 0;
(g) pressure := 760.0; II in pascals.
(h) 1* Perhaps this fix will work:
volume = 100.0; 1* in litres. *1
*1
(i) case = 2;
3. Which of the following are valid constants:

(a) 27
(b) 11,111
(c) 'Hello world'
(d) 'a'
(e) -3.1415926535897932
(f) '\t'
(g) 25L4
(h) '\032'
Chapter 3

Fundamental Types and Basic


Operators

c++ is a typed language; that is the variables and constants that occur in a program
each have a type and this controls how they may be used and what storage is required.
For example, variables of the int type, which are used to represent integers, may require
two bytes of memory, and variables of the float type, which are used to represent
floating point numbers, may need four bytes. Furthermore, the float and int types
are represented in memory in entirely different ways. The language-defined types that
are used to represent integers, Booleans, characters and floating point numbers are
known as fundamental types and are the concern of this chapter. 1 It is also possible to
define what are known as derived types in order to manipulate objects such as matrices,
complex numbers or 3-dimensional solids. 2 Techniques for creating derived types are
described in later chapters.

The motivation for using a typed language is that the compiler can catch many
programming errors by performing type-checking. For example, if an object is declared
to be constant (by using the const keyword, which is explained later in this chapter)
then an attempt to assign a value to the object is a compile-time error since it has the
wrong type for such operations.
In this chapter we examine all of the fundamental types defined by the C++ lan-
guage, together with some of the basic operators. This will enable us to carry out the
usual arithmetic operations and to manipulate characters. Compared with some lan-
guages, the fundamental types are rather limited; for instance, unlike Fortran, complex
numbers are not defined. Although this may seem a bit restrictive for many applica-
tions, derived types can effectively extend the language indefinitely. For example,
complex arithmetic is part of the ANSI C++ Standard Library. (See Section 17.3.l.)

IThe fundamental types are sometimes known as built-in or standard types.


2Derived types are sometimes known as useT'-defined types.

19
D. Capper, Introducing C++ for Scientists, Engineers and Mathematicians
© Springer-Verlag London 2001
20 CHAPTER 3. FUNDAMENTAL TYPES AND BASIC OPERATORS

3.1 Integral Data Types


The integral data types consist of three groups: the integer, Boolean and character
types. The integer group contains the short, int and long types, all of which can
be either signed or unsigned. 3 The integer types are used to store and perform
arithmetic operations on "whole" numbers (0, I, -50 etc.). Boolean variables can only
be used to store the two constants true and false. The character types are char,
signed char and unsigned char. Since characters are actually represented internally
by small integers, the character types can also be used for storing and operating on
such integers.

3.1.1 Type int


The int data type is the most important of the integral types and can hold both positive
and negative integers. For ints represented by two bytes, the maximum number that
can be represented is 32767 and the minimum is -32768. (For some compilers these
numbers may be 32768 and -32767 respectively, since sixteen bits can hold 216 = 65536
different numbers, including 0.) The exact limits for all integral data types are given
in a header file, called <climi ts>. It is worth examining this file at some stage to
see the limits for your particular system. On a UNIX or Linux system, the header
files are usually in the directory /usr/include/g++, or something similar. You should
be aware that the <climits> notation only implies that the compiler knows where
to find the file. It does not necessarily imply that the file is actually called climi ts.
The contents of the C++ header file <climits> are the same as the C header file
<limits.h>, so you may find that <climits> merely includes <limits.h>. If this
is the case, then you will have to search for <limits. h>. On a UNIX or Linux system
this will probably be in the /usr/include directory.
If we wish to use the variables i, j, k, then they can be defined by:
int i;
int j;
int k;

It is also possible to define a list of variables:

int i, j, k;

We say "define" rather than "declare"; in C++ the distinction is both subtle and
important. Defining an object, as above, not only specifies the type, but also reserves
the appropriate amount of memory. As will be seen later, it is possible to make a
declaration, such as

extern int i;

without reserving any memory (which must of course be done somewhere). In a com-
plete program there must be one (and only one) definition of an object, even though
there can be many declarations. It is worth emphasizing that, although an object may
be defined in the sense of memory being allocated, its "value" can still be arbitrary.
3The integer types are signed by default. It is therefore very rare and completely redundant to
have signed int, signed long or signed short.
3.1. INTEGRAL DATA TYPES 21

An object must be defined or declared before it can be used in a program, otherwise


a compile-time error results. This is more restrictive than some other languages, but
helps to eliminate errors such as mistyped identifiers.
The operator, =, is used for integer assignment, so the following defines i, j, k and
sets them to 1, 2, 3 respectively:

int i, j, k',
i l', II Notice that every statement
j 2', II ends with a semicolon.
k 3;

Addition and subtraction of integers are carried out using the usual + and - oper-
ators, as in:

int i, j, k',
i 1;
j 2;
k 3;
i i + j;
k k - i;
Notice that "=" is the assignment rather than equality operator, so the statement:

i = i + j;

means add the current values of i and j (1 and 2) and assign the result (3) to i. The
fact that "=" is the assignment operator means that expressions such as:

i + 1 = 7; II WRONG
which look mathematically respectable , are not correct C++ statements. Conversely,
some expressions that are valid in C++, would make no sense as mathematical equa-
tions. For example, in the above code fragment, the statement:

i = i + j;

does not imply that j is zero; in fact j is 3 in this context. It is also worth pointing
out that : = is not a valid assignment operator, nor even an operator:

i := 10; II WRONG: := is not an operator.

Our short sequence of assignment statements does not form a complete C++ pro-
gram but , following the examples in Chapter 1, we can easily rectify this situation to
produce the following code:

#include <iostream> II For cout


using namespace std;
int mainO
{
int i, j, k;
i l',
j = 2;
22 CHAPTER 3. FUNDAMENTAL TYPES AND BASIC OPERATORS

k 3;
i i + j;
k k - i;
cout « "i " « i «" k " << k << "\n";
returneO);
}

Notice that mainO is a function that returns the int type and in this example we
return the value o. (More discussion of this return value is given later, but in some
circumstances it may be important for the operating system to know whether or not
the program has run successfully, as indicated by 0.) We also include a statement
so that the program can actually display the result of the calculations by using the
insertion operator to send the values of i and k to the output stream. The resulting
output is:

i =3 k =0
Exercise
Enter the above program into a file on your system, making sure the file
has the appropriate extension, such as . cxx. Then compile, link and run
the program. Check that you get the expected result. Try modifying the
program to add different combinations of integers.

Since the int type occupies a fixed and finite amount of memory, only a limited
range of integers can be stored. Consequently it is possible to perform operations which
mathematically would give results above the maximum value that can be represented
or below the minimum value. Such invalid operations are known respectively as integer
overflow and integer underflow. These are demonstrated in the following program:

#include <iostream>
#include <climits>
using namespace std;
int maine)
{
int i;
i = INT_MAX + 10; II Integer overflow.
cout « "i = " « i « "\n";
i = INT_MIN - 10; II Integer underflow.
cout « "i = " « i « "\n";
returneO);
}

INT_MAX and INT_MIN are the maximum and minimum values that can be stored by
the type int and are defined in the header file, <climits>. These values depend on
the particular compiler, as does the result of underflow or overflow.

Exercise
What values are given to i for these two statements on your system? Show
that your results are consistent with the values given in <climits>.
3.1. INTEGRAL DATA TYPES 23

3.1.2 Integer Multiplication


As might be expected, the token, *, is used to denote integer multiplication. The usual
rules of arithmetic are followed, as in:

#include <iostream>
using namespace std;
int main()
{
int i, j, k, m, n;
i 2;
j -3;
k -4;
m= i II Assigns -6 to m.
* j;
= j k·, II Assigns 12 to n.
n
*
i 3
* 6; II Assigns 18 to i.
cout « "m " « m « "\nn = " « n « "\ni " « i «
lI\n ll ;
return(O);
}

Exercise
Check that the above program gives the results you would expect on your
system.

3.1.3 Integer Division


The forward slash is used to denote the integer division operator, as in:

int k;
k = 3 I 2;

which means divide 3 by 2 and put the result in k. Since 2 does not exactly divide
3, there is a potential ambiguity as to whether k is set to 1 or 2. In fact, in common
with most languages, the C++ result is 1; integer division with both numbers positive
always truncates. The same is true when both numbers are negative, so that -3 / -2
yields 1 rather than 2. If only one number is negative, then the result depends on
the compiler: -3 I 2 could give either -1 or -2. Relying on a feature provided by a
particular compiler is not good programming practice and should be avoided if at all
possible. (In general, if you do need to use a compiler-dependent feature, then you
should have a clear comment on this in your program.)
In mathematics, dividing any non-zero number by zero gives infinity and dividing
zero by zero is undefined; in C++, any integer division by zero is undefined.

3.1.4 Integer Modulus or Remainder Operator


The %token is the modulus or remainder operator. If i and j are both positive integers,
then i % j (read as "i modulo .i") gives the remainder obtained on dividing i by j.
24 CHAPTER 3. FUNDAMENTAL TYPES AND BASIC OPERATORS

For instance, 5 % 3 yields the value 2. If both i and j are negative then the result is
negative; that is -5 % -3 yields -2. If only one of i and j is negative, then the result is
again dependent on the C++ compiler, but should be consistent with the dependency
for division. That is:
(i I j) * j + i %j
should give the value of i. Again, if j is zero the result of i % j is not defined and
may not be consistent with the (undefined) result of i I j. (Saying that a piece of
code is "undefined" means that the C++ language definition doesn't say how it should
be interpreted.) Notice that 0 % j gives 0 for any (non-zero) integer, j.
Exercise
Tryout the following program for various values of i and j (positive, neg-
ative and zero) and explain the output. What happens if you enter a non-
sense value, such as "accidentally" hitting the w key instead of 2? Why?
#include <iostream>
using namespace std;
int main()
{
int i, j, m, n, a, b;
cout « "enter an integer: ";
cin » i;
cout « "enter an integer: ";
cin» j;
m = i I j;
n = i % j;
a = m
* j; II (i I j ) * j
b a + n; II (i I j) * j + i
cout « "i " « i «" j "« j « "\n\n" «
"i I j " « m« " i %j = " « n «
"\n\nThe following result should be " « i «
":\n" « " (i I j) * j + i % j = " « b « " \n" ;
return(O);
}

In this example we use the C++ input stream, cin, so that the values of i and j can
be entered from the keyboard. The expression:
cin » i;
extracts the value of i from the input stream. The operator, », is known as an
extraction operator. It is possible to concatenate such operators so that the first few
lines can be replaced by:
cout « "enter two integers: ";
cin » i » j;
but notice that the following is not equivalent:
cin » i, j; II WRONG!
The statement does compile, but no value is assigned to j when the program is run.
3.1. INTEGRAL DATA TYPES 25

3.1.5 Increment and Decrement Operators


The value of a variable can be changed without using the assignment operator. Instead
of:

i = i + 1;

we can use:
++i; II Prefix increment operator.
or:
i++; II Postfix increment operator.
In all three cases, i is increased by one. Whereas the prefix operator increments i by
one before the value of i is used, the postfix operator increments i after its value has
been used. Either version of the increment operator has the same effect in the above
code fragments, but note that this is not true for the following program:
#include <iostream>
using namespace std;
int mainO
{
int i, j, k, m, n;
i 2;
j i;
k 3;
m i++ I k; II Assigns 0 to m.
n = ++j I k; II Assigns 1 to n.
cout « tom " « m « "\nn " « n « "\ni " « i «
"\nj =" « j «"\n";
return(O);
}

In this example, the expression for m is evaluated before i is incremented, but n is


evaluated after j is incremented.

Exercise
Modify the above program so that it reads i and k from the keyboard. Try
entering a few different values of i and k, and check that you get the results
you expect for m and n.

As might be expected, there are also prefix and postfix decrement operators so that:

--i;

and:
i--;

are equivalent to:


26 CHAPTER 3. FUNDAMENTAL TYPES AND BASIC OPERATORS

i = i - 1;

Whereas the prefix decrement operator decreases the value of i by one before it is used
in an expression, the postfix decrement operator decreases i after the value has been
used. The use of increment and decrement operators can lead to very compact code,
but it is worth exercising some restraint otherwise the code can get difficult to read.

Exercise
Replace the increment by decrement operators in your program for the
previous exercise.

It may seem obvious, but constants cannot be incremented or decremented:

++3.142; II WRONG!
10--; II WRONG!
In any case, it is difficult to imagine how such statements could be useful.

3.1.6 Associativity and Precedence of Integer Operators


Although we have only considered simple expressions so far, we have learned how to
use quite a few operators:
+ I % ++
*
The =, *, I, %tokens are all binary operators; that is they are defined for an operand
on each side of the operator, such as in:

k = i * j; I I Valid C++.
rather than:
k = i *; II WRONG: where is the second operand?
The ++ and -- operators are both unary operators, that is they require a single operand:
++x; II Unary - operator takes only one operand.
The - operator can be both a binary operator, as in:
k = i - j; II Binary - operator.
or a unary operator, as in:

k = -j; II Unary - operator takes only one operand.


The unary + operator, as in:

k = +j; II Valid but useless unary + operator.


is not expressly forbidden. However, it doesn't serve any useful purpose and you won't
come across the unary + operator again in this book.
In complicated expressions, such as:

k = i + jim * n - k;
3.1. INTEGRAL DATA TYPES 27

the two concepts of associativity and precedence are used to determine the order in
which the evaluation is carried out. Operator precedence controls which operator in
an expression is applied first; the associativity determines the order in which operators
with the same precedence are applied. That is, the compiler first uses operator prece-
dence to determine the order of evaluations in an expression and then any remaining
ambiguities are removed by using operator associativity.
The properties of the operators introduced so far are given in Table 3.1. Notice

Operator I Associativity I Section First Defined I


++ postfix increment right to left 3.1.5
-- postfix decrement right to left 3.1.5
++ prefix increment right to left 3.1.5
-- prefix decrement right to left 3.1.5
- unary minus right to left 3.1.6
* multiplication left to right 3.1.2
I division left to right 3.1.3
% modulo left to right 3.1.4
+ addition left to right 3.1
- subtraction left to right 3.1
= assignment right to left 3.1
+= add and assign right to left 3.4.3
-= subtract and assign right to left 3.4.3
*= multiply and assign right to left 3.4.3
1= divide and assign right to left 3.4.3
%= modulo and assign right to left 3.4.3

Table 3.1: Common operators.

that the postfix increment and decrement operators have a higher precedence than the
prefix increment and decrement operators. All operators shown in the same group have
the same precedence and associativity, but a group higher up in the table has a higher
precedence than one further down. For example, in the expression: 4

i = 1 - 2 * 3 + 4; II * has higher precedence than - or +.

the multiplication operator has the highest precedence and is applied first, yielding:

i = 1 - 6 + 4; II -, + have higher precedence than =.


The subtraction and addition operators have equal precedence, greater than that of
the assignment operator, so the right-hand side of the expression is evaluated left to
right, giving the result of -1. Finally -1 is assigned to i. These rules, which are similar
to those of many other languages, do not necessarily give the results that would be
expected mathematically. For instance, due to the left to right associativity of the
divide operator, the statement:
4Throughout this book short fragments of code, which are not complete programs, are frequently
given. You should now be able to convert these code fragments into programs, by introducing mainO,
the appropriate #include directives and sending results to the output stream. Indeed, you are strongly
encouraged to tryout as many such programs as possible.
28 CHAPTER 3. FUNDAMENTAL TYPES AND BASIC OPERATORS

i =3 I 4 I 2;

is evaluated as:
i = (3 I 4) I 2;

rather than:
i = (3 * 2) I 4;
Any expression inside parentheses is evaluated first, which means that: 5

i = (1 - 2) * (3 + 4);

is reduced to:

i = -1 * 7;

which assigns -7 to i. If you are in doubt about the precedence of any operator, it is
always possible to use parentheses.

Exercise
Write a program to evaluate the following expressions:

i 2 I 3 + 3 I 2;
i 2 I 3 I 3;
i 3 I 2 % 7;
i 7 % 2 * 3;
i 7 I 2 * 3;

Are the results what you would expect?

3.1.7 Long Integers


Long integers have the same properties as integers, except that at least the same
number of bytes must be used in their representation as are used for the int data type.
Typically four bytes are used and integers between -2147483648 and 2147483647 can
be represented, as in:
long i, j, k;
i 2140001111; II Too big for 2 bytes.
j -2140001111; II Too small for 2 bytes.
k i - j;

However, it is fairly common for a compiler to define both the int and long data types
to have the same four-byte representations. The limits for a particular compiler are
again given in the <climi ts> header file.
Notice that the keyword, long, is used to define (and declare) long integers. The
definition:
5When describing the four different bracket types, the common terminology employed is: paren-
theses for ( ), braces for { }, square brackets for [], and angle brackets for < >. Note that the various
brackets must always occur in pairs.
3.1. INTEGRAL DATA TYPES 29

long int i, j, k;

is equivalent to that given above, but is less widely used.


The suffix L (or 1) is used to distinguish a long constant:

long i;
i = 1L;

3.1.8 Short Integers


The short type has the same properties as int, except that a particular C++ compiler
should not use more bytes to represent short than are used for into Typically the
short type uses two bytes and has a range of -32767 to 32768. This type can be
useful for saving memory as in:

short i, j, k·,
i 1·, II Can easily be represented by 2 bytes.
j 2; II Can easily be represented by 2 bytes.
k i - j;

However, if the representation is less than the natural size suggested by the hardware,
then there may be a performance penalty. It is best to avoid short integers unless there
is a very good reason to do otherwise. In any case, a compiler will often use the same
number of bytes for short as for into
Notice that the keyword, short, is used to define short integers. The equivalent
definition:

short int i, j, k;

is again less widely used.

3.1. 9 Unsigned Integers


The short, int and long types all have corresponding unsigned types. These occupy
the same amount of memory as the signed type and obey the laws of arithmetic
modulo 2", where n is the number of bits in the representation. For instance, if n is 16
(two bytes), then numbers between 0 and 65535 (that is 216 - 1) can be represented.
Unsigned addition does not overflow and subtraction does not underflow; they simply
wrap round. This is demonstrated by the following program:

#include <iostream>
#include <climits>
using namespace std;
int mainO
{
unsigned int i;
i = UINT_MAX;
i = i + 1;
cout « "UINT_MAX + 1 " « i « "\n";
i = i - 1;
30 CHAPTER 3. FUNDAJl.lENTAL TYPES AND BASIC OPERATORS

cout « "0 - 1 " « i « "\n";


return(O);
}

The program gets UINLMAX (the largest unsigned appropriate for the particular com-
piler) from the header file <climits>. Adding one to UINLMAX gives zero, and sub-
tracting one from zero gives UINT .11AX.
It is not usually worth using an unsigned rather than signed integral type just to
gain a higher upper limit on the positive integers that can be stored. An example of
the resulting possible pitfalls is given in Exercise 2 of Chapter 4; an example where
using an unsigned type is worthwhile appears in Section 11.4.1.
A U (or u) is used to denote an unsigned constant, as in:
unsigned int i;
unsigned long j;
i 1U;
j = 1UL;

Any combination of U, u and L, 1 m any order can be used for an uns igned long
constant.

3.1.10 Booleans
A Boolean can have one of two values, true or false. In C++, a Boolean is represented
by the bool data type, as in:
bool b1, b2;
b1 true;
b2 = false;
We can convert between the types bool and into By definition, true takes the value 1
on conversion to type int, and false takes the value O. The rule for the conversion of
type int to bool is that 0 is converted to false and any non-zero integer corresponds
to true. So the output from:
#include <iostream>
using namespace std;
int mainO
{
bool b1, b2;
b1 = true;
b2 = false;
cout « "b1 is " « b1 « "\n" «
"b2 is " « b2 « "\n";
return(O);
}

is:
b1 is 1
b2 is 0
The operators for Booleans are introduced in Section 4.2.
3.1. INTEGRAL DATA TYPES 31

3.1.11 Character Types


The type, char, is represented by a sufficient number of bytes to hold any charac-
ter belonging to the character set for the particular compiler. This representation is
usually one byte. Rather confusingly C++ distinguishes three character types: char,
unsigned char and signed char. The signed char and unsigned char data types
obey the same rules of arithmetic as their integer counterparts. If the type is simply
specified as char, then it is compiler-dependent as to whether or not the high order bit
is treated as a sign bit. This makes no difference when storing the standard printing
characters, but if other data is stored as type char it may appear to be negative on
one computer and positive on another. If the sign of such data is significant, then the
type should be specified as either signed or unsigned char, as appropriate. Such dis-
tinctions may seem a bit obscure to you at present, but may be relevant in the future
when you are puzzled by why your code behaves differently on different computers.
Although the char types obey the corresponding rules of integer arithmetic, they
are typically used to hold character data, as in:
#include <iostream>
using namespace std;
int maine)
{
char c1, c2;
c1 = 'C' ;
c2 = '+' ;
cout « c1 « c2 « c2 « "\n";
return(O);
}

Exercise
What does the above program output? Verify the answer on your system.

Since characters are represented by numbers, it is possible to make assignments


directly rather than by using the character constant notation. For instance an obscure
way of rewriting the above code, for the ASCII character set, is:
#include <iostream>
using namespace std;
int maine)
{
char c1, c2, c3;
c1 67;
c2 = 43;
c3 = 10;
cout « c1 « c2 « c2 « c3;
II Does the output agree with the previous exercise?
II See the ASCII character set in Appendix A.
return(O);
}

but such manipulations are rarely useful in scientific programming.


32 CHAPTER 3. FUNDAMENTAL TYPES AND BASIC OPERATORS

3.2 Floating Point Data Types


Floating point numbers, such as 3.142 and 2.9979 x 108 , are essential to almost every
scientific calculation. In C++, there are three floating point types: float, double and
long double. The type float is typically represented by 4 bytes, a double by 8 bytes
and a long double by 10 or 12 bytes. However, all that is required is that a double
uses at least the same number of bytes as a float and a long double uses at least as
many as a double. We first consider the type double, since from many points of view
it is the standard floating point type.

3.2.1 Type double


Identifiers of type double are defined by using the double keyword, as in:

double pi, c;
pi 3.1415926535897932;
c = 2.997925e8;

where the floating point assignment operator is denoted by the token, =. The expression
for c is typical of a floating point number and may be split into three parts:
2 the integer part
997925 the fractional part
8 the exponent.

A decimal point separates the integer and fractional parts, while e (E is also valid)
separates the fractional part from the exponent. A floating point constant must contain
a decimal point or an exponent or both, since otherwise there would be nothing to
distinguish it from an integer. If there is a decimal point, then either an integer or a
fractional part must be present. If there is no decimal point, then there must be both
an integer part and an exponent (but there can be no fractional part of course). Some
examples of valid floating point assignments are:

double x, y, z;
x = 1.0;
Y 0.1;
z = lel0;
x = 1. lelO;
y lle9;
z = .11ell;

However, the following are not valid double constants:

.e9 II WRONG: no integer or fractional part.


1,000.0 II WRONG: an embedded comma is not permitted.
1 000.0 II WRONG: an embedded space is not permitted.
1000 II WRONG: this is an integer constant.
el0 II WRONG: no integer part.

Apart from the use of e or E, all of this should be straightforward to anyone familiar
with scientific notation.
3.2. FLOATING POINT DATA TYPES 33

We can perform all of the usual arithmetic operations of assignment, addition,


subtraction, multiplication, division, increment, decrement and unary minus. In fact
all of the operators we introduced for integers, except for the modulus operator, are
also valid for double identifiers and constants. The following program demonstrates
these operations:

#include <iostream>
using namespace std;
int mainO
{
double x, y, z;
x = 3.1416; II ASSignment.
Y = -x; II Unary minus.
z = -3.1416; II Unary minus.
++x; II Increment (prefix version).
y--; II Decrement (postfix version).
x = x - 1.0; II Subtraction.
Y y+1.0; II Addition.
z = x * y; II Multiplication.
z = z I 3.1416; II Division.
cout « z « "\n";
return(O);
}

All of these operators have the same precedence and associativity as for the corre-
sponding integer versions. Notice that -3.1416 is actually an expression involving a
unary minus together with a double constant and that (as you might expect) floating
point division does not truncate to an integer, unlike integer division.

Exercise
What is the final result for z in the above code? Verify your answer by
running the program.

Only a finite subset of all floating point numbers can be represented by one of
the defined types, such as double. There are many ways of representing a floating
point number by a fixed number of bytes, but most C++ compilers conform to what
is known as the IEEE standard. For such compilers a double of eight bytes gives a
range of about 10- 308 to 10 308 and an accuracy of sixteen decimal places. More details
of how floating point numbers are represented by a computer are given in Chapter II.
For the present it is worth pointing out that in numerical calculations it is very easy to
attempt to generate a number whose absolute magnitude is too big to be represented
(causing floating point overflow) or too small (causing floating point underflow). It
is also possible to attempt to perform invalid operations, such as a divide by zero.
For a C++ compiler conforming to the IEEE standard, all such meaningless results
are flagged as NaNs (Not a Number). Once a NaN is created it propagates through
the calculation, ensuring that any meaningless final answers are also suitably flagged.
However, unless there is an appropriate compiler option, a NaN is not flagged when it
is generated. Such an option is invaluable for large numerical applications.
34 CHAPTER 3. FUNDAMENTAL TYPES AND BASIC OPERATORS

Unlike some other languages, such as FORTRAN, there is no operator for raising
a number (either integer or floating point) to a power. In C++, such operations are
carried out by a function call. For small integer powers it is, in any case, usually much
faster to use repeated multiplication, as in:

velocity = 0.5 * acceleration * time * time;

3.2.2 Type float


The type float should use at least four bytes (but not more than for double) to
represent a floating point number. For compilers conforming to the IEEE standard,
four bytes gives a range of about 1O~38 to 1038 and an accuracy of seven decimal places.
The type float has the advantage of using less memory than double and in fact four-
byte floating point arithmetic is accurate enough for many scientific and engineering
applications. Also, calculations using the float type may be significantly faster than
double. However, this will depend on the processor used in a particular machine. Older
versions of C++ only provided double implementations for the standard mathematical
functions (sine, cosine etc.). Fortunately, the C++ Standard Library provides both
float and double implementations and so it is easier for the programmer to make an
appropriate choice of floating point type.
Variables of type float are defined by the keyword, float, as in:

float pi, c;
pi = 3.142f;
c = 2.997ge8f;

A float constant is distinguished from its double counterpart by means of the suffix f
(or F). Omitting the f does not cause an error in the above examples, as the compiler
inserts a conversion from double to float. Such omissions are quite common. Notice
that the f is appended; it does not replace the e (or E):

c = 2.9979f8; II WRONG: f is not legal.


The operators available for the types float and double are identical. The prece-
dence and associativity of the operators are also identical.

3.2.3 Type long double


The type long double is defined by means of the long double keyword, as in:

long double pi, gamma;


pi = 3. 14159265358979323846L; II pi.
gamma = 0.57721566490153286061L; II Euler's constant.

A long double constant is distinguished from double and float by means of the
suffix, L. The letter 1 is also valid, but is probably best avoided since 1 looks too
similar to 1. 6 You do need to append the L (or 1) or else the constant will be read as a
6For the same reason, it is best to avoid using a single 1 as a user-defined identifier.
Another Random Scribd Document
with Unrelated Content
And so it was that the heart of Elizabeth the Queen warmed again,
and dearly, towards two Huguenot exiles, and showed that in doing
justice she also had not so sour a heart towards her sex as was set
down to her credit. Yet she made one further effort to keep De la
Forêt in her service. When Michel, once again, declined, dwelt
earnestly on his duty towards the widow of his dead chief, and
begged leave to share her exile in Jersey, Elizabeth said, “On my
soul, but I did not think there was any man on earth so careless of
princes’ honors!”
To this De la Forêt replied that he had given his heart and life to one
cause, and since Montgomery had lost all, even life, the least Michel
de la Forêt could do was to see that the woman who loved him be
not unprotected in the world. Also, since he might not at this present
fight for the cause, he could speak for it; and he thanked the Queen
of England for having shown him his duty. All that he desired was to
be quiet for a space somewhere in “her high Majesty’s good realm”
till his way was clear to him.
“You would return to Jersey, then, with our friend of Rozel?”
Elizabeth said, with a gesture towards Lemprière, who, now
recovered from his wound, was present at the audience.
De la Forêt inclined his head. “If it be your high Majesty’s pleasure.”
And Lemprière of Rozel said, “He would return with myself your
noble Majesty’s friend before all the world, and Buonespoir his ship
the Honeyflower.”
Elizabeth’s lips parted in a smile, for she was warmed with the luxury
of doing good, and she answered:
“I know not what the end of this will be, whether our loyal
Lemprière will become a pirate or Buonespoir a butler to my court;
but it is too pretty a hazard to forego in a world of chance. By the
rood, but I have never, since I sat on my father’s throne, seen black
so white as I have done this past three months. You shall have your
Buonespoir, good Rozel; but if he plays pirate any more—tell him this
from his Queen—upon an English ship, I will have his head, if I must
needs send Drake of Devon to overhaul him.”
That same hour the Queen sent for Angèle, and by no leave, save
her own, arranged the wedding-day, and ordained that it should take
place at Southampton, whither the Comtesse de Montgomery had
come on her way to Greenwich to plead for the life of Michel de la
Forêt and to beg Elizabeth to save her poverty, both of which things
Elizabeth did, as the annals of her life record.
After Elizabeth—ever self-willed—had declared her way about the
marriage ceremony, looking for no reply save that of silent
obedience, she made Angèle sit at her feet and tell her whole story
again from first to last. They were alone, and Elizabeth showed to
this young refugee more of her own heart than any other woman
had ever seen. Not by words alone, for she made no long story; but
once she stooped and kissed Angèle upon the cheek, and once her
eyes filled up with tears, and they dropped upon her lap unheeded.
All the devotion shown herself as a woman had come to naught; and
it may be that this thought stirred in her now. She remembered how
Leicester and herself had parted, and how she was denied all those
soft resources of regret which were the right of the meanest women
in her realm. For, whatever she might say to her Parliament and
people, she knew that all was too late—that she would never marry,
and must go childless and uncomforted to her grave. Years upon
years of delusion of her people, of sacrifice to policy, had at last
become a self-delusion, to which her eyes were not full opened yet—
she sought to shut them tight. But these refugees, coming at the
moment of her own struggle, had changed her heart from an ever-
growing bitterness to human sympathy. When Angèle had ended her
tale once more the Queen said:
“God knows ye shall not linger in my court. Such lives have no place
here. Get you back to my Isle of Jersey, where ye may live in peace.
Here all is noise, self-seeking, and time-service. If ye twain are not
happy I will say the world should never have been made.”
Before they left Greenwich Palace—M. Aubert and Angèle, De la
Forêt, Lemprière, and Buonespoir—the Queen made Michel de la
Forêt the gift of a chaplaincy to the crown. To Monsieur Aubert she
gave a small pension, and in Angèle’s hands she placed a deed of
dower worthy of a generosity greater than her own.
At Southampton Michel and Angèle were married by royal license,
and with the Comtesse de Montgomery set sail in Buonespoir’s boat,
the Honeyflower, which brought them safe to St. Helier’s, in the Isle
of Jersey.
XX
OLLOWED several happy years for Michel and
Angèle. The protection of the Queen herself, the
chaplaincy she had given De la Forêt, the
friendship with the governor of the island, and
the boisterous tales Lemprière had told of those
days at Greenwich Palace quickened the
sympathy and held the interest of the people at
large, while the simple lives of the two won their way into the hearts
of all, even, at last, to that of De Carteret of St. Ouen’s. It was
Angèle herself who brought the two seigneurs together at her own
good table; and it needed all her tact on that occasion to prevent
the ancient foes from drinking all the wine in her cellar.
There was no parish in Jersey that did not know their goodness, but
mostly in the parishes of St. Martin’s and Rozel were their faithful
labors done. From all parts of the island people came to hear Michel
speak, though that was but seldom; and when he spoke he always
wore the sword the Queen had given him and used the Book he had
studied in her palace. It was to their home that Buonespoir the
pirate—faithful to his promise to the Queen that he would harry
English ships no more—came wounded, after an engagement with a
French boat sent to capture him, carried thither by Shadrach,
Meshach, and Abednego. It was there he died, after having drunk a
bottle of St. Ouen’s muscadella, brought secretly to him by his
unchanging friend Lemprière, so hastening the end.
The Comtesse de Montgomery, who lived in a cottage near by, came
constantly to the little house on the hill-side by Rozel Bay. She had
never loved her own children more than she did the brown-haired
child with the deep-blue eyes which was the one pledge of the great
happiness of Michel and Angèle.
Soon after this child was born M. Aubert had been put to rest in St.
Martin’s churchyard, and there his tombstone might be seen so late
as a hundred years ago. So things went softly by for seven years,
and then Madame de Montgomery journeyed to England, on
invitation of the Queen and to better fortune, and Angèle and De la
Forêt were left to their quiet life in Jersey. Sometimes this quiet was
broken by bitter news from France of fresh persecution and fresh
struggle on the part of the Huguenots. Thereafter for hours,
sometimes for days, De la Forêt would be lost in sorrowful and
restless meditation; and then he fretted against his peaceful calling
and his uneventful life. But the gracious hand of his wife and the
eyes of his child led him back to cheerful ways again.
Suddenly one day came the fearful news from England that the
plague had broken out and that thousands were dying. The flight
from London was like the flight of the children of Israel into the
desert. The dead-carts, filled with decaying bodies, rattled through
the foul streets, to drop their horrid burdens into the great pit at
Aldgate; the bells of London tolled all day and all night for the
passing of human souls. Hundreds of homes, isolated because of a
victim of the plague found therein, became ghastly breeding-places
of the disease, and then silent, disgusting graves. If a man shivered
in fear or staggered from weakness, or for very hunger turned sick,
he was marked as a victim, and despite his protests was huddled
away with the real victims to die the awful death. From every
church, where clergy were left to pray, went up the cry for salvation
from “plague, pestilence, and famine.” Scores of ships from Holland
and from France lay in the Channel, not allowed to touch the shores
of England nor permitted to return whence they came. On the very
day that news of this reached Jersey came a messenger from the
Queen of England for Michel de la Forêt to hasten to her court, for
that she had need of him, and need which would bring him honor.
Even as the young officer who brought the letter handed it to De la
Forêt in the little house on the hill-side above Rozel Bay, he was
taken suddenly ill and fell at the Camisard’s feet.
De la Forêt straightway raised him in his arms. He called to his wife,
but, bidding her not come near, he bore the doomed man away to
the lonely Ecréhos rocks lying within sight of their own doorway.
Suffering no one to accompany him, he carried the sick man to the
boat which had brought the Queen’s messenger to Rozel Bay. The
sailors of the vessel fled, and alone De la Forêt set sail for the
Ecréhos.
There, upon the black rocks, the young man died, and Michel buried
him in the shore-bed of the Maître Île. Then, after two days—for he
could bear suspense no longer—he set sail for Jersey. Upon that
journey there is no need to dwell. Any that hath ever loved a woman
and a child must understand. A deep fear held him all the way, and
when he stepped on shore at Rozel Bay he was as one who had
come from the grave, haggard and old.
Hurrying up the hill-side to his doorway, he called aloud to his wife,
to his child. Throwing open the door, he burst in. His dead child lay
upon a couch, and near by, sitting in a chair, with the sweat of the
dying on her brow, was Angèle. As he dropped on his knee beside
her, she smiled and raised her hand as if to touch him, but the hand
dropped and the head fell forward on his breast. She was gone into
a greater peace.
Once more Michel made a journey—alone—to the Ecréhos, and
there, under the ruins of the old Abbey of Val Richer, he buried the
twain he had loved. Not once in all the terrible hours had he shed a
tear; not once had his hand trembled; his face was like stone and his
eyes burned with an unearthly light.
He did not pray beside the graves. But he knelt and kissed the earth
again and again. He had doffed his robes of peace, and now wore
the garb of a soldier, armed at all points fully. Rising from his knees,
he turned his face towards Jersey.
“Only mine! Only mine!” he said, aloud, in a dry, bitter voice.
In the whole island, only his loved ones had died of the plague. The
holiness and charity and love of Michel and Angèle had ended so!
When once more he set forth upon the Channel, he turned his back
on Jersey and shaped his course towards France, having sent
Elizabeth his last excuses for declining a service which would have
given him honor, fame, and regard. He was bent upon a higher duty.
Not long did he wait for the death he craved. Next year, in a
Huguenot sortie from Anvers, he was slain.
He died with these words on his lips:
“Maintenant, Angèle!”

In due time the island people forgot them both, but the Seigneur of
Rozel caused a stone to be set up on the highest point of land that
faces France, and on the stone were carved the names of Michel and
Angèle. Having done much hard service for his country and for
England’s Queen, Lemprière at length hung up his sword and gave
his years to peace. From the Manor of Rozel he was wont to repair
constantly to the little white house, which remained as the two had
left it—his own by order of the Queen—and there, as time went on,
he spent most of his days. To the last he roared with laughter if ever
the name of Buonespoir was mentioned in his presence; he
swaggered ever before the royal court and De Carteret of St. Ouen’s;
and he spoke proudly of his friendship with the Duke’s Daughter,
who had admired the cut of his jerkin at the court of Elizabeth. But
in the house where Angèle had lived he moved about as though in
the presence of a beloved sleeper he would not awake.
Michel and Angèle had had their few years of exquisite life and love,
and had gone; Lemprière had longer measure of life and little love,
and who shall say which had more profit of breath and being? The
generations have passed away, and the Angel of Equity hath a
smiling pity as she scans the scales and the weighing of the past.

THE END

“Come hither, O come hither,


There’s a bride upon her bed;
They have strewn her o’er with roses,
There are roses ’neath her head:
Life is love and tears and laughter,
But the laughter it is dead—
Sing the way to the valley, to the valley!
Hey, but the roses they are red!”
*** END OF THE PROJECT GUTENBERG EBOOK A LADDER OF
SWORDS: A TALE OF LOVE, LAUGHTER AND TEARS ***

Updated editions will replace the previous one—the old editions


will be renamed.

Creating the works from print editions not protected by U.S.


copyright law means that no one owns a United States
copyright in these works, so the Foundation (and you!) can copy
and distribute it in the United States without permission and
without paying copyright royalties. Special rules, set forth in the
General Terms of Use part of this license, apply to copying and
distributing Project Gutenberg™ electronic works to protect the
PROJECT GUTENBERG™ concept and trademark. Project
Gutenberg is a registered trademark, and may not be used if
you charge for an eBook, except by following the terms of the
trademark license, including paying royalties for use of the
Project Gutenberg trademark. If you do not charge anything for
copies of this eBook, complying with the trademark license is
very easy. You may use this eBook for nearly any purpose such
as creation of derivative works, reports, performances and
research. Project Gutenberg eBooks may be modified and
printed and given away—you may do practically ANYTHING in
the United States with eBooks not protected by U.S. copyright
law. Redistribution is subject to the trademark license, especially
commercial redistribution.

START: FULL LICENSE


THE FULL PROJECT GUTENBERG LICENSE
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the


free distribution of electronic works, by using or distributing this
work (or any other work associated in any way with the phrase
“Project Gutenberg”), you agree to comply with all the terms of
the Full Project Gutenberg™ License available with this file or
online at www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand,
agree to and accept all the terms of this license and intellectual
property (trademark/copyright) agreement. If you do not agree
to abide by all the terms of this agreement, you must cease
using and return or destroy all copies of Project Gutenberg™
electronic works in your possession. If you paid a fee for
obtaining a copy of or access to a Project Gutenberg™
electronic work and you do not agree to be bound by the terms
of this agreement, you may obtain a refund from the person or
entity to whom you paid the fee as set forth in paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only


be used on or associated in any way with an electronic work by
people who agree to be bound by the terms of this agreement.
There are a few things that you can do with most Project
Gutenberg™ electronic works even without complying with the
full terms of this agreement. See paragraph 1.C below. There
are a lot of things you can do with Project Gutenberg™
electronic works if you follow the terms of this agreement and
help preserve free future access to Project Gutenberg™
electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright
law in the United States and you are located in the United
States, we do not claim a right to prevent you from copying,
distributing, performing, displaying or creating derivative works
based on the work as long as all references to Project
Gutenberg are removed. Of course, we hope that you will
support the Project Gutenberg™ mission of promoting free
access to electronic works by freely sharing Project Gutenberg™
works in compliance with the terms of this agreement for
keeping the Project Gutenberg™ name associated with the
work. You can easily comply with the terms of this agreement
by keeping this work in the same format with its attached full
Project Gutenberg™ License when you share it without charge
with others.

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. Unless you have removed all references to Project


Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project
Gutenberg™ work (any work on which the phrase “Project
Gutenberg” appears, or with which the phrase “Project
Gutenberg” is associated) is accessed, displayed, performed,
viewed, copied or distributed:

This eBook is for the use of anyone anywhere in the United


States and most other parts of the world at no cost and
with almost no restrictions whatsoever. You may copy it,
give it away or re-use it under the terms of the Project
Gutenberg License included with this eBook or online at
www.gutenberg.org. If you are not located in the United
States, you will have to check the laws of the country
where you are located before using this eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is


derived from texts not protected by U.S. copyright law (does not
contain a notice indicating that it is posted with permission of
the copyright holder), the work can be copied and distributed to
anyone in the United States without paying any fees or charges.
If you are redistributing or providing access to a work with the
phrase “Project Gutenberg” associated with or appearing on the
work, you must comply either with the requirements of
paragraphs 1.E.1 through 1.E.7 or obtain permission for the use
of the work and the Project Gutenberg™ trademark as set forth
in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is


posted with the permission of the copyright holder, your use and
distribution must comply with both paragraphs 1.E.1 through
1.E.7 and any additional terms imposed by the copyright holder.
Additional terms will be linked to the Project Gutenberg™
License for all works posted with the permission of the copyright
holder found at the beginning of this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files
containing a part of this work or any other work associated with
Project Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute


this electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the
Project Gutenberg™ License.

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.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™
works unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or


providing access to or distributing Project Gutenberg™
electronic works provided that:

• 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 provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project


Gutenberg™ electronic work or group of works on different
terms than are set forth in this agreement, you must obtain
permission in writing from the Project Gutenberg Literary
Archive Foundation, the manager of the Project Gutenberg™
trademark. Contact the Foundation as set forth in Section 3
below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on,
transcribe and proofread works not protected by U.S. copyright
law in creating the Project Gutenberg™ collection. Despite these
efforts, Project Gutenberg™ electronic works, and the medium
on which they may be stored, may contain “Defects,” such as,
but not limited to, incomplete, inaccurate or corrupt data,
transcription errors, a copyright or other intellectual property
infringement, a defective or damaged disk or other medium, a
computer virus, or computer codes that damage or cannot be
read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except


for the “Right of Replacement or Refund” described in
paragraph 1.F.3, the Project Gutenberg Literary Archive
Foundation, the owner of the Project Gutenberg™ trademark,
and any other party distributing a Project Gutenberg™ electronic
work under this agreement, disclaim all liability to you for
damages, costs and expenses, including legal fees. YOU AGREE
THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT
LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT
EXCEPT THOSE PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE
THAT THE FOUNDATION, THE TRADEMARK OWNER, AND ANY
DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE LIABLE
TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL,
PUNITIVE OR INCIDENTAL DAMAGES EVEN IF YOU GIVE
NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of
receiving it, you can receive a refund of the money (if any) you
paid for it by sending a written explanation to the person you
received the work from. If you received the work on a physical
medium, you must return the medium with your written
explanation. The person or entity that provided you with the
defective work may elect to provide a replacement copy in lieu
of a refund. If you received the work electronically, the person
or entity providing it to you may choose to give you a second
opportunity to receive the work electronically in lieu of a refund.
If the second copy is also defective, you may demand a refund
in writing without further opportunities to fix the problem.

1.F.4. Except for the limited right of replacement or refund set


forth in paragraph 1.F.3, this work is provided to you ‘AS-IS’,
WITH NO OTHER WARRANTIES OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of
damages. If any disclaimer or limitation set forth in this
agreement violates the law of the state applicable to this
agreement, the agreement shall be interpreted to make the
maximum disclaimer or limitation permitted by the applicable
state law. The invalidity or unenforceability of any provision of
this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the


Foundation, the trademark owner, any agent or employee of the
Foundation, anyone providing copies of Project Gutenberg™
electronic works in accordance with this agreement, and any
volunteers associated with the production, promotion and
distribution of Project Gutenberg™ electronic works, harmless
from all liability, costs and expenses, including legal fees, that
arise directly or indirectly from any of the following which you
do or cause to occur: (a) distribution of this or any Project
Gutenberg™ work, (b) alteration, modification, or additions or
deletions to any Project Gutenberg™ work, and (c) any Defect
you cause.

Section 2. Information about the Mission


of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new
computers. It exists because of the efforts of hundreds of
volunteers and donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project
Gutenberg™’s goals and ensuring that the Project Gutenberg™
collection will remain freely available for generations to come. In
2001, the Project Gutenberg Literary Archive Foundation was
created to provide a secure and permanent future for Project
Gutenberg™ and future generations. To learn more about the
Project Gutenberg Literary Archive Foundation and how your
efforts and donations can help, see Sections 3 and 4 and the
Foundation information page at www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-
profit 501(c)(3) educational corporation organized under the
laws of the state of Mississippi and granted tax exempt status
by the Internal Revenue Service. The Foundation’s EIN or
federal tax identification number is 64-6221541. Contributions
to the Project Gutenberg Literary Archive Foundation are tax
deductible to the full extent permitted by U.S. federal laws and
your state’s laws.

The Foundation’s business office is located at 809 North 1500


West, Salt Lake City, UT 84116, (801) 596-1887. Email contact
links and up to date contact information can be found at the
Foundation’s website and official page at
www.gutenberg.org/contact
Section 4. Information about Donations to
the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission
of increasing the number of public domain and licensed works
that can be freely distributed in machine-readable form
accessible by the widest array of equipment including outdated
equipment. Many small donations ($1 to $5,000) are particularly
important to maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws


regulating charities and charitable donations in all 50 states of
the United States. Compliance requirements are not uniform
and it takes a considerable effort, much paperwork and many
fees to meet and keep up with these requirements. We do not
solicit donations in locations where we have not received written
confirmation of compliance. To SEND DONATIONS or determine
the status of compliance for any particular state visit
www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states


where we have not met the solicitation requirements, we know
of no prohibition against accepting unsolicited donations from
donors in such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot


make any statements concerning tax treatment of donations
received from outside the United States. U.S. laws alone swamp
our small staff.

Please check the Project Gutenberg web pages for current


donation methods and addresses. Donations are accepted in a
number of other ways including checks, online payments and
credit card donations. To donate, please visit:
www.gutenberg.org/donate.

Section 5. General Information About


Project Gutenberg™ electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg™ concept of a library of electronic works that could
be freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg™ eBooks with only a loose
network of volunteer support.

Project Gutenberg™ eBooks are often created from several


printed editions, all of which are confirmed as not protected by
copyright in the U.S. unless a copyright notice is included. Thus,
we do not necessarily keep eBooks in compliance with any
particular paper edition.

Most people start at our website which has the main PG search
facility: www.gutenberg.org.

This website includes information about Project Gutenberg™,


including how to make donations to the Project Gutenberg
Literary Archive Foundation, how to help produce our new
eBooks, and how to subscribe to our email newsletter to hear
about new eBooks.
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like