C__-A.Dialog

Embed Size (px)

Citation preview

C++: A DialogISBN: 0130094021

You can order this book from the online bookstore Amazon.com, by

clicking

For the whole book online, FREE, click here.Download a ZIP file containing the source code from C++: A Dialog.

DedicationThis book is dedicated to Susan Patricia Caffee Heller, the light of my life. Without her, this book would not be what it is; even more important, I would not be what I am: a happy man.www.steveheller.com [email protected]

Table of Contents

List of Figures xix How to Buy This Book xxxvii Foreword xxxix Preface xli Acknowledgements xlvii Letter from a Novice xlix CHAPTER 1 Introduction to Programming 1Baby Steps 7

CHAPTER 2 Hardware Fundamentals 11

Objectives of This Chapter 13 Inside the Box 14 The Binary Number System 32 Exercises 48 Using the 16-bit Register Names 48 Review 63 Conclusion 64 Answers to Exercises 64

CHAPTER 3 Basics of Programming 67Objectives of This Chapter 68 Rapid and Accurate Calculation 69 The Compiler 72 How the CPU Stores and Manipulates Data in Memory 77 The Layout of Data in Memory 80 Exercises, First Set 82 The char and string Types 96using, namespace, and std 98 int main() 100

Exercises, Second Set 109 Input and Output 110 Changing the Course of Execution 112 The while Loop 115 Exercises, Third Set 117 Our First Slightly Realistic Program 118 Exercises, Fourth Set 128 Review 129 Conclusion 132 Answers to Exercises 133

CHAPTER 4 More Basics 149Algorithmic Thinking 150 Handling Any Number of Prizes 159 Index Variables 169

The Selection Sort 178 Program Failure 200 Review 207 Exercises 209 Conclusion 211 Answers to Exercises 212

CHAPTER 5 Functional Literacy 219Objectives of This Chapter 223 Modules vs. Functions 223 Using a Function 239 Software Is a Virtual Computer 247 Scope of Variables 267 The Disadvantages of Global Variables 282 More on Using the Stack 285 Review 287 Exercises 290 Conclusion 291 Answers to Exercises 291

CHAPTER 6 Taking Inventory 295Objectives of This Chapter 298 User-defined Data Types 299 The StockItem class 305 More Definitions 308 Concrete Data Types 309 The class Scope 327 More about the StockItem class Interface 333 Working around the Standard Library 348 Reference Arguments 350 Checking Inventory for a Misplaced Item 391 Review 392 Exercises 401 Conclusion 402 Answers to Exercises 402

CHAPTER 7 Creating a Homegrown string class 405C String Literals vs. strings 406 Dynamic Memory Allocation via new and delete 417 Constructing a string from a C String 424 Assignment Operator Issues 438 Solving the Assignment Operator Problem 441 The const Modifier for Reference Arguments 444 Calling operator= 448 Review 466 Exercises 467 Conclusion 469 Answers to Exercises 470

CHAPTER 8 Finishing Our homegrown string class 473The string Copy Constructor 483 More about the private Access Specifier 500 First Review 506 Adding Further Facilities to our string class 510 Initialization vs. Assignment 542 Second Review 549 Exercises 551 Conclusion 553 Answers to Exercises 554

CHAPTER 9 Inheritance 563Objectives of This Chapter 565 Taking Inventory 574 Adding ReorderItems to the Inventory class 575 Adding Expiration Dates 581

The protected Access Specifier 596static Member Functions 616 The stream classes 621

More about stringstream 624 Review 651 Exercises 654 Conclusion 656

CHAPTER 10 Polymorphism 657Objectives of This Chapter 659 Introduction to Polymorphism 659 Exercises, First Set 693 Polymorphic Objects 694 More Definitions 694 Why We Need Polymorphic Objects 695 Implementing Safe Polymorphism 700 Reimplementing the Standard Member Functions for the New Version of StockItem 715 Avoiding an Infinite Regress During Construction 720 Reference Counting 723 Sharing a Worker Object 724 Why We Need m_Count in StockItem 743 Review 746 Exercises, Second Set 751 Conclusion 752

CHAPTER 11 The Home Inventory Project 753Objectives of This Chapter 754 Data Items for the Home Inventory Project 755 The Manager/Worker Idiom Again 758 Hiding Unnecessary Information from the class User 763 Saving the Number of the Elements in the File

793 Creating a Data File Programmatically 797 Adding the Ability to Edit a Record 814 The New Member Functions of HomeItemMusic 839 Review 846 Exercises 853 Conclusion 854

CHAPTER 12 More on the Home Inventory Project 855Objectives of This Chapter 857 Extending the Functionality of strings 857 How to Implement Our New string Functionality 858 The Include Guard 863 Lessons of the xstring class Implementation 878 Case-Insensitive Searching 880 Searching for an Item by a Substring 888 Putting It All Together 895 How Software Development Really Works 906 Review 907 Conclusion 910

CHAPTER 13 Analyzing the Home Inventory Project 911Objectives of This Chapter 912 The Final Version of the Home Inventory Program 913 Using a namespace to Group Utility Functions 925 The Functions of the HomeUtility namespace 930 Checking the Inventory 955 Finishing up the HomeItem class 974 Are We Having Fun Yet? 983 Review 983

Exercises 988 Conclusion 989

APPENDIX A Tying up Loose Ends 991Wrapping Up 993

APPENDIX B Glossary 995Special Characters 995 A 999 B 1002 C 1004 D 1010 E 1013 F 1014 G 1017 H 1017 I 1018 K 1021 L 1021 M 1023 N 1025 O 1028 P 1030 R 1033 S 1036 T 1041 U 1042 V 1044 W 1045 Y 1045 Z 1045

About the Author 1047

Bibliography 1049 Index 1051www.steveheller.com [email protected]

How to Buy This BookTo buy a printed copy of this book from Amazon.com, just click here. Thanks!www.steveheller.com [email protected]

A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X -Y-Z

Index

Symbols#define preprocessor directive 856 #endif preprocessor directive 856, 863 #ifndef preprocessor directive 856, 863, 865 #include preprocessor directive 122, 130, 304, 343 " " vs. < > 164, 343 & as "address of" operator 619 as marker for reference argument 350 .cc file extension 73 .cpp file extension 73 .h file extension 73

.hpp file extension 73 // as comment marker 73 header file 411 header file 346 header file 631 header file 411=

vs. == 158

-> defined 461 described 710

Numerics16 bit register names 48 16 bit register names on a 32 bit machine 50 64 bit register 41

Aaccess function 505 access specifier 317, 395 private 327, 328, 395, 500 encapsulation and 503 member variables 364 why member variables should be 340, 397 protected 586, 652 defined 565 disadvantages of 600 use of 596 public 317, 327, 395

global variables and 501 why member variables should not be 341 repeating in class declaration 604 scope and 328 algebraic equality vs. assignment statement 75 algorithm defined 3 aliasing defined 753 problem 816 defined 754 argument const reference 445, 890 temporary and 477-483 const string& 480 default 927 defined 857 defined 233 non-const reference 445, 446 passing 234, 890, 908 reference 350, 351, 398, 444, 445, 474, 476, 506, 507 reasons for using 482 to C function 619 value 234, 286, 288, 350, 474, 506 array defined 489 exceeding bounds of 495 initialization list 826 defined 754 name translated to address 495 used in homegrown string class 543

vs. pointer 491-500 arrow keys, as input 940 ASCII code 105 assembler 49 assembly language 49-63 add instruction 91 defined 13 increment instruction 172 mov instruction 91 op code 89 operation code 89 assignment 129 defined 74 operator See operator = statement 74, 76 statement vs. algebraic equality 75 See also class, base class, derived class, polymorphic object

Bbackslash 108 backspace key, editing with 945 base 16 numbering system 42 base 8 numbering system 41 base class 563, 564, 660 constructor 634-641, 653 special 741 default constructor 636 destructor 679

initializer 636, 637, 639, 653 object 635 part of derived class object 586, 598, 635 defined 565 base class pointer 653, 665 deleting a derived class object through 679 pointing to a derived class object 643, 699 BASIC language 283 batch file 126 beta testing 906 big-endian See under endian 81 binary number system 32-37 defined 13 bit 63 blank lines ignored by compiler 73 in input file 776 skipping 776 block 132 defined 68 bool 399 See under variable booting the computer 20 bootstrapping 125 defined 20 break statement 354, 355, 398

buffer 565 defined 543 byte 63 defined 16

CC standard library 411 string defined 412 vs. std::string 427 string literal 103, 131, 406, 427 defined 68 related to char* 433 type of 446 C++ address of char data for standard string 884 as a "language kit" 299 case sensitivity of identifiers and keywords 69 of input 390 derivation of name 172 facilities not provided by standard 917, 948 header file preprocessor symbol convention 865 keywords and symbols, reusing 297, 444 operator precedence in 992 philosophy of 858 standard library xlii, 68, 162 reasons for using 859 standard, official name of 232 string position numbering convention in 882 type system 107

cache 24, 27, 53 calendar and one-based indexing 167 call See function call carriage return 985 case statement 922 catch block 456 cerr 354 defined 795 char* 466, 477 use of for variable length data 421 character nondisplay 108 nonprinting 107 special for program text 109 child class See derived class chip defined 18 cin defined 111 class as a user-defined type 302 base See base class creating vs. using 393 defined 297 derived

See derived class designing for others 602 first example definition 305 how to create 303 implementation 297, 303, 318, 392 interface 297, 392 interface and implementation files 303 interface definition 303 internals 318 leaving out name inside declaration 322 member function 297, 318, 322, 330, 393, 397 member variable 298, 319, 323, 330, 393, 397 membership operator :: See under operator scope of member variables 327, 329 size of objects determined 321 static member variable 327 types supported like native types 448 vs. namespace 926 clreol function 948, 986 code duplication, reducing 820 comment defined 73 comparing two streams 804 compilation defined 5 compiler checking types of variables 107 defined 5 function of 72 memory leak reporting 457 relation to linker 304

compiler-generated assignment 313 copy constructor 474 destructor 739 functions 395 vs. native type facilities 311 member functions 394 compiling the compiler 72 concrete data type 309-315, 394, 466, 894 compiler-generated functions 375 defined 308 conio library 948 console defined 948 mode program 222 window 951 const 551 assignment not allowed to 324 defining a const value 541, 542 use with reference arguments 444 constructor 319, 322, 395, 466 defined 308 normal 333 See also class, base class, derived class, polymorphic object continuation expression See under for loop controlled block See under for loop controlled statement

See under for loop conversion function 875 Coplien, James 694, 696 copy constructor 310, 394, 395, 467 argument to 485 compiler generated 483 compiler-generated 475 defined 308 See also class, base class, derived class, polymorphic object cout defined 110 existing types and 535 user-defined types and 533 CPU 22 defined 13 crashes, cause 454 creating data types See class curly braces 101, 116 See also block See also for loop cursor defined 911

Ddangling pointer 661 data file

creating programmatically 797 data input preventing improper 203 debugging defined 9 decimal system defined 12 default defined 255 default constructor 310, 319, 320, 331, 394, 466 compiler-generated 332 defined 308 private 332 See also class, base class, derived class, polymorphic object default keyword 838 defensive programming 737 delete See under operator derived class 564, 586, 660 constructor 636 location of definition 604 object 635 See also class, base class, polymorphic object derived class object 651 destructor 310, 394, 466, 678 compiler-generated 594 defined 308 implementation for homegrown string class 463-465

normally called automatically 464 order of execution 735 unique for a given class 739 virtual 679, 738, 750 why we need a 680 why we need in a base class 679 See also class, base class, derived class, polymorphic object device independence 964 digit definition of 12 double See under variable double quotes 106 dump defined 810 dust bunnies 14 Dvorak keyboard 170 dynamic memory allocation 417 error prone nature of 456 dynamic typing defined 658

EEBCDIC character code 106 echoing data to the screen 943 else statement 114 empty C string literal "" 325

encapsulation 341, 503 defined 298 end pointer See under stream endian big 81 little 81 endl 114, 623 endless loop 914, 983 end-of-file condition handling properly 795 ENIAC 69 enum 824, 852, 915 automatic conversion to integer type 828 defined 754 why we should not do arithmetic on 831 escape sequence 142 exception 455 executable program 249, 250 defined 5, 74 executing code before the beginning of main 744 Exiguus, Dionysius 167 exit code 126 statement 456 explicit keyword 875, 878 extended string class

See xstring external cache 25, 51, 64 Extreme Programming 855

Ffail See under stream 398 fencepost error 357 field 631 fixed-length data 103 float See under variable floating-point flaw, Pentium 69 floppy disk 15 for loop 170-177, 208 continuation expression 171, 208 controlled block 171, 174 controlled statement 174 inner loop 186 iteration 175 modification expression 171, 208 outer loop 186 starting expression 171, 208 for statement See for loop formatting of the display 954 form-feed character 962 FORTRAN 169

free store 434 friend 538, 539 vs. inheritance 584 See also class, base class, derived class, polymorphic object function 221-293 argument list 231, 233, 287 call 222, 225, 287 virtual 662 call by value 234 called 222, 233, 238, 287 calling 222, 225, 231, 233, 260, 287 declaration 230, 287 defined 222 example of use 229 global disadvantages of 859 machine language call instruction 261, 266 machine language return instruction 266 main 226, 229 nested 244, 258 retrieval 223 return 245 return 0 228 return address 260, 288 return statement 222, 227, 288 return type 230, 231, 287 incompatible 231 int 228 return value 378 returning more than one value 931 side effects 227, 340 signature 333, 658

storage 223 undefined 243 virtual 661 calling most recently defined version of 851 calling through a base class pointer 665 defined 658 English description of mechanism 673 operation of 666-676 polymorphism and 666 protected 817 reusing code via 783 valid object required to call 717 vtable and 675 vs. module 223 why user-defined only 428 function overloading 333, 337, 395 using to select a special constructor 721

Ggarbage in, garbage out 203 general register 52, 78 getdate function 619 getline See under stream global namespace See under namespace gotoxy function 948, 986 grocery inventory program 295-404, 563-752

H

halting problem 906 hard disk 15 access time 17 head crash 15 platters 15 recording heads 15 rotational delay 19 sectors 16 seek 19 tracks 16 hardware defined 5 header file 73 Heller, Steve contact information xlv hexadecimal digit 42 hexit 42 notation 41 number system defined 12 numbers 65 home inventory program 753-989 analyzing the final version 913-983 homegrown string class 405-561 (char*) constructor 435 calling 436 implementation of 436 C string literals vs. 406 comparison operators 553

constructor 424, 425 containing a null byte 518 copy constructor 508 creating 405-561 defined 408 destructor 465, 471 null byte at end 520 operators != 557 < 533 556 >= 556 reading from an istream 540 HomeInventory class See home inventory program HomeItem class See home inventory program HomeUtility namespace 930-955

II/O defined 110 identifier 68, 232 defined 67 global 273 ideographic languages 97 idiom, programming 695 if statement 113, 116

conditions 158 ifstream 346, 353, 397, 576 See also stream ignore function See under stream 546 implementation file 73, 220 defined 222 implementation module 221 implicit conversion 875 include guard 856, 863, 864, 907 incremental development 897-905 incrementing a variable 172 indexing one-based 166, 167-168 zero-based 166, 167 inexpensive defined 254 information hiding 763, 823 inheritance 563-566, 583-615, 634-651 for extension 614 virtual functions and 658 See also class, base class, polymorphic object initialization vs. assignment 542 instruction fetch 23 int See under variable int main() 100

integer how negative values are stored 37 integral type 100 Intel architecture 58 internal cache 52, 64 internal polymorphism See polymorphic object internals defined 298 Inventory class See under grocery inventory program iostream 220, 353 manipulators 632, 633 using with class types 339 See also stream isA 613 defined 566 istream 214, 575 reading from 547 See also stream

Kkeyword 67, 233 defined 68

Lleast recently used (LRU) 28

library See library module library module 219, 249, 252 defined 222 link time 269, 276 linker 249, 288, 304 linking defined 249 literal value 237 defined 74 vs. named constant 542 little-endian See under endian logical AND operator && See under operator logical OR operator || See under operator long See under variable loop defined 115 loop control See while loop, for loop lpt1 921 LRU 28

M

machine instruction 49, 57 defined 13 machine language program defined 72 magic numbers 971 main function 101 manager/worker idiom 748, 758 defined 694 See also polymorphic object manipulator See under stream megabyte defined 16 megahertz defined 23 member function See under class member initialization expression 323 list 323, 636 member variable See under class memberwise copy 475, 506 memcmp 529, 549 memcpy 419, 422 memory address 19, 21

allocation errors 453 leak 455, 679 memory hierarchy 24, 51 memory manipulation functions hazards of 548 memory protection facilities 251 memory-to-memory instructions 52 memset 544 MIPS defined 69 modification expression See under for loop module 221, 223 modules affected by a change in a header 249 MS-DOS 251 multicharacter constant 138 multiplication symbol "*" 34

Nnamed constants naming convention 542 namespace creating our own 925, 926 defined 99 global 911, 926 scope and 285

namespace permissions blanket 335 nanoseconds 20 new need for 418 source of memory for 434 newline 936, 986 used as string terminator 545 non-const array size not allowed 544 nonmember function 395, 502 non-standard library 948 normal constructor defined 565, 726 Notepad 73 null byte 104, 131 use in C string 428 null object 377, 400

Oobject 299, 302, 392 defined 297 See also class, base class, derived class, polymorphic object object code 222 defined 5 library 220 module 219, 248

defined 222 object file 248, 288 defined 222 object member access operator defined 308 object-oriented design 589, 878 object-oriented programming 302, 393 .primary organizing principles 341 defined 298 octal 41 off by one error 357 ofstream 576 See also stream operating system facilities 250 operator 514, 519, 533, 534, 535, 536, 540, 549, 549, 550, 685 && 524 ++ 172, 960 += 217, 363 . (period) 451, 458 / 110 :: as class membership operator 309, 322 as scope resolution operator 273 -= 363 = 74, 310, 394, 438, 440, 466 and copy constructor 507 as assignment operator 75 compiler-generated 312, 594

declaring for homegrown string class 447 defined 308 description of 459 for native types 312, 313 hypothetical version with explicit this 462 implementation for homegrown string class 438-462 reference argument to 506 return value from 443 user-defined 312 user-defined for homegrown string class 441 why it needs a reference argument 474, 475==

158, 550

>> 215, 348, 550 polymorphism and 691-692 || 389 class membership :: 309 delete 452 destructor and 737 for class type 679 improper call to 453 pointers and 691 new 417 for object of class type 643 reporting failure 455 use of 420 redefining 443 scope resolution :: 273 ostream 214, 575 See also stream override defined 564 overriding a base class function 589, 651

Pparent class See base class parentheses 175 in conditional expression 116 partial assignment See slicing peek function See under stream plural terms, not used in C++ xlv pointer array address and 491 declared type used for type checking 743 defined 414 different meanings of 415 hazards of 548 invalid 454 member access operator -> 461 near-equivalence to array 496 new and 420 not a concrete data type 595 problems with copying 440 to same type being defined 699 types of 432 used for variable-length items 429 using only inside class implementations 452 variable types relevant to 415 why it is dangerous 661 polluting the global namespace 927 polymorphic object 694-744, 748, 758-823

avoiding an infinite regress during construction 720 base class constructor 719 base class destructor and 739 base class initializer 719 class registry function 745 copy constructor 728 default constructor 717 defined 694 destruction of 740 destructor 735 key to implementation of 710 operator = 730, 733 preventing infinite regress in 750 reference counting assignment and 733 similarities between different types of 759 slicing avoided by using 732 special constructor 720, 721 polymorphism adding types at link time 745 and pointers 676 dangerous 659-693 defined 658 native mechanism 661 safe See polymorphic object positional number systems 44 prefetch queue 61 prefetching 61, 62 premature destruction 475 preprocessor 863, 907 defined 856

preprocessor directive 121, 863 defined 856 preprocessor symbol 863 defined 856 private in class declaration line 614 inheritance 613 See also under access specifier processor 63 program counter 261, 262 program failure 200-201 program maintenance 583 programming as creating a virtual computer 247 by stepwise refinement 7 defined 4 waterfall mode of development 4 programming defensively 796 protected member function 617 protected vs. private variables 599 public in class declaration line 612 inheritance 613 See also under access specifier pumpkin-weighing program 118-128, 150-209 Purify, by Rational Software 454 put pointer See under stream

QQBASIC 283 quotes use of single and double 104 QWERTY keyboard 170

RRadio Shack TRS-80 Model III 283 RAM 23, 63, 77, 197 defined 18 reallocating memory 792 recursion 258, 642 reference counting 694, 723-744, 750, 816 defined 658 delete and 723 references to pointers 689 register 28, 53, 64 16-bit 30 32 bit 30 dedicated 28 general 29 regression testing 808 regular member function 592 defined 564 See also class, base class, derived class, polymorphic object

resize function 791 retrieval function 340 return statement See under function ROM defined 20 runaway program 251 run-time efficiency 166, 167, 202

Sscope class 396 defined 267 defining a namespace 285 global 267, 289 local 267, 289 variable going out of 464 vs. access specifier 328 scope resolution operator:: See under operator screen, number of lines 951 scroll area 953, 954 searching case sensitivity in 880 case-insensitive 880 selection expression 838 selection sort 178, 189, 207, 208 separate compilation 684

setfill manipulator 631, 633 setw manipulator 631, 633 short See under variable short-circuit evaluation rule 390 size function 785 different for each type of Vec 786 slicing 615, 860 software as a virtual computer 247 defined 5 software development process 906 sorting case sensitivity and 512 source code defined 5 source file 73 space after numeric value 937 space character 104 spaces allowed between components of a name 322 square brackets 163 in assembly language program 79, 84 stack 258-267 empty 259 layout of data in 262 memory usage of 260

overflow 289 pointer 261, 262 16 bit 261 32 bit 261 pop a value 259 push 259 retrieve a value 259 return addresses stored on 261 usage of 265 use of 288 using for temporary storage 285 stack-based addressing 264 standard library identifiers 335 string class undesirable behavior when initialized with 0 878 why we should use 348 standard member functions implementing for polymorphic object 715 See also class, base class, derived class, polymorphic object standard string class case sensitivity of 857 See also string class, homegrown string class, xstring classt starting expression See under for loop startup library 252 statement defined 72 static array 826, 852

static member function 615-617, 799 defined 565 static protected member function 617 static type checking 744 static typing defined 658 vs. static keyword 658 std namespace 99 using in header files 335 StockItem class See under grocery inventory program storage class 297 auto 257 dynamic 417 static 269, 288 storage function 340 stream 214, 627 buffer 622 buffering 942 clear function 938 end pointer 625, 629 fail 355 flush function 941, 962 get pointer 625 getline specifying terminating character 547 ignore function 933 manipulator 631 defined 564

maximum number of characters 934 peek function 546, 936 put pointer 622, 629 resetting status 935 stream classes 621-634 string class adding case insensitivity to 858 peculiarities of standard library version 348 why it isn't a native type 407 See also standard string class, homegrown string class, xstring class stringstream 620, 627, 629, 634, 652 defined 624 strlen 428 strnicmp 884, 908 Stroustrup, Bjarne 12, 39, 257 on the type system 348 subscript See index 164 substring, searching by 888 switch statement 837, 921 defined 754 selection expression 754

Ttemporary 482 temporary variable 478, 508 text editors 73

this 460, 461 defined 450 throwing an exception 455 tilde as marker for destructor 465 token 449 touch typing 170 transistors 18 try block 456 defined 456 Turbo Pascal compiler 248 Turing machine 247 Turing, Alan 247, 906 twinned strings 507 type implicit conversion 231 type checking dynamic 107 static 107, 231

Uunderscore character _ 233 Unicode standard 97 uninitialized const 542 variable

See under variable unqualified name 451 user-defined assignment 313 data type 295-989 user-defined data type See also class user-defined name See identifier using names from a namespace 99 using namespace std 98, 99

Vvariable allocation automatic vs. static 268 assigning a memory address 253 assigning storage at link time 253 auto 254, 255, 257, 258, 268, 288 automatic initialization not supplied for auto type 254 bool 295, 363 char 96 as a very short numeric value 494 deallocating 463 defined 29 double 295, 763, 992 float 295, 992 floating-point 30, 169, 819, 992 fully supported 296 global 267, 269, 274, 279 disadvantages 282

index 169 pre-standard scope of 779 scope of 779 initial value 253 initializing 202, 268, 276 static 253 int 100 integer 29 local 267 defining when needed 778 long 295, 763 native type 295, 297, 310 nonnumeric 71, 96 numeric 30, 71, 129 range double 1012 float 1015 int 1020 long 1022 short 39 scalar 164 scope 255, 267, 289, 326 short 30, 39, 64 signed 37 signed char 96 signed short 38, 39 static 253, 254, 255, 269, 279 static storage class 253 storage class 253, 288 auto 296 static 296 string 96, 97 types 280 uninitialized 192, 194-199, 241 unsigned 38

unsigned char 96 unsigned short 38, 39, 64 user-defined type 295 Vec 150, 162, 166, 207, 252, 785, 786, 850, 852 creating only when needed 778 element 208 index 163 index variable 208 mixing types of objects in 746 resizing 791 setting size 792 size function 952 sorting a Vec of strings 510 used with class types 344 vs. vector 194 vector 161, 252 element 161 See also class, scope, storage class variable-length data 103 Vec See under variable Vec.h 162 vector See under variable vector vs. Vec 194 vertical bars || See under operator || virtual computer 247 virtual function See under function void as return type 340

void type 339, 397 vtable 662, 667, 674, 747

Wwhile loop 115 Windows 251 Windows 2000 251 Windows NT 251 Windows Write 73 Word for Windows 73

Xxstring class 857-887 concatenation 868 operator + 870 why we don't have to worry about slicing 867

Zzero accidental initialization by 873 initialization of a string by 878 not using indiscriminately 722 oddities of 781, 873 pointer deleting is legal 453 zero-character C string literal 325 zero-character string 413

ForewordThe fundamental problem with most technical books is that the authors are just too smart for their readers' good. By the time one becomes an expert at a highly technical field, such as C++ programming, one has usually lost the knack of identifying with the poor struggling newbie. Also - it has to be said - most techies are not very good writers. Fortunately, the most able 10% of programmers also tend to be rather good writers - and my old friend Steve Heller is well up in both categories. He's also clever enough to know that he's not really very good at thinking like a programming newbie, and to go find help from people who are. But the book you're holding in your hands isn't just clever; it has a special, serendipitous magic that makes it one of the most remarkable technical books I've ever seen. Because Steve found a writing partner whose intelligence matched his own, and whose eager, questioning ignorance was the perfect complement of his seasoned expertise. This book, besides being an omnibus of the books Steve and Susan have written together, is also the story of the meeting of two very remarkable minds. Their continuing dialogue gives it a human texture that is sadly absent from most technical tutorials. They bring out the best in each other; Steve

continually challenges Susan to think and learn and grow, and Susan draws Steve out of the high fastnesses of abstraction into generating examples and analogies that are grounded in everyday experience. The result is a lovely fugue in two voices that weaves together many themes. Steve's unfolding of the mysteries of C++ intertwines with Susan's developing understanding of the language. Their growing affection and respect for each other complements the tale of bytes and silicon as they explore the inner world of the computer together. Susan discovers what she did not know, and Steve re-discovers what he does. Both processes are a pleasure to behold. How many introductions to programming are there that are also love stories? This may well be the only one. I won't spoil the ending for you - but I will say that if nothing else, Steve and Susan's relationship has produced work that is not merely topcaliber technical instruction but arguably art of a high and subtle order. It is an honor to know these two human beings, and a privilege to introduce their book. I hope you find that their journey of discovery guides you on one of your own. Eric S. Raymondwww.steveheller.com [email protected]

PrefaceIs this book for you? If you're a programmer in a language other than C++ and you want to upgrade your skills, then you shouldn't have much difficulty figuring that out for yourself by reading a few pages. But what if you have no previous programming experience? In that case, here's a little quiz that may help you decide:1. Do you want to know how the programs in your computer work inside and how to write some of your own? 2. Are you willing to exert yourself mentally to learn a complex technical subject? 3. Do you have a sense of humor?

If you've answered yes to these questions and follow through with the effort required, then you will get a lot out of this book. The common wisdom states that programming is a difficult subject that should be reserved for a small number of specialists. One of the main reasons that I have written this book is that I believe this attitude is wrong; it is possible, and even desirable, for you to learn how programs work and how to write them. Those who don't understand how computers perform their seemingly magical feats are at an ever-increasing disadvantage in a society ever more dependent on these

extraordinary machines. Regardless of the topic, I can see no valid reason for a book to be stuffy and dry, and I've done everything possible to make this one approachable. However, don't let the casual tone fool you into thinking that the subject is easy; there is no royal road to programming, any more than there is to geometry. Especially if you have no prior experience in programming, C++ will stretch your mind more than virtually any other area of study. Assuming that you want to learn C++, why should you read this book rather than any of dozens of other introductory C++ books? One difference between this book and other introductory books is that many of them still don't use the C++ standard library1, a very important part of the C++ language definition. We'll make use of some of the features of the standard library in this book, to get you started on learning this large and complex part of the C++ language. However, we certainly won't cover it in its entirety; that would require much more room that we can devote to it here. In fact, many books can be and have been written about the standard library alone, although I don't know of any that would be suitable for novices to programming. But there is one ingredient that makes this book unique: the participation of a real, live person who didn't already know the material before reading it, namely Susan Heller, my wife.2 Her main contribution has been to read every line of the book, starting with the first draft, and to ask questions via e-mail about anything she didn't understand. I answered her questions, also by e-mail, until both of us were satisfied that she understood the material in question and that the text was clear. After the text was otherwise complete, I extracted appropriate parts of the e-mail exchanges, edited them for spelling, punctuation, and so forth, and included them in the text where they will be most useful to the reader. For this latest version of the book, we have discussed the changes caused by the adoption of the standard library. As a result of our discussions, I have added to and modified the existing e-mail conversations as appropriate so that they make sense in the context of those changes. However, Susan still has the final say on what goes in her side of these conversations, so they are still authentic conversations. Of course, these exchanges do take up room in the book that might otherwise be filled with more information about C++ and programming. Therefore, if you want to get the absolute

maximum of new information per page, you might want to select another book such as Bjarne Stroustrup's excellent The C ++ Programming Language (ISBN 0-201-88954-4), or perhaps Accelerated C++, by Andrew Koenig and Barbara Moo (ISBN 0201-70353-X). However, the vast majority of comments I've received from readers of my other books for beginners have indicated that they found my approach very helpful, and I suspect that most readers of this book will feel the same. Susan has written an account of part of her involvement in this project, which immediately follows this Preface. I recommend that you read that account before continuing with the technical material following it, as it explains how and why she has contributed to making your task easier and more enjoyable. Speaking of Susan, here is a bit of correspondence between us on the topic of how one should read this book, which occurred after her first reading of what is now Chapter 2, "Hardware Fundamentals", and Chapter 3, "Basics of Programming".Susan: Let me say this: to feel like I would truly understand it, I would really need to study this about two more times. Now, I could do this, but I am not sure you would want me to do so. I think reading a chapter once is enough for most people. Steve: As a matter of fact, I would expect the reader of my book to read and study these chapters several times if necessary; for someone completely new to programming, I imagine that it would be necessary. Programming is one of the most complex human disciplines, although it doesn't take the mathematical skills of a subject such as nuclear physics, for example.3 I've tried to make my explanations as simple as possible, but there's no way to learn programming (or any other complex subject) without investing a significant amount of work and thought.

After she had gone through the text a number of times and had learned a lot from the process, we continued this discussion as follows:Susan: Well then, maybe this should be pointed out in a Preface or something. Of course, it would eventually be obvious to the reader as it was to me, but it took me a while to come to that conclusion. The advantage of knowing this in advance is that maybe I would not be so discouraged that I was not brilliant after one read of a chapter. Steve: I will indeed mention in the preface that the reader shouldn't be fooled by the casual tone into thinking that this is going to be a walk in the park. In any event, please don't be discouraged. It seems to me that you have absorbed a fair amount of very technical material with no previous background; that's something to be proud of!

We'll be hearing from Susan many more times in the course of the book. She will be checking in frequently in the form of extracts from the e-mail discussion we engaged in during the testing and revising process. I hope you will find her comments and my replies add a personal touch to your study of this technical material. While we're on the topic of your studying, this would be a good time to tell you how to get updates and help with any errors you might find in the book or with any other questions you might have. The best way is to visit my WWW site, steveheller.com. My e-mail address is [email protected]. In the event that you enjoy this book and would like to tell others about it, you might want to write an online review on Amazon.com, which you can do by visiting my home page and following the links to the "customer reviews" on Amazon. I should also tell you how the various typefaces are used in the book. Helvetica is used for program listings, for terms used in programs, and for words defined in the C++ language. Italics are used primarily for technical terms that are found in the glossary, although they are also used for emphasis in some places. The first time that a particular technical term is used, it is in bold face; if it is a term defined in the C++ language, it will be in bold Helvetica.4 Please note that I have used a consistent Helvetica font for words like "classes" and other plurals of C++ terms, rather than putting the plural ending in a different font, e.g., "classes", because I find frequent changes of font inside individual words distracting. There are no plural terms in C++ itself. If you remember that, you won't make the mistake of thinking that "classes" is a C++ term, when the term is really "class". If you do make such a mistake, you'll quickly find out about it because you'll get an error message when you try to use the term incorrectly in your program. Now that those preliminaries are out of the way, let's proceed. The next voice you will hear is that of Susan, my test reader. I hope you get as much out of her participation in this book as I have.1

A "library", in computer programming terms, is a collection of programs or parts of programs that have already been written so you don't have to write them yourself.2

To avoid confusion, I should explain that we were not married

when we started working on the first edition of this book, which was called Who's Afraid of C++? In fact, we met as a result of working on that book.3

Or deciphering a long distance telephone bill.4

Those of you who have read other programming books that use monospace fonts for code examples may find the use of a proportional-width font peculiar. However, I am following the example of Bjarne Stroustrup's The C++ Programming Language, in which he points out that "[P]roportional-width fonts are generally regarded as better than constant-width fonts for presentation of text." (p. 5)

www.steveheller.com [email protected]

AcknowledgementsI'd like to thank all the readers of my previous books who have written to me with praise and sometimes with corrections. Of course, I appreciate the former very much, but I appreciate the latter as well; every correction a reader sends me makes the next printing or edition of the book that much better. My primary technical reviewer, Donovan Rebbechi, found a number of ways to improve my code and my explanations thereof. My copy editor, Vivian Clark, has the rare facility of correcting errors without interfering with my style in the process. Working with her, despite a few technical glitches, was a great improvement over my previous experience with this phase of book production. Finally, I'd also like to thank my mother, Sali Heller Neff, and father, the late Leonard Heller. They had that rare but invaluable characteristic among parents: the courage and patience to let me do it my way.www.steveheller.com [email protected]

Letter from a NoviceOne day in March, 1995 I found myself reading this little message on my computer monitor:[#: 288196 S10/Have You Heard?] [25-Mar-95 20:34:55] [Sb: Readers for my new book] [Fm: Steve Heller 71101,1702] [To: all] Hi! I'm looking for some readers for a book I'm working on, which teaches people how to program, using C++ as the language. The ideal candidate is someone who wants to learn how to program, but has little or no knowledge or experience in programming. I can't pay anything, but participants will learn how to program, and will be acknowledged in the book, as well as getting an autographed copy. If you're interested, please reply by e-mail. Steve

As I considered my response to this message I felt a little trepidation for what was to come. I have known only one profession: nursing. I had owned and used a computer for only a little over two years at the time and thought DOS was too difficult to understand. Not only had I no prior knowledge of programming, I had very little knowledge of computers in general. Yet, what knowledge I did have of the computer fed my

curiosity for more, and as my love of the computer grew, it soon was apparent I had no choice. I replied by e-mail, waited impatiently for several days, and then...I jumped to the sound of an ominous knock at my front door. A sense of foreboding heightened with every step I made toward the sound. Cracking it open, I saw dark bluish-grey clouds hanging low overhead, threatening to unleash their contents at any moment. The tenseness of the postal worker's expression changed suddenly to an implacable smile as he quickly slipped a large envelope into my unsuspecting hands. Almost as soon as I realized I held the envelope, I looked up again to find the postman gone. The sky began to swirl, though there was only a hint of a breeze on my face. A slow shudder engulfed me as I quickly locked the door. Half dazed, I was left standing at my doorway, staring at my name on the envelope, written in a handwriting nearly identical to my own. Confused, but with a penetrating sense of courage, I tore open the mysterious yellow mailer. It in turn seemed to be the catalyst for the rupturing of the sky, and my roof and heart pounded in unison. As the contents of the envelope spilled out on my lap, I caught a glimpse of the words "Who's Afraid of C++?" on the looseleaf manuscript. I was briefly frozen by a paralyzing shiver that gripped my body, as I began to wonder what would become of me. What did this mean? What was C++ and why should I be afraid of it? What was I getting myself into? And one more question, most mysterious of all: Who is Steve Heller?

Never in my wildest dreams would I have ever expected that I would end up reading every page of this book with utmost attention to detail, leaving no word unturned, no concept overlooked, no hair on my head left unpulled for the next nine months of my life. But, if we were going to make this book as clear as possible for anyone who wanted to read it, there was no other way. The process of writing this book was an enormous effort on both our parts. Neither Steve nor I could have ever imagined the type of dialogue that would ensue. It just happened; as I asked the questions, he answered the questions and I asked again. The exchange would continue until we were both satisfied that I "had it". When that happened, Steve knew the right wording for the book, and I could move on to the next concept. It was an experience like no other in my life. It was a time filled with confusion, frustration, anger, acceptance, understanding, and joy. The process often gave cause for others to question my motivation for doing it. Admittedly, at times my frustration was such that I wanted to give up. But it became my mountain, and I had to climb it. I would not accept defeat. The material was not the only source of my frustration. There

was the inherent difficulty that Steve and I had in keeping communication flowing and speaking the same language. We found we had very different writing styles, which added another obstacle to our undertaking. He, the ultimate professional, and I, the incorrigible misfit, finally managed a happy medium. We corresponded on a daily basis, almost exclusively by e-mail. Through that medium it was our challenge to get into each other's minds. He had to learn how I thought and I had to learn how he thought - not an easy task for an expert and a novice who were total strangers. What you are about to read is the refinement of the writings of the mind of a genius filtered through the mind of a novice. Ideally, the result of this combination has produced the best possible information, written in the most understandable form. The book as you see it is considerably different from the original version, as a result of this filtering process. For that same reason, it is also different from any other book of its kind. To our knowledge, this is the first time that someone with no previous background in programming has been enlisted in the creation of such a book. Of course, it took tutoring, but that tutoring is what led to the simplification of the text so that future novices could enjoy a relatively pain-free reading experience. During the first few months of this process, I had to take it on faith that somehow all of this material would eventually make sense. But late one quiet night while first reading about objectoriented programming (the creation of "classes"), I was abruptly shaken by the most incredible feeling. I was held spellbound for a few moments, I gasped and was gripped with the sudden realization and awe of the profound beauty of the code. I had finally caught a glimpse of what programming was really all about. This experience later led me to write the following in a letter to my sister:Programming is SOOOO gorgeous. So fine, so delicate. It is so beautifully spun with silk threads, tiny and intricate. Yet like silk it can be strong and powerful, it all depends on how you use it.

At last, I had "gotten it". Within these pages the beauty lies dormant, waiting to be viewed only when the work has been done and the mountain scaled by those who embark on the task of learning. It is an exquisite panorama and a most worthy journey.

Further Adventures in C++ That was in 1995. As I write this years later, I have gained further insight into the art of programming. When Steve Heller asked me to help with the writing of the second part of this book, originally published as Who's Afraid of More C++?, I felt that shiver down my back again. I groaned, knowing full well this time what I was getting myself into and wondering if I had the stamina to do it again. Well, I did and we had another book. I also have the answers to the questions that I asked myself those years ago. I have learned what C++ is. It is a computer programming language. It is an immense language, it is a complicated language, and it is a very powerful language. I learned through the writing of this book that C++ can be molded and shaped to do just about anything you want it to do. It convolutes, twists and turns corners. You can play hide and seek with it. Yet, in the hands of an expert, it is amazing to see it come to life. As Steve and I wrote this book, I became more than a test reader, I also became a usability tester. Through this role I saw just how complicated writing a program is. I had already seen all the source code for the home inventory program that Steve wrote for this book, and was amazed to see just this one little screen of words to show for all our efforts. I knew what was underneath that screen. I knew all the hours, the false starts, the redos, the polishing that it took to get to where we were in the program, and I could not believe that so little showed for our efforts. Just when Steve thought he was done with it, I was quick to inform him that indeed he was not. It didn't take me long to "break" the program, causing more redos. Then there were things I wanted in the program to make it just a little easier, or a just little prettier. Back Steve went to the compiler. Actually, I think this was as much of a lesson on software design as it was on "more C++". There is so much to think about when writing a program; you have to program not only what you want it to do, but also what you don't want it to do. I can't say that there is no reason to fear C++. It is a difficult thing to learn, but no more so than any other language, including human spoken ones. It takes interest, work, and practice. But I think that as with any difficult subject, it can be mastered with the right learning tools and a competent teacher. I believe Steve to be a natural teacher and in this book, he has

created an excellent learning tool. As for the other question, Who is Steve Heller?: he is now my husband. Even after all the trouble he caused me with C++, I figured anyone who has the same handwriting as I do must be my soulmate. Susan Patricia Caffee Heller Sulphur Springs, Texaswww.steveheller.com [email protected]

CHAPTER 1 Introduction to Programming"Begin at the beginning, and go on till you come to the end: then stop." This method of telling a story is as good today as it was when the King of Hearts prescribed it to the White Rabbit. In this book, we must begin with you, the reader, since my job is to explain a technical subject to you. It might appear that I'm at a severe disadvantage; after all, I've never met you. Nevertheless, I can make some pretty good guesses about you. You almost certainly own a computer and know how to use its most common application, browsing the World Wide Web. If you use the computer in business, you probably also have an acquaintance with spreadsheets and word processors and perhaps some database experience as well. Now you have decided to learn how to program the computer yourself rather than relying completely on programs written by others. On the other hand, you might be a student using this book as a text in an introductory course on programming. In that case, you'll be happy to know that this book isn't written in the dry, overly academic style employed by many textbook writers. I hope that you will enjoy reading it as much as my previous readers have. Whether you are using this book on your own or in school, there are many good reasons to learn how to program. You may have a problem that hasn't been solved by commercial software, you

may want a better understanding of how commercial programs function so you can figure out how to get around their shortcomings and peculiarities, or perhaps you're just curious about how computers perform their seemingly magical feats. Whatever the initial reason, I hope you come to appreciate the great creative possibilities opened up by this most ubiquitous of modern inventions.1 Before we begin, however, we should agree on definitions for some fundamental words in the computing field. Susan had some incisive observations about the power of words. Here is our exchange on that issue:Susan: I will read something usually at face value, but often there is much more to it; that is why I don't get it. Then, when I go back and really think about what those words mean, it will make more sense. This book almost needs to be written in ALL CAPS to get the novice to pay closer attention to each and every word. Steve: IMAGINE WRITING A BOOK IN ALL CAPS! THAT WOULD BE VERY DIFFICULT TO READ, DON'T YOU THINK?

Many of the technical words used in this book are defined in the glossary at the end of the book. It is also very helpful to have a good dictionary of computer terms, as well as a good English dictionary. Of course, you may not be able to remember all of these technical definitions the first time through. If you can't recall the exact meaning of one of these terms, just look up the word or phrase in the index or in the glossary. Before we continue, let's check in again with Susan. The following is from her first letter to me about the contents of this book:Susan: I like the one-on-one feel of your text, like you are talking just to me. Now, you did make a few references to how simple some things were which I didn't catch on to, so it kinda made me feel I was not too bright for not seeing how apparently simple those things were... I think maybe it would have been helpful if you could have stated from the onset of this book just what direction you were taking, at least chapter by chapter. I would have liked to have seen a goal stated or a least a summary of objectives from the beginning. I often would have the feeling I was just suddenly thrown into something as I was reading along. Also (maybe you should call this C++ for Dummies, or is that taken already?)2, you might even define what programming is! What a concept! Because it did occur to me that since I have never seen it done, I really don't know what programming is! I just knew it was something that nerds do.

Susan's wish is my command, so I have provided a list of objectives at the beginning of each chapter after this one. I've also fulfilled her request for a definition of some programming terms.1

Of course, it's also possible that you already know how to program in another language and you're using this book to learn how to do so in C++. If so, you'll have a head start; I hope that you'll learn enough to repay the effort of wading through some material you already know.2

As it happens, that title is indeed taken. However, I'm not sure it's been applied appropriately, since that book assumes previous knowledge of C! What that says about C programmers is better left to the imagination.

www.steveheller.com [email protected]

1.1. DefinitionsAn algorithm is a set of precisely defined steps to calculate an answer to a problem or set of problems, and which is guaranteed to arrive at such an answer eventually. As this implies, a set of steps that might never end is not, strictly speaking, an algorithm.1 Programming is the art and science of solving problems by the following procedure:21. Find or invent a general solution to a class of problems. 2. Express this solution as an algorithm or set of algorithms. 3. Translate the algorithm(s) into terms so simple that a stupid machine like a computer can follow them to calculate the specific answer for any specific problem in the class.

At this point, let's see what Susan had to say about the above definition and my response to her.Susan: Very descriptive. How about this definition: Programming is the process of being creative using the tools of science such as incremental problem solving to make a stupid computer do what you want it to. That I understand! Your definition is just fine. A definition has to be concise and descriptive, and that you have done - and covered all the bases. But you know what is

lacking? An example of what it looks like. Maybe just a little statement that really looks bizarre to me, and then say that by the end of the chapter you, the reader, will actually know what this stuff really means! Sort of like a coming attraction type of thing. Steve: I understand the idea of trying to draw the reader into the "game". However, I think that presenting a bunch of apparent gibberish with no warning could frighten readers as easily as it might intrigue them. I think it's better to delay showing examples until they have some background.

Now let's return to our list of definitions: Hardware refers to the physical components of a computer, the ones you can touch. Examples include the keyboard, the monitor, the printer. Software refers to the nonphysical components of a computer, the ones you cannot touch. If you can install it on your hard disk, it's software. Examples include a spreadsheet, a word processor, a database program. Source code is a program in a form suitable for reading and writing by a human being. An executable program (or an executable, for short) is a program in a form suitable for running on a computer. Object code is a portion of a program in a form suitable for incorporation into an executable program. Compilation is the process of translating source code into object code. Almost all of the software on your computer was created by this process. A compiler is a program that performs compilation as defined above.

How to Write a ProgramNow you have a definition of programming. Unfortunately, however, this doesn't tell you how to write a program. The process of solving a problem by programming in C++ follows these steps:1. Problem: After discussions between the user and the programmer, the

programmer defines the problem precisely. 2. Algorithms: The programmer finds and/or creates algorithms that will solve the problem. 3. C++: The programmer implements these algorithms as source code in C+ +. 4. Executable: The programmer runs the C++ compiler, which must already be present on the programmer's machine, to translate the source code into an executable program. 5. Hardware: The user runs the resulting executable program on a computer.

These steps advance from the most abstract to the most concrete, which is perfectly appropriate for an experienced C++ programmer. However, if you're using this book to learn how to program in C++, obviously you're not an experienced C++ programmer, so before you can follow this path to solving a problem you're going to need a fairly thorough grounding in all of these steps. This description is actually a bit oversimplified, as we'll see in the discussion of linking in Chapter 5, "Functional Literacy". For now, let's see what Susan thinks about this issue.Susan: With all the new concepts and all the new language and terms, it is so hard to know what one thing has to do with the other and where things are supposed to fit into the big picture. Anyway, you have to understand; for someone like me, this is an enormous amount of new material to be introduced to all at once. When you are bombarded with so many new terms and so many abstract concepts, it is a little hard to sort out what is what. Will you have guidelines for each of the steps? Since I know a little about this already, the more I look at the steps, I just know that what is coming is going to be a big deal. For example, take step 1; you have to give the ingredients for properly defining a problem. If something is left out, then everything that follows won't work. Steve: I hope you won't find it that frustrating, because I explain all of the steps carefully as I do them. Of course, it's possible that I haven't been careful enough, but in that case you can let me know and I'll explain it further. Unfortunately, it's not possible for me to provide a thorough guide to all of those steps, as that would be a series of books in itself. However, there's a wonderful small book called How to Solve It, by G. Polya, that you should be able to get at your local library. It was written to help students solve geometry problems, but the techniques are applicable in areas other than geometry. I'm going to recommend that readers of my book read it if they have any trouble with general problem solving.

The steps for solving a problem via programming might sound reasonable in the abstract, but that doesn't mean that you can follow them easily without practice. Assuming that you already have a pretty good idea of what the problem is that you're

trying to solve, the algorithms step is likely to be the biggest stumbling block. Therefore, it might be very helpful to go into that step in a bit more detail.1

I should note that there is some disagreement on this fine point of definition. Some people consider a procedure to be an algorithm even if it may never end.2

This definition is possibly somewhat misleading since it implies that the development of a program is straightforward and linear, with no revisions required. This is known as the "waterfall model" of programming, since water going over a waterfall follows a preordained course in one direction. However, real-life programming doesn't usually work this way; rather, most programs are written in an incremental process as assumptions are changed and errors are found and corrected, as we'll see in Chapters 11 and 12.

www.steveheller.com [email protected]

1.2. Baby StepsIf we already understand the problem we're going to solve, the next step is to figure out a plan of attack which we will then break down into steps small enough that they can be expressed in C++. This is called stepwise refinement, since we start out with a "coarse" solution and refine it until the steps are within the capability of the C++ language. For a complex problem, this may take several intermediate steps; but let's start out with a simple example. Say that we want to know how much older one person is than another. We might start with the following general outline:1. Get two ages to be compared. 2. Calculate difference of ages. 3. Display the result.

This in turn can be broken down further, as follows:1. a. b. 2. 3. Get two ages to be compared. Ask user for first age. Ask user for second age. Subtract second age from first age. Display result.

This looks okay, except that if the first person is younger than the second one, the result will be negative. That may be acceptable. If so, we're just about done, since these steps are simple enough for us to translate them into C++ fairly directly. Otherwise, we'll have to modify our program to do something different, depending on which age is higher. For example:1. a. b. 2. a. b. 3. Get two ages to be compared. Ask user for first age. Ask user for second age. Compute difference of ages. If first age is greater than second, subtract second age from first age. Otherwise, subtract first age from second age. Display result.

You've probably noticed that this is a much more detailed description than would be needed to tell a human being what you want to do. That's because the computer is extremely stupid and literal: it does only what you tell it to do, not what you meant to tell it to do.1 Unfortunately, it's very easy to get one of the steps wrong, especially in a complex program. In that case, the computer will do something ridiculous and you'll have to figure out what you did wrong. This debugging, as it's called, is one of the hardest parts of programming. Actually, it shouldn't be too difficult to understand why that is the case; after all, you're looking for a mistake you've made yourself. If you knew exactly what you were doing, you wouldn't have made the mistake in the first place.2 I hope that this brief discussion has made the process of programming a little less mysterious. In the final analysis, it's basically just logical thinking.3

On with the ShowNow that you have some idea how programming works, it's time to see exactly how the computer actually performs the steps in a program. This is the topic of Chapter 2, "Hardware Fundamentals".1

In case you would like to see a C++ program that performs this calculation, I've written one. It's called "ages.cpp", and can be found in the code directory mentioned in the compiler installation instructions on the CD.

2

For this reason, one of the best ways to debug a program that is giving you trouble is to explain it in great detail to someone else. If you don't see the bug yourself, the other person almost certainly will find it for you.3

Of course, the word just in this sentence is a bit misleading; taking logical thinking for granted is a sure recipe for trouble.

www.steveheller.com [email protected]

CHAPTER 2 Hardware FundamentalsLike any complex tool, the computer can be understood on several levels. For example, it's entirely possible to learn to drive an automobile without having the slightest idea how it works. The analogy with computers is that it's relatively easy to learn how to use a Web browser without having any notion of how such programs work. On the other hand, programming is much more closely analogous to designing an automobile than it is to driving one. Therefore, we're going to have to go into some detail about the internal workings of a computer, not at the level of electronic components, but at the lowest level accessible to a programmer. This is a book on learning to program in C++, not on how a computer works.1 Therefore, it might seem better to start there and eliminate this detour, and indeed many (perhaps most) books on C++ do exactly that. However, in working out in detail how I'm going to explain C++ to you, I've come to the conclusion that it would be virtually impossible to explain why certain features of the language exist and how they actually work, without your understanding how they relate to the underlying computer hardware. I haven't come to this position by pure logical deduction, either. In fact, I've worked backward from the concepts that you will

need to know to program in C++ to the specific underlying information that you will have to understand first. I'm thinking in particular of one specific concept, the pointer, that is supposed to be extremely difficult for a beginning programmer in C++ to grasp. With the approach we're taking, you shouldn't have much trouble understanding this concept by the time you get to it in Chapter 7, "Creating a Homegrown string class". I'd be interested to know how you find my explanation, given the background that you'll have by that point. Don't hesitate to email me about this topic (or any other, for that matter). On the other hand, if you're an experienced programmer a lot of this will be just review for you. Nonetheless, it can't hurt to go over the basics one more time before diving into the ideas and techniques that make C++ different from other languages.2 Now let's begin with some definitions and objectives.1

For a really in-depth (or at least very funny) explanation of how computers work, you might want to take a look at Dave Barry in Cyberspace (ISBN 0-517-59575-3).2

Some people believe that you should learn C before you learn C++. Obviously, I'm not one of those people; for that matter, neither is the inventor of C++, Bjarne Stroustrup. On page 169 of his book, The Design and Evolution of C++, he says "Learn C++ first. The C subset is easier to learn for C/C++ novices and easier to use than C itself."

www.steveheller.com [email protected]

2.1. DefinitionsA digit is one of the characters used in any positional numbering system to represent all numbers starting at 0 and ending at one less than the base of the numbering system. In the decimal system, there are ten digits, 0 - 9, and in the hexadecimal system there are sixteen digits, 0 - 9 and a - f. A binary number system is one that uses only two digits, 0 and 1. A hexadecimal number system is one that uses sixteen digits, 0 - 9 and a - f. CPU is an abbreviation for central processing unit. This is the "active" part of your computer, which executes all the machine instructions that make the computer do useful work. A machine instruction is one of the fundamental operations that a CPU can perform. Some examples of these operations are addition, subtraction, or other arithmetic operations; other possibilities include operations that control what instruction will be executed next. All C++ programs must be converted into machine instructions by a compiler before they can be executed

by the CPU. An assembly language program is the human-readable representation of a set of machine instructions; each assembly language statement corresponds to one machine instruction. By contrast, a C++ program consists of much higher-level operations which cannot be directly translated one-for-one into machine instructions.www.steveheller.com [email protected]

2.2. Objectives of This ChapterBy the end of this chapter, you should Understand the programmer's view of the most important pieces of software in your computer. Understand the programmer's view of the most important pieces of hardware in your computer. Understand how whole numbers are stored in the computer.www.steveheller.com [email protected]

2.3. Inside the BoxFirst we'll need to expand on the definition of hardware. As noted earlier, hardware means the physical components of a computer, the ones you can touch.1 Examples are the monitor, which displays your data while you're looking at it, the keyboard, the printer, and all of the interesting electronic and electromechanical components inside the case of your computer.2 Right now, we're concerned with the programmer's view of the hardware. The hardware components of a computer with which you'll be primarily concerned are the disk, RAM (Random Access Memory), and last but certainly not least, the CPU.3 We'll take up each of these topics in turn.

DiskWhen you sit down at your computer in the morning, before you turn it on, where are the programs you're going to run? To make this more specific, suppose you're going to use a word processor to revise a letter you wrote yesterday before you turned the computer off. Where is the letter, and where is the word processing program? You probably know the answer to this question; they are stored on a disk inside the case of your computer. Technically, this is a

hard disk, to differentiate it from a floppy disk, the removable storage medium often used to distribute software or transfer files from one computer to another.4 Disks use magnetic recording media, much like the material used to record speech and music on cassette tapes, to store information in a way that will not be lost when power is turned off. How exactly is this information (which may be either executable programs or data such as word processing documents) stored? We don't have to go into excruciating detail on the storage mechanism, but it is important to understand some of its characteristics. A disk consists of one or more circular platters, which are extremely flat and smooth pieces of metal or glass covered with a material that can be very rapidly and accurately magnetized in either of two directions, "north" or "south". To store large amounts of data, each platter is divided into many billions of small regions, each of which can be magnetized in either direction, independent of the other regions. The magnetization is detected and modified by recording heads, similar in principle to those used in tape cassette decks. However, in contrast to the cassette heads, which make contact with the tape while they are recording or playing back music or speech, the disk heads "fly" a few millionths of an inch away from the platters, which rotate at very high velocity in a vacuum.5 The separately magnetizable regions used to store information are arranged in groups called sectors, which are in turn arranged in concentric circles called tracks. All tracks on one side of a given platter (a recording surface) can be accessed by a recording head dedicated to that recording surface; each sector is used to store some number of bytes of the data, generally a few hundred to a few thousand. Byte is a coined word meaning a group of binary digits, or bits for short; there are 8 bits in a byte in just about every modern general-purpose computer system, including PCs and Macintoshes.6 You may wonder why the data aren't stored in the more familiar decimal system, which of course uses the digits from 0 through 9. This is not an arbitrary decision; on the contrary, there are a couple of very good reasons that data on a disk are stored using the binary system, in which each digit has only two possible states, 0 and 1. One of these reasons is that it's a lot easier to determine reliably whether a particular area on a disk is magnetized "north" or "south" than it is to determine 1 of 10 possible levels of magnetization. Another reason is that the

binary system is also the natural system for data storage using electronic circuitry, which is used to store data in the rest of the computer. While magnetic storage devices have been around in one form or another since the very early days of computing, the advances in technology just in the last 16 years have been staggering. To comprehend just how large these advances have been, we need to define the term used to describe storage capacities: the megabyte. The standard engineering meaning of mega is "multiply by 1 million", which would make a megabyte equal to 1 million (1,000,000) bytes. As we have just seen, however, the natural number system in the computer field is binary. Therefore, one megabyte is often used instead to specify the nearest round number in the binary system, which is 220 (2 to the power of 20), or 1,048,576 bytes. This wasn't obvious to Susan, so I explained it some more:

Susan: Just how important is it to really understand that the megabyte is

220 (1,048,576) bytes? I know that a meg is not really a meg; that is, it's

more than a million. But I don't understand 220, so is it enough to just take your word on this and not get bogged down as to why I didn't go any further than plane geometry in high school? You see, it makes me worry and upsets me that I don't understand how you "round" a binary number. Steve: 220 would be 2 to the power of 20; that is, 20 twos multiplied

together. This is a "round" number in binary, just as 106 (1,000,000, or 6 tens multiplied together) is a round number in decimal.

Seventeen Years of ProgressWith that detail out of the way, we can see just how far we've come in a relatively short time. In 1985, I purchased a 20 megabyte disk for $900 ($45 per megabyte) and its access time, which measures how long it takes to retrieve data, was approximately 100 milliseconds (milli = 1/1000, so a millisecond is 1/1000 of a second). In October 2001, a 40,000 megabyte disk cost as little as $130, or approximately 0.3 cent per megabyte; in addition to delivering almost 14000 times as much storage per dollar, this disk had an access time of 9 milliseconds, which is approximately 11 times as fast as the old disk. Of course, this significantly understates the amount of progress in technology in both economic and technical terms. For one thing, a 2001 dollar is worth considerably less than a 1985 dollar. In addition, the new drive is superior in every other

measure as well. It is much smaller than the old one, consumes much less power, and has many times the projected reliability of the old drive. This tremendous increase in performance and decrease in price has prevented the long-predicted demise of disk drives in favor of new technology. However, the inherent speed limitations of disks still require us to restrict their role to the storage and retrieval of data for which we can afford to wait a relatively long time. You see, while 9 milliseconds isn't very long by human standards, it is a long time indeed to a modern computer. This will become more evident as we examine the next essential component of the computer, the RAM.

RAMThe working storage of the computer, where data and programs are stored while we're using them, is called RAM, which is an acronym for random access memory. For example, a word processor is stored in RAM while you're using it. The document you're working on is likely to be there as well unless it's too large to fit all at once, in which case parts of it will be retrieved from the disk as needed. Since we have already seen that both the word processor and the document are stored on the disk in the first place, why not leave them there and use them in place, rather than copying them into RAM? The answer, in a word, is speed. RAM, which is sometimes called "internal storage", as opposed to "external storage" (the disk), is physically composed of millions of microscopic switches on a small piece of silicon known as a chip: a 4-megabit RAM chip has approximately 4 million of them.7 Each of these switches can be either on or off; we consider a switch that is on to be storing a 1, and a switch that is off to be storing a 0. Just as in storing information on a disk, where it is easier to magnetize a region in either of two directions, it's a lot easier to make a switch that can be turned on or off reliably and quickly than one that can be set to any value from 0 to 9 reliably and quickly. This is particularly important when you're manufacturing millions of them on a silicon chip the size of your fingernail. A main difference between disk and RAM is what steps are needed to access different areas of storage. In the case of the

disk, the head has to be moved to the right track (an operation known as a seek), and then we have to wait for the platter to spin so that the region we want to access is under the head (called rotational delay). On the other hand, with RAM, the entire process is electronic; we can read or write any byte immediately as long as we know which byte we want. To specify a given byte, we have to supply a unique number, called its memory address, or just address for short.

Memory AddressesWhat is an address good for? Let's see how my discussion with Susan on this topic started.Susan: About memory addresses, are you saying that each little itty bitty tiny byte of RAM is a separate address? Well, this is a little hard to imagine. Steve: Actually, each byte of RAM has a separate address, which doesn't change, and a value, which does.

In case the notion of an address of a byte of memory on a piece of silicon is too abstract, it might help to think of an address as a set of directions to find the byte being addressed, much like directions to someone's house. For example, "Go three streets down, then turn left. It's the second house on the right". With such directions, the house number wouldn't need to be written on the house. Similarly, the memory storage areas in RAM are addressed by position; you can think of the address as telling the hardware which street and house you want, by giving directions similar in concept to the preceding example. Therefore, it's not necessary to encode the addresses into the RAM explicitly. Susan wanted a better picture of this somewhat abstract idea:Susan: Where are the bytes on the RAM, and what do they look like? Steve: Each byte corresponds to a microscopic region of the RAM chip. As to what they look like, have you ever seen a printed circuit board such as the ones inside your computer? Imagine the lines on that circuit board reduced thousands of times in size to microscopic dimensions, and you'll have an idea of what a RAM chip looks like inside.

Since it has no moving parts, storing and retrieving data in RAM is much faster than waiting for the mechanical motion of a disk platter turning.8 As we've just seen, disk access times are measured in milliseconds, or thousandths of a second. However,

RAM access times are measured in nanoseconds (ns); nano means one-billionth. In late 2001, a typical speed for RAM was 10 ns, which means that it is possible to read a given data item from RAM about 1,000,000 times as quickly as from a disk. In that case, why not use disks only for permanent storage, and read everything into RAM in the morning when we turn on the machine? The reason is cost. In late 2001, the cost of 512 megabytes of RAM was approximately $120. For that same amount of money, you could have bought 37000 megabytes of disk space! Therefore, we must reserve RAM for tasks where speed is allimportant, such as running your word processing program and holding a letter while you're working on it. Also, since RAM is an electronic storage medium (rather than a magnetic one), it does not maintain its contents when the power is turned off. This means that if you had a power failure while working with data only in RAM, you would lose everything you had been doing.9 This is not merely a theoretical problem, by the way; if you don't remember to save what you're doing in your word processor once in a while, you might lose a whole day's work from a power outage of a few seconds.10 Before we get to how a program actually works, we need to develop a better picture of how RAM is used. As I've mentioned before, you can think of RAM as consisting of a large number of bytes, each of which has a unique identifier called an address. This address can be used to specify which byte we mean, so the program might specify that it wants to read the value in byte 148257, or change the value in byte 66666. Susan wanted to make sure she had the correct understanding of this topic:Susan: Are the values changed in RAM depending on what program is loaded in it? Steve: Yes, and they also change while the program is executing. RAM is used to store both the program and its data.

This is all very well, but it doesn't answer the question of how the program actually uses or changes values in RAM, or performs arithmetic and other operations; that's the job of the CPU, which we will take up next.

The CPUThe CPU (central processing unit) is the "active" component in

the computer. Like RAM, it is physically composed of millions of microscopic transistors on a chip; however, the organization of these transistors in a CPU is much more complex than on a RAM chip, as the latter's functions are limited to the storage and retrieval of data. The CPU, on the other hand, is capable of performing dozens or hundreds of different fundamental operations called machine instructions, or instructions for short. While each instruction performs a very simple function, the tremendous power of the computer lies in the fact that the CPU can perform (or execute) tens or hundreds of millions of these instructions per second. These instructions fall into a number of categories: instructions that perform arithmetic operations such as adding, subtracting, multiplying, and dividing; instructions that move information from one place to another in RAM; instructions that compare two quantities to help make a determination as to which instructions need to be executed next and instructions that implement that decision; and other, more specialized types of instructions.11 Of course, adding two numbers together, for example, requires that the numbers be available for use. Possibly the most straightforward way of making them available is to store them in and retrieve them from RAM whenever they are needed, and indeed this is done sometimes. However, as fast as RAM is compared to disk drives (not to mention human beings), it's still pretty slow compared to modern CPUs. For example, the computer I'm using right now has a 500 megahertz (MHz) Pentium III CPU, which can execute an instruction in 2 ns.12 To see why RAM is a bottleneck, let's calculate how long it would take to execute an instruction if all the data had to come from and go back to RAM. A typical instruction would have to read some data from RAM and write its result back there; first, though, the instruction itself has to be loaded (or fetched) into the CPU before it can be executed. Let's suppose we have an instruction in RAM, reading and writing data also in RAM. Then the minimum timing to do such an instruction could be calculated as in Figure 2.1.FIGURE 2.1. RAM vs. CPU speeds

Time 10 ns

Function Read instruction from RAM

10 ns02 ns

Read data from RAM Execute instruction Write result back to RAM Total instruction execution time

10 ns 32 ns

To compute the effective speed of a CPU, we divide 1 second by the time it takes to execute one instruction.13 Given the assumptions in this example, the CPU could execute only about 31 MIPS (million instructions per second), which is a far cry from the 500 MIPS or more that we might expect.14 This seems very wasteful; is there a way to get more speed? In fact, there is. As a result of a lot of research and development both in academia and in the semiconductor industry, it is possible to approach the rated performance of fast CPUs, as will be illustrated in Figure 2.12. Some of these techniques have been around for as long as we've had computers; others have fairly recently trickled down from supercomputers to microcomputer CPUs. One of the most important of these techniques is the use of a number of different kinds of storage devices having different performance characteristics; the arrangement of these devices is called the memory hierarchy. Figure 2.2 illustrates the memory hierarchy of my home machine. Susan and I had a short discussion about the layout of this figure.Susan: OK, just one question on Figure 2.2. If you are going to include the disk in this hierarchy, I don't know why you have placed it over to the side of RAM and not above it, since it is slower and you appear to be presenting this figure in ascending order of speed from the top of the figure downward. Did you do this because it is external rather than internal memory and it doesn't "deserve" to be in the same lineage as the others? Steve: Yes; it's not the same as "real" memory, so I wanted to distinguish it.

Before we get to the diagram, I should explain that a cache is a small amount of fast memory where frequently used data are stored temporarily. According to this definition, RAM functions more or less as a cache for the disk; after all, we have to copy data from a slow disk into fast RAM before we can use it for anything. However, while this is a valid analogy, I should point out that the situations aren't quite parallel. Our programs usually read data from disk into RAM explicitly; that is, we're

aware of whether it's on the disk or in RAM, and we have to issue commands to transfer it from one place to the other. On the other hand, caches are "automatic" in their functioning. We don't have to worry about them and our programs work in exactly the same way with them as without them, except faster. In any event, the basic idea is the same: to use a faster type of memory to speed up repetitive access to data usually stored on a slower storage device. We've already seen that the disk is necessary to store data and programs when the machine is turned off, while RAM is needed for its higher speed in accessing data and programs we're currently using.15 But why do we need the external cache? Actually, we've been around this track before when we questioned why everything isn't loaded into RAM rather than read from the disk as needed; we're trading speed for cost. To have a cost-effective computer with good performance requires the designer to choose the correct amount of each storage medium. So just as with the disk vs. RAM trade-off, the reason that we use the external cache is to improve performance. While RAM can be accessed about 100 million times per second, the external cache is made from a faster type of memory chip, which can be accessed about 250 million times per second. While not as extreme as the speed differential between disk and RAM, it is still significant. However, we can't afford to use external cache exclusively instead of RAM because there isn't enough of it. Therefore, we must reserve external cache for tasks where speed is allimportant, such as supplying frequently used data or programs to the CPU.FIGURE 2.2. A memory hierarchy

The same analysis applies to the trade-off between the external cache and the internal cache. The internal cache's characteristics are similar to those of the external cache, but to a greater degree; it's even smaller and faster, allowing access at the rated speed of the CPU. Both characteristics have to do with its privileged position on the same chip as the CPU; this reduces the delays in communication between the internal cache and the CPU, but means that chip area devoted to the

cache has to compete with area for the CPU, as long as the total chip size is held constant. Unfortunately, we can't just increase the size of the chip to accommodate more internal cache because of the expense of doing so. Larger chips are more difficult to make, which reduces their yield, or the percentage of good chips. In addition, fewer of them fit on one wafer, which is the unit of manufacturing. Both of these attributes make larger chips more expensive to make.

How Caches Improve PerformanceTo oversimplify a bit, here's how caching reduces the effects of slow RAM. Whenever a data item is requested by the CPU, there are three possibilities.1. It is already in the internal cache. In this case, the value is sent to the CPU without referring to RAM at all. 2. It is in t