0% found this document useful (0 votes)
3 views

C++ 1

The document is a textbook titled 'How to Think Like a Computer Scientist' by Allen B. Downey, focusing on programming concepts using C++. It covers fundamental topics such as programming languages, debugging, variables, functions, conditionals, and recursion, structured in a clear and educational format. The book is available under a Creative Commons license and includes resources for further learning.

Uploaded by

zaff888
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

C++ 1

The document is a textbook titled 'How to Think Like a Computer Scientist' by Allen B. Downey, focusing on programming concepts using C++. It covers fundamental topics such as programming languages, debugging, variables, functions, conditionals, and recursion, structured in a clear and educational format. The book is available under a Creative Commons license and includes resources for further learning.

Uploaded by

zaff888
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

How to think like a computer scientist

Allen B. Downey

November 2012
2

How to think like a computer scientist


C++ Version

Copyright (C) 2012 Allen B. Downey

Permission is granted to copy, distribute, and/or modify this document un-


der the terms of the Creative Commons Attribution-NonCommercial 3.0 Un-
ported License, which is available at http://creativecommons.org/licenses/
by-nc/3.0/.
The original form of this book is LATEX source code. Compiling this code
has the effect of generating a device-independent representation of a textbook,
which can be converted to other formats and printed.
This book was typeset by the author using latex, dvips and ps2pdf, among
other free, open-source programs. The LaTeX source for this book is avail-
able from http://greenteapress.com/thinkcpp and from the SVN repository
http://code.google.com/p/thinkcpp.
Contents

1 The way of the program 1


1.1 What is a programming language? . . . . . . . . . . . . . . . . . 1
1.2 What is a program? . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 What is debugging? . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3.1 Compile-time errors . . . . . . . . . . . . . . . . . . . . . 4
1.3.2 Run-time errors . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3.3 Logic errors and semantics . . . . . . . . . . . . . . . . . 4
1.3.4 Experimental debugging . . . . . . . . . . . . . . . . . . . 5
1.4 Formal and natural languages . . . . . . . . . . . . . . . . . . . . 5
1.5 The first program . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.6 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2 Variables and types 11


2.1 More output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2 Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.4 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.5 Outputting variables . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6 Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.7 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.8 Order of operations . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.9 Operators for characters . . . . . . . . . . . . . . . . . . . . . . . 17
2.10 Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.11 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3 Function 21
3.1 Floating-point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2 Converting from double to int . . . . . . . . . . . . . . . . . . . 22
3.3 Math functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.4 Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.5 Adding new functions . . . . . . . . . . . . . . . . . . . . . . . . 24
3.6 Definitions and uses . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.7 Programs with multiple functions . . . . . . . . . . . . . . . . . . 27
3.8 Parameters and arguments . . . . . . . . . . . . . . . . . . . . . 28

i
ii CONTENTS

3.9 Parameters and variables are local . . . . . . . . . . . . . . . . . 29


3.10 Functions with multiple parameters . . . . . . . . . . . . . . . . . 30
3.11 Functions with results . . . . . . . . . . . . . . . . . . . . . . . . 30
3.12 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

4 Conditionals and recursion 33


4.1 The modulus operator . . . . . . . . . . . . . . . . . . . . . . . . 33
4.2 Conditional execution . . . . . . . . . . . . . . . . . . . . . . . . 33
4.3 Alternative execution . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.4 Chained conditionals . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.5 Nested conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.6 The return statement . . . . . . . . . . . . . . . . . . . . . . . . 36
4.7 Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.8 Infinite recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.9 Stack diagrams for recursive functions . . . . . . . . . . . . . . . 39
4.10 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5 Fruitful functions 41
5.1 Return values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.2 Program development . . . . . . . . . . . . . . . . . . . . . . . . 43
5.3 Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.4 Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.5 Boolean values . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.6 Boolean variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.7 Logical operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.8 Bool functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.9 Returning from main . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.10 More recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.11 Leap of faith . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.12 One more example . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.13 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6 Iteration 55
6.1 Multiple assignment . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.2 Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.3 The while statement . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.4 Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6.5 Two-dimensional tables . . . . . . . . . . . . . . . . . . . . . . . 60
6.6 Encapsulation and generalization . . . . . . . . . . . . . . . . . . 60
6.7 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.8 More encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6.9 Local variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6.10 More generalization . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.11 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
CONTENTS iii

7 Strings and things 67


7.1 Containers for strings . . . . . . . . . . . . . . . . . . . . . . . . 67
7.2 string variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
7.3 Extracting characters from a string . . . . . . . . . . . . . . . . . 68
7.4 Length . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
7.5 Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
7.6 A run-time error . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
7.7 The find function . . . . . . . . . . . . . . . . . . . . . . . . . . 70
7.8 Our own version of find . . . . . . . . . . . . . . . . . . . . . . . 71
7.9 Looping and counting . . . . . . . . . . . . . . . . . . . . . . . . 71
7.10 Increment and decrement operators . . . . . . . . . . . . . . . . . 72
7.11 String concatenation . . . . . . . . . . . . . . . . . . . . . . . . . 72
7.12 strings are mutable . . . . . . . . . . . . . . . . . . . . . . . . . 73
7.13 strings are comparable . . . . . . . . . . . . . . . . . . . . . . . 74
7.14 Character classification . . . . . . . . . . . . . . . . . . . . . . . . 74
7.15 Other string functions . . . . . . . . . . . . . . . . . . . . . . . 75
7.16 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

8 Structures 77
8.1 Compound values . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8.2 Point objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8.3 Accessing instance variables . . . . . . . . . . . . . . . . . . . . . 78
8.4 Operations on structures . . . . . . . . . . . . . . . . . . . . . . . 79
8.5 Structures as parameters . . . . . . . . . . . . . . . . . . . . . . . 80
8.6 Call by value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
8.7 Call by reference . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
8.8 Rectangles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
8.9 Structures as return types . . . . . . . . . . . . . . . . . . . . . . 84
8.10 Passing other types by reference . . . . . . . . . . . . . . . . . . 84
8.11 Getting user input . . . . . . . . . . . . . . . . . . . . . . . . . . 85
8.12 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

9 More structures 89
9.1 Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
9.2 printTime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
9.3 Functions for objects . . . . . . . . . . . . . . . . . . . . . . . . . 90
9.4 Pure functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
9.5 const parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
9.6 Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
9.7 Fill-in functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
9.8 Which is best? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
9.9 Incremental development versus planning . . . . . . . . . . . . . 95
9.10 Generalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
9.11 Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
9.12 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
iv CONTENTS

10 Vectors 99
10.1 Accessing elements . . . . . . . . . . . . . . . . . . . . . . . . . . 100
10.2 Copying vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
10.3 for loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
10.4 Vector size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
10.5 Vector functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
10.6 Random numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
10.7 Statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
10.8 Vector of random numbers . . . . . . . . . . . . . . . . . . . . . . 105
10.9 Counting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
10.10Checking the other values . . . . . . . . . . . . . . . . . . . . . . 107
10.11A histogram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
10.12A single-pass solution . . . . . . . . . . . . . . . . . . . . . . . . 108
10.13Random seeds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
10.14Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

11 Member functions 111


11.1 Objects and functions . . . . . . . . . . . . . . . . . . . . . . . . 111
11.2 print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
11.3 Implicit variable access . . . . . . . . . . . . . . . . . . . . . . . . 113
11.4 Another example . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
11.5 Yet another example . . . . . . . . . . . . . . . . . . . . . . . . . 115
11.6 A more complicated example . . . . . . . . . . . . . . . . . . . . 115
11.7 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
11.8 Initialize or construct? . . . . . . . . . . . . . . . . . . . . . . . . 117
11.9 One last example . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
11.10Header files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
11.11Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

12 Vectors of Objects 123


12.1 Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
12.2 Card objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
12.3 The printCard function . . . . . . . . . . . . . . . . . . . . . . . 125
12.4 The equals function . . . . . . . . . . . . . . . . . . . . . . . . . 127
12.5 The isGreater function . . . . . . . . . . . . . . . . . . . . . . . 128
12.6 Vectors of cards . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
12.7 The printDeck function . . . . . . . . . . . . . . . . . . . . . . . 131
12.8 Searching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
12.9 Bisection search . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
12.10Decks and subdecks . . . . . . . . . . . . . . . . . . . . . . . . . 135
12.11Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
CONTENTS v

13 Objects of Vectors 137


13.1 Enumerated types . . . . . . . . . . . . . . . . . . . . . . . . . . 137
13.2 switch statement . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
13.3 Decks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
13.4 Another constructor . . . . . . . . . . . . . . . . . . . . . . . . . 141
13.5 Deck member functions . . . . . . . . . . . . . . . . . . . . . . . 141
13.6 Shuffling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
13.7 Sorting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
13.8 Subdecks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
13.9 Shuffling and dealing . . . . . . . . . . . . . . . . . . . . . . . . . 145
13.10Mergesort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
13.11Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

14 Classes and invariants 149


14.1 Private data and classes . . . . . . . . . . . . . . . . . . . . . . . 149
14.2 What is a class? . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
14.3 Complex numbers . . . . . . . . . . . . . . . . . . . . . . . . . . 151
14.4 Accessor functions . . . . . . . . . . . . . . . . . . . . . . . . . . 153
14.5 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
14.6 A function on Complex numbers . . . . . . . . . . . . . . . . . . 155
14.7 Another function on Complex numbers . . . . . . . . . . . . . . . 155
14.8 Invariants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
14.9 Preconditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
14.10Private functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
14.11Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160

15 File Input/Output and apmatrixes 161


15.1 Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
15.2 File input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
15.3 File output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
15.4 Parsing input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
15.5 Parsing numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
15.6 The Set data structure . . . . . . . . . . . . . . . . . . . . . . . . 166
15.7 apmatrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
15.8 A distance matrix . . . . . . . . . . . . . . . . . . . . . . . . . . 170
15.9 A proper distance matrix . . . . . . . . . . . . . . . . . . . . . . 171
15.10Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

A Quick reference for AP classes 175


A.1 apstring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
A.2 apvector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
A.3 apmatrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
vi CONTENTS
Chapter 1

The way of the program

The goal of this book is to teach you to think like a computer scientist. I like
the way computer scientists think because they combine some of the best fea-
tures of Mathematics, Engineering, and Natural Science. Like mathematicians,
computer scientists use formal languages to denote ideas (specifically computa-
tions). Like engineers, they design things, assembling components into systems
and evaluating tradeoffs among alternatives. Like scientists, they observe the
behavior of complex systems, form hypotheses, and test predictions.
The single most important skill for a computer scientist is problem-solving.
By that I mean the ability to formulate problems, think creatively about solu-
tions, and express a solution clearly and accurately. As it turns out, the process
of learning to program is an excellent opportunity to practice problem-solving
skills. That’s why this chapter is called “The way of the program.”
Of course, the other goal of this book is to prepare you for the Computer
Science AP Exam. We may not take the most direct approach to that goal,
though. For example, there are not many exercises in this book that are similar
to the AP questions. On the other hand, if you understand the concepts in this
book, along with the details of programming in C++, you will have all the tools
you need to do well on the exam.

1.1 What is a programming language?


The programming language you will be learning is C++, because that is the
language the AP exam is based on, as of 1998. Before that, the exam used
Pascal. Both C++ and Pascal are high-level languages; other high-level
languages you might have heard of are Java, C and FORTRAN.
As you might infer from the name “high-level language,” there are also
low-level languages, sometimes referred to as machine language or assembly
language. Loosely-speaking, computers can only execute programs written in
low-level languages. Thus, programs written in a high-level language have to
be translated before they can run. This translation takes some time, which is a

1
2 CHAPTER 1. THE WAY OF THE PROGRAM

small disadvantage of high-level languages.

But the advantages are enormous. First, it is much easier to program in


a high-level language; by “easier” I mean that the program takes less time to
write, it’s shorter and easier to read, and it’s more likely to be correct. Secondly,
high-level languages are portable, meaning that they can run on different kinds
of computers with few or no modifications. Low-level programs can only run on
one kind of computer, and have to be rewritten to run on another.

Due to these advantages, almost all programs are written in high-level lan-
guages. Low-level languages are only used for a few special applications.

There are two ways to translate a program; interpreting or compiling.


An interpreter is a program that reads a high-level program and does what it
says. In effect, it translates the program line-by-line, alternately reading lines
and carrying out commands.

source
code interpreter

The interpreter ... and the result


reads the appears on
source code... the screen.

A compiler is a program that reads a high-level program and translates it all


at once, before executing any of the commands. Often you compile the program
as a separate step, and then execute the compiled code later. In this case, the
high-level program is called the source code, and the translated program is
called the object code or the executable.

As an example, suppose you write a program in C++. You might use a


text editor to write the program (a text editor is a simple word processor).
When the program is finished, you might save it in a file named program.cpp,
where “program” is an arbitrary name you make up, and the suffix .cpp is a
convention that indicates that the file contains C++ source code.

Then, depending on what your programming environment is like, you might


leave the text editor and run the compiler. The compiler would read your source
code, translate it, and create a new file named program.o to contain the object
code, or program.exe to contain the executable.
1.2. WHAT IS A PROGRAM? 3

source object
code compiler code executor

The compiler ... and generates You execute the ... and the result
reads the object code. program (one way appears on
source code... or another)... the screen.
The next step is to run the program, which requires some kind of executor.
The role of the executor is to load the program (copy it from disk into memory)
and make the computer start executing the program.
Although this process may seem complicated, the good news is that in
most programming environments (sometimes called development environments),
these steps are automated for you. Usually you will only have to write a pro-
gram and type a single command to compile and run it. On the other hand, it
is useful to know what the steps are that are happening in the background, so
that if something goes wrong you can figure out what it is.

1.2 What is a program?


A program is a sequence of instructions that specifies how to perform a com-
putation. The computation might be something mathematical, like solving a
system of equations or finding the roots of a polynomial, but it can also be
a symbolic computation, like searching and replacing text in a document or
(strangely enough) compiling a program.
The instructions (or commands, or statements) look different in different
programming languages, but there are a few basic functions that appear in just
about every language:

input: Get data from the keyboard, or a file, or some other device.
output: Display data on the screen or send data to a file or other device.
math: Perform basic mathematical operations like addition and multiplication.
testing: Check for certain conditions and execute the appropriate sequence of
statements.
repetition: Perform some action repeatedly, usually with some variation.

Believe it or not, that’s pretty much all there is to it. Every program you’ve
ever used, no matter how complicated, is made up of functions that look more or
less like these. Thus, one way to describe programming is the process of breaking
a large, complex task up into smaller and smaller subtasks until eventually the
subtasks are simple enough to be performed with one of these simple functions.
4 CHAPTER 1. THE WAY OF THE PROGRAM

1.3 What is debugging?


Programming is a complex process, and since it is done by human beings, it often
leads to errors. For whimsical reasons, programming errors are called bugs and
the process of tracking them down and correcting them is called debugging.
There are a few different kinds of errors that can occur in a program, and it
is useful to distinguish between them in order to track them down more quickly.

1.3.1 Compile-time errors


The compiler can only translate a program if the program is syntactically cor-
rect; otherwise, the compilation fails and you will not be able to run your
program. Syntax refers to the structure of your program and the rules about
that structure.
For example, in English, a sentence must begin with a capital letter and end
with a period. this sentence contains a syntax error. So does this one
For most readers, a few syntax errors are not a significant problem, which is
why we can read the poetry of e e cummings without spewing error messages.
Compilers are not so forgiving. If there is a single syntax error anywhere in
your program, the compiler will print an error message and quit, and you will
not be able to run your program.
To make matters worse, there are more syntax rules in C++ than there
are in English, and the error messages you get from the compiler are often
not very helpful. During the first few weeks of your programming career, you
will probably spend a lot of time tracking down syntax errors. As you gain
experience, though, you will make fewer errors and find them faster.

1.3.2 Run-time errors


The second type of error is a run-time error, so-called because the error does
not appear until you run the program.
For the simple sorts of programs we will be writing for the next few weeks,
run-time errors are rare, so it might be a little while before you encounter one.

1.3.3 Logic errors and semantics


The third type of error is the logical or semantic error. If there is a logical
error in your program, it will compile and run successfully, in the sense that
the computer will not generate any error messages, but it will not do the right
thing. It will do something else. Specifically, it will do what you told it to do.
The problem is that the program you wrote is not the program you wanted
to write. The meaning of the program (its semantics) is wrong. Identifying
logical errors can be tricky, since it requires you to work backwards by looking
at the output of the program and trying to figure out what it is doing.
1.4. FORMAL AND NATURAL LANGUAGES 5

1.3.4 Experimental debugging


One of the most important skills you should acquire from working with this
book is debugging. Although it can be frustrating, debugging is one of the most
intellectually rich, challenging, and interesting parts of programming.
In some ways debugging is like detective work. You are confronted with
clues and you have to infer the processes and events that lead to the results you
see.
Debugging is also like an experimental science. Once you have an idea what
is going wrong, you modify your program and try again. If your hypothesis
was correct, then you can predict the result of the modification, and you take
a step closer to a working program. If your hypothesis was wrong, you have to
come up with a new one. As Sherlock Holmes pointed out, “When you have
eliminated the impossible, whatever remains, however improbable, must be the
truth.” (from A. Conan Doyle’s The Sign of Four).
For some people, programming and debugging are the same thing. That is,
programming is the process of gradually debugging a program until it does what
you want. The idea is that you should always start with a working program
that does something, and make small modifications, debugging them as you go,
so that you always have a working program.
For example, Linux is an operating system that contains thousands of lines
of code, but it started out as a simple program Linus Torvalds used to explore
the Intel 80386 chip. According to Larry Greenfield, “One of Linus’s earlier
projects was a program that would switch between printing AAAA and BBBB.
This later evolved to Linux” (from The Linux Users’ Guide Beta Version 1).
In later chapters I will make more suggestions about debugging and other
programming practices.

1.4 Formal and natural languages


Natural languages are the languages that people speak, like English, Spanish,
and French. They were not designed by people (although people try to impose
some order on them); they evolved naturally.
Formal languages are languages that are designed by people for specific
applications. For example, the notation that mathematicians use is a formal
language that is particularly good at denoting relationships among numbers and
symbols. Chemists use a formal language to represent the chemical structure of
molecules. And most importantly:

Programming languages are formal languages that have


been designed to express computations.

As I mentioned before, formal languages tend to have strict rules about


syntax. For example, 3+3 = 6 is a syntactically correct mathematical statement,
but 3 = +6$ is not. Also, H2 O is a syntactically correct chemical name, but
2 Zz is not.
6 CHAPTER 1. THE WAY OF THE PROGRAM

Syntax rules come in two flavors, pertaining to tokens and structure. Tokens
are the basic elements of the language, like words and numbers and chemical
elements. One of the problems with 3=+6$ is that $ is not a legal token in
mathematics (at least as far as I know). Similarly, 2 Zz is not legal because
there is no element with the abbreviation Zz.
The second type of syntax error pertains to the structure of a statement;
that is, the way the tokens are arranged. The statement 3=+6$ is structurally
illegal, because you can’t have a plus sign immediately after an equals sign.
Similarly, molecular formulas have to have subscripts after the element name,
not before.
When you read a sentence in English or a statement in a formal language,
you have to figure out what the structure of the sentence is (although in a
natural language you do this unconsciously). This process is called parsing.
For example, when you hear the sentence, “The other shoe fell,” you under-
stand that “the other shoe” is the subject and “fell” is the verb. Once you have
parsed a sentence, you can figure out what it means, that is, the semantics of
the sentence. Assuming that you know what a shoe is, and what it means to
fall, you will understand the general implication of this sentence.
Although formal and natural languages have many features in common—
tokens, structure, syntax and semantics—there are many differences.
ambiguity: Natural languages are full of ambiguity, which people deal with
by using contextual clues and other information. Formal languages are
designed to be nearly or completely unambiguous, which means that any
statement has exactly one meaning, regardless of context.
redundancy: In order to make up for ambiguity and reduce misunderstand-
ings, natural languages employ lots of redundancy. As a result, they are
often verbose. Formal languages are less redundant and more concise.
literalness: Natural languages are full of idiom and metaphor. If I say, “The
other shoe fell,” there is probably no shoe and nothing falling. Formal
languages mean exactly what they say.
People who grow up speaking a natural language (everyone) often have a
hard time adjusting to formal languages. In some ways the difference between
formal and natural language is like the difference between poetry and prose, but
more so:
Poetry: Words are used for their sounds as well as for their meaning, and the
whole poem together creates an effect or emotional response. Ambiguity
is not only common but often deliberate.
Prose: The literal meaning of words is more important and the structure con-
tributes more meaning. Prose is more amenable to analysis than poetry,
but still often ambiguous.
Programs: The meaning of a computer program is unambiguous and literal,
and can be understood entirely by analysis of the tokens and structure.

You might also like