Day 1
Getting Started
Introduction
Welcome to Teach Yourself C++ in 21 Days! Today you will get started on
your way to becoming a proficient C++ programmer. You'll learn
-
Why C++ is the emerging standard in software development.
-
The steps to develop a C++ program.
-
How to enter, compile, and link your first working C++ program.
A Brief History of C++
Computer languages have undergone dramatic evolution since the first electronic
computers were built to assist in telemetry calculations during World War
II. Early on, programmers worked with the most primitive computer instructions:
machine language. These instructions were represented by long strings of
ones and zeroes. Soon, assemblers were invented to map machine instructions
to human-readable and -manageable mnemonics, such as ADD and MOV.
In time, higher-level languages evolved, such as BASIC and COBOL. These
languages let people work with something approximating words and sentences,
such as Let I = 100. These instructions were translated back into
machine language by interpreters and compilers. An interpreter translates
a program as it reads it, turning the program instructions, or code, directly
into actions. A compiler translates the code into an intermediary form.
This step is called compiling, and produces an object file. The compiler
then invokes a linker, which turns the object file into an executable program.
Because interpreters read the code as it is written and execute the
code on the spot, interpreters are easy for the programmer to work with.
Compilers, however, introduce the extra steps of compiling and linking
the code, which is inconvenient. Compilers produce a program that is very
fast each time it is run. However, the time-consuming task of translating
the source code into machine language has already been accomplished.
Another advantage of many compiled languages like C++ is that you can
distribute the executable program to people who don't have the compiler.
With an interpretive language, you must have the language to run the program.
For many years, the principle goal of computer programmers was to write
short pieces of code that would execute quickly. The program needed to
be small, because memory was expensive, and it needed to be fast, because
processing power was also expensive. As computers have become smaller,
cheaper, and faster, and as the cost of memory has fallen, these priorities
have changed. Today the cost of a programmer's time far outweighs the cost
of most of the computers in use by businesses. Well-written, easy-to-maintain
code is at a premium. Easy- to-maintain means that as business requirements
change, the program can be extended and enhanced without great expense.
Programs
The word program is used in two ways: to describe individual instructions,
or source code, created by the programmer, and to describe an entire piece
of executable software. This distinction can cause enormous confusion,
so we will try to distinguish between the source code on one hand, and
the executable on the other.
-
New Term: A program can
be defined as either a set of written instructions created by a programmer
or an executable piece of software.
Source code can be turned into an executable program in two ways: Interpreters
translate the source code into computer instructions, and the computer
acts on those instructions immediately. Alternatively, compilers translate
source code into a program, which you can run at a later time. While interpreters
are easier to work with, most serious programming is done with compilers
because compiled code runs much faster. C++ is a compiled language.
Solving Problems
The problems programmers are asked to solve have been changing. Twenty
years ago, programs were created to manage large amounts of raw data. The
people writing the code and the people using the program were all computer
professionals. Today, computers are in use by far more people, and most
know very little about how computers and programs work. Computers are tools
used by people who are more interested in solving their business problems
than struggling with the computer.
Ironically, in order to become easier to use for this new audience,
programs have become far more sophisticated. Gone are the days when users
typed in cryptic commands at esoteric prompts, only to see a stream of
raw data. Today's programs use sophisticated "user-friendly interfaces,"
involving multiple windows, menus, dialog boxes, and the myriad of metaphors
with which we've all become familiar. The programs written to support this
new approach are far more complex than those written just ten years ago.
As programming requirements have changed, both languages and the techniques
used for writing programs have evolved. While the complete history is fascinating,
this book will focus on the transformation from procedural programming
to object-oriented programming.
Procedural, Structured, and
Object-Oriented Programming
Until recently, programs were thought of as a series of procedures that
acted upon data. A procedure, or function, is a set of specific instructions
executed one after the other. The data was quite separate from the procedures,
and the trick in programming was to keep track of which functions called
which other functions, and what data was changed. To make sense of this
potentially confusing situation, structured programming was created.
The principle idea behind structured programming is as simple as the
idea of divide and conquer. A computer program can be thought of as consisting
of a set of tasks. Any task that is too complex to be described simply
would be broken down into a set of smaller component tasks, until the tasks
were sufficiently small and self-contained enough that they were easily
understood.
As an example, computing the average salary of every employee of a company
is a rather complex task. You can, however, break it down into these subtasks:
-
1. Find out what each person earns.
2. Count how many people you have.
3. Total all the salaries.
4. Divide the total by the number of people you have.
Totaling the salaries can be broken down into
-
1. Get each employee's record.
2. Access the salary.
3. Add the salary to the running total.
4. Get the next employee's record.
In turn, obtaining each employee's record can be broken down into
-
1. Open the file of employees.
2. Go to the correct record.
3. Read the data from disk.
Structured programming remains an enormously successful approach for dealing
with complex problems. By the late 1980s, however, some of the deficiencies
of structured programing had became all too clear.
First, it is natural to think of your data (employee records, for example)
and what you can do with your data (sort, edit, and so on) as related ideas.
Second, programmers found themselves constantly reinventing new solutions
to old problems. This is often called "reinventing the wheel," and is the
opposite of reusability. The idea behind reusability is to build components
that have known properties, and then to be able to plug them into your
program as you need them. This is modeled after the hardware world--when
an engineer needs a new transistor, she doesn't usually invent one, she
goes to the big bin of transistors and finds one that works the way she
needs it to, or perhaps modifies it. There was no similar option for a
software engineer.
-
New Term: The way we are now using
computers--with menus and buttons and windows--fosters a more interactive,
event-driven approach to computer programming. Event-driven means
that an event happens--the user presses a button or chooses from a menu--and
the program must respond. Programs are becoming increasingly interactive,
and it has became important to design for that kind of functionality.
Old-fashioned programs forced the user to proceed step-by-step through
a series of screens. Modern event-driven programs present all the choices
at once and respond to the user's actions.
Object-oriented programming attempts to respond to these needs, providing
techniques for managing enormous complexity, achieving reuse of software
components, and coupling data with the tasks that manipulate that data.
The essence of object-oriented programming is to treat data and the
procedures that act upon the data as a single "object"--a self-contained
entity with an identity and certain characteristics of its own.
C++ and Object-Oriented Programming
C++ fully supports object-oriented programming, including the four pillars
of object-oriented development: encapsulation, data hiding, inheritance,
and polymorphism. Encapsulation and Data Hiding When an engineer needs
to add a resistor to the device she is creating, she doesn't typically
build a new one from scratch. She walks over to a bin of resistors, examines
the colored bands that indicate the properties, and picks the one she needs.
The resistor is a "black box" as far as the engineer is concerned--she
doesn't much care how it does its work as long as it conforms to her specifications;
she doesn't need to look inside the box to use it in her design.
The property of being a self-contained unit is called encapsulation.
With encapsulation, we can accomplish data hiding. Data hiding is the highly
valued characteristic that an object can be used without the user knowing
or caring how it works internally. Just as you can use a refrigerator without
knowing how the compressor works, you can use a well-designed object without
knowing about its internal data members.
Similarly, when the engineer uses the resistor, she need not know anything
about the internal state of the resistor. All the properties of the resistor
are encapsulated in the resistor object; they are not spread out through
the circuitry. It is not necessary to understand how the resistor works
in order to use it effectively. Its data is hidden inside the resistor's
casing.
C++ supports the properties of encapsulation and data hiding through
the creation of user-defined types, called classes. You'll see how to create
classes on Day 6, "Basic Classes." Once created, a well-defined class acts
as a fully encapsulated entity--it is used as a whole unit. The actual
inner workings of the class should be hidden. Users of a well-defined class
do not need to know how the class works; they just need to know how to
use it. Inheritance and Reuse When the engineers at Acme Motors want to
build a new car, they have two choices: They can start from scratch, or
they can modify an existing model. Perhaps their Star model is nearly perfect,
but they'd like to add a turbocharger and a six-speed transmission. The
chief engineer would prefer not to start from the ground up, but rather
to say, "Let's build another Star, but let's add these additional capabilities.
We'll call the new model a Quasar." A Quasar is a kind of Star, but one
with new features.
C++ supports the idea of reuse through inheritance. A new type, which
is an extension of an existing type, can be declared. This new subclass
is said to derive from the existing type and is sometimes called a derived
type. The Quasar is derived from the Star and thus inherits all its qualities,
but can add to them as needed. Inheritance and its application in C++ are
discussed on Day 12, "Inheritance," and Day 15, "Advanced Inheritance."
Polymorphism The new Quasar might respond differently than a Star does
when you press down on the accelerator. The Quasar might engage fuel injection
and a turbocharger, while the Star would simply let gasoline into its carburetor.
A user, however, does not have to know about these differences. He can
just "floor it," and the right thing will happen, depending on which car
he's driving.
C++ supports the idea that different objects do "the right thing" through
what is called function polymorphism and class polymorphism. Poly means
many, and morph means form. Polymorphism refers to the same name taking
many forms, and is discussed on Day 10, "Advanced Functions," and Day 13,
"Polymorphism."
How C++ Evolved
As object-oriented analysis, design, and programming began to catch on,
Bjarne Stroustrup took the most popular language for commercial software
development, C, and extended it to provide the features needed to facilitate
object-oriented programming. He created C++, and in less than a decade
it has gone from being used by only a handful of developers at AT&T
to being the programming language of choice for an estimated one million
developers worldwide. It is expected that by the end of the decade, C++
will be the predominant language for commercial software development.
While it is true that C++ is a superset of C, and that virtually any
legal C program is a legal C++ program, the leap from C to C++ is very
significant. C++ benefited from its relationship to C for many years, as
C programmers could ease into their use of C++. To really get the full
benefit of C++, however, many programmers found they had to unlearn much
of what they knew and learn a whole new way of conceptualizing and solving
programming problems.
The ANSI Standard
The Accredited Standards Committee, operating under the procedures of the
American National Standards Institute (ANSI), is working to create an international
standard for C++.
The draft of this standard has been published, and a link is available
at www.libertyassociates.com.
The ANSI standard is an attempt to ensure that C++ is portable--that
code you write for Microsoft's compiler will compile without errors, using
a compiler from any other vendor. Further, because the code in this book
is ANSI compliant, it should compile without errors on a Mac, a Windows
box, or an Alpha.
For most students of C++, the ANSI standard will be invisible. The standard
has been stable for a while, and all the major manufacturers support the
ANSI standard. We have endeavored to ensure that all the code in this edition
of this book is ANSI compliant.
Should I Learn C First?
The question inevitably arises: "Since C++ is a superset of C, should I
learn C first?" Stroustrup and most other C++ programmers agree. Not only
is it unnecessary to learn C first, it may be advantageous not to do so.
This book attempts to meet the needs of people like you, who come to C++
without prior experience of C. In fact, this book assumes no programming
experience of any kind.
Preparing to Program
C++, perhaps more than other languages, demands that the programmer design
the program before writing it. Trivial problems, such as the ones discussed
in the first few chapters of this book, don't require much design. Complex
problems, however, such as the ones professional programmers are challenged
with every day, do require design, and the more thorough the design, the
more likely it is that the program will solve the problems it is designed
to solve, on time and on budget. A good design also makes for a program
that is relatively bug-free and easy to maintain. It has been estimated
that fully 90 percent of the cost of software is the combined cost of debugging
and maintenance. To the extent that good design can reduce those costs,
it can have a significant impact on the bottom-line cost of the project.
The first question you need to ask when preparing to design any program
is, "What is the problem I'm trying to solve?" Every program should have
a clear, well-articulated goal, and you'll find that even the simplest
programs in this book do so.
The second question every good programmer asks is, "Can this be accomplished
without resorting to writing custom software?" Reusing an old program,
using pen and paper, or buying software off the shelf is often a better
solution to a problem than writing something new. The programmer who can
offer these alternatives will never suffer from lack of work; finding less-expensive
solutions to today's problems will always generate new opportunities later.
Assuming you understand the problem, and it requires writing a new program,
you are ready to begin your design.
Your Development Environment
This book makes the assumption that your computer has a mode in which you
can write directly to the screen, without worrying about a graphical environment,
such as the ones in Windows or on the Macintosh.
Your compiler may have its own built-in text editor, or you may be using
a commercial text editor or word processor that can produce text files.
The important thing is that whatever you write your program in, it must
save simple, plain-text files, with no word processing commands embedded
in the text. Examples of safe editors include Windows Notepad, the DOS
Edit command, Brief, Epsilon, EMACS, and vi. Many commercial word processors,
such as WordPerfect, Word, and dozens of others, also offer a method for
saving simple text files.
The files you create with your editor are called source files, and for
C++ they typically are named with the extension .CPP, .CP,
or .C. In this book, we'll name all the source code files with
the .CPP extension, but check your compiler for what it needs.
NOTE: Most C++ compilers don't
care what extension you give your source code, but if you don't specify
otherwise, many will use .CPP by default.
DO use a simple text editor to create your source code, or use the built-in
editor that comes with your compiler. DON'T use a word processor that saves
special formatting characters. If you do use a word processor, save the
file as ASCII text. DO save your files with the .C, .CP,
or .CPP extension. DO check your documentation for specifics about
your compiler and linker to ensure that you know how to compile and link
your programs.
Compiling the Source Code
Although the source code in your file is somewhat cryptic, and anyone who
doesn't know C++ will struggle to understand what it is for, it is still
in what we call human-readable form. Your source code file is not a program,
and it can't be executed, or run, as a program can.
To turn your source code into a program, you use a compiler. How you
invoke your compiler, and how you tell it where to find your source code,
will vary from compiler to compiler; check your documentation. In Borland's
Turbo C++ you pick the RUN menu command or type
tc <filename>
from the command line, where <filename> is the name
of your source code file (for example, test.cpp). Other compilers
may do things slightly differently.
NOTE: If you compile the source
code from the operating system's command line, you should type the following:
For the Borland C++ compiler: bcc
<filename>
For the Borland C++ for Windows compiler: bcc
<filename>
For the Borland Turbo C++ compiler: tc
<filename>
For the Microsoft compilers: cl <filename>
After your source code is compiled, an object file is produced. This file
is often named with the extension .OBJ. This is still not an executable
program, however. To turn this into an executable program, you must run
your linker.
Creating an Executable File
with the Linker
C++ programs are typically created by linking together one or more OBJ
files with one or more libraries. A library is a collection of linkable
files that were supplied with your compiler, that you purchased separately,
or that you created and compiled. All C++ compilers come with a library
of useful functions (or procedures) and classes that you can include in
your program. A function is a block of code that performs a service, such
as adding two numbers or printing to the screen. A class is a collection
of data and related functions; we'll be talking about classes a lot, starting
on Day 5, "Functions."
The steps to create an executable file are
-
1. Create a source code file, with a .CPP extension.
2. Compile the source code into a file with the .OBJ
extension.
3. Link your OBJ file with any needed libraries to produce an
executable program.
The Development Cycle
If every program worked the first time you tried it, that would be the
complete development cycle: Write the program, compile the source code,
link the program, and run it. Unfortunately, almost every program, no matter
how trivial, can and will have errors, or bugs, in the program. Some bugs
will cause the compile to fail, some will cause the link to fail, and some
will only show up when you run the program.
Whatever type of bug you find, you must fix it, and that involves editing
your source code, recompiling and relinking, and then rerunning the program.
This cycle is represented in Figure 1.1, which diagrams the steps in the
development cycle.
Figure
1.1. The steps in the development of a C++ program.
HELLO.CPPYour First C++ Program
Traditional programming books begin by writing the words Hello World
to the screen, or a variation on that statement. This time-honored tradition
is carried on here.
Type the first program directly into your editor, exactly as shown.
Once you are certain it is correct, save the file, compile it, link it,
and run it. It will print the words Hello World to your screen.
Don't worry too much about how it works, this is really just to get you
comfortable with the development cycle. Every aspect of this program will
be covered over the next couple of days.
WARNING: The following listing
contains line numbers on the left. These numbers are for reference within
the book. They should not be typed in to your editor. For example, in line
1 of Listing 1.1, you should enter:
#include <iostream.h>
Listing
1.1. HELLO.CPP, the Hello World program.
1: #include <iostream.h>
2:
3: int main()
4: {
5: cout << "Hello World!\n";
6: return 0;
7: }
Make certain you enter this exactly as shown. Pay careful attention to
the punctuation. The << in line 5 is the redirection symbol,
produced on most keyboards by holding the Shift key and pressing the comma
key twice. Line 5 ends with a semicolon; don't leave this off!
Also check to make sure you are following your compiler directions properly.
Most compilers will link automatically, but check your documentation. If
you get errors, look over your code carefully and determine how it is different
from the above. If you see an error on line 1, such as cannot find
file iostream.h, check your compiler documentation for directions
on setting up your include path or environment variables. If you
receive an error that there is no prototype for main, add the
line int main(); just before line 3. You will need to add this
line before the beginning of the main function in every program
in this book. Most compilers don't require this, but a few do.
Your finished program will look like this:
1: #include <iostream.h>
2:
3:
4: int main();
5: {
6: cout <<"Hello World!\n";
7: return 0;
8: }
Try running HELLO.EXE; it should write
Hello World!
directly to your screen. If so, congratulations! You've just entered, compiled,
and run your first C++ program. It may not look like much, but almost every
professional C++ programmer started out with this exact program.
Compile Errors
Compile-time errors can occur for any number of reasons. Usually they are
a result of a typo or other inadvertent minor error. Good compilers will
not only tell you what you did wrong, they'll point you to the exact place
in your code where you made the mistake. The great ones will even suggest
a remedy!
You can see this by intentionally putting an error into your program.
If HELLO.CPP ran smoothly, edit it now and remove the closing
brace on line 6. Your program will now look like Listing 1.2.
Listing
1.2. Demonstration of compiler error.
1: #include <iostream.h>
2:
3: int main()
4: {
5: cout << "Hello World!\n";
6: return 0;
Recompile your program and you should see an error that looks similar
to the following:
Hello.cpp, line 5: Compound statement missing terminating } in function main().
This error tells you the file and line number of the problem, and what
the problem is (although I admit it is somewhat cryptic). Note that the
error message points you to line 5. The compiler wasn't sure if you intended
to put the closing brace before or after the cout statement on
line 5. Sometimes the errors just get you to the general vicinity of the
problem. If a compiler could perfectly identify every problem, it would
fix the code itself.
Summary
After reading this chapter, you should have a good understanding of how
C++ evolved and what problems it was designed to solve. You should feel
confident that learning C++ is the right choice for anyone interested in
programming in the next decade. C++ provides the tools of object-oriented
programming and the performance of a systems-level language, which makes
C++ the development language of choice.
Today you learned how to enter, compile, link, and run your first C++
program, and what the normal development cycle is. You also learned a little
of what object-oriented programming is all about. You will return to these
topics during the next three weeks.
Q&A
-
Q. What is the difference between a text editor and a word processor?
A. A text editor produces files with plain text in them.
There are no formatting commands or other special symbols required by a
particular word processor. Text files do not have automatic word wrap,
bold print, italics, and so forth.
Q. If my compiler has a built-in editor, must I use it?
A. Almost all compilers will compile code produced by any text
editor. The advantages of using the built-in text editor, however, might
include the ability to quickly move back and forth between the edit and
compile steps of the development cycle. Sophisticated compilers include
a fully integrated development environment, allowing the programmer to
access help files, edit, and compile the code in place, and to resolve
compile and link errors without ever leaving the environment.
Q. Can I ignore warning messages from my compiler?
A. Many books hedge on this one, but I'll stake myself to this
position: No! Get into the habit, from day one, of treating warning messages
as errors. C++ uses the compiler to warn you when you are doing something
you may not intend. Heed those warnings, and do what is required to make
them go away.
Q. What is compile time?
A. Compile time is the time when you run your compiler, as opposed
to link time (when you run the linker) or run-time (when running the program).
This is just programmer shorthand to identify the three times when errors
usually surface.
Workshop
The Workshop provides quiz questions to help you solidify your understanding
of the material covered and exercises to provide you with experience in
using what you've learned. Try to answer the quiz and exercise questions
before checking the answers in Appendix D, and make sure you understand
the answers before continuing to the next chapter.
Quiz
-
1. What is the difference between an interpreter and a compiler?
2. How do you compile the source code with your compiler?
3. What does the linker do?
4. What are the steps in the normal development cycle?
Exercises
-
1. Look at the following program and try to guess what it does without
running it.
1: #include <iostream.h>
2: int main()
3: {
4: int x = 5;
5: int y = 7;
6: cout "\n";
7: cout << x + y << " " << x * y;
8: cout "\n";
9:return 0;
10: }
-
2. Type in the program from Exercise 1, and then compile and link
it. What does it do? Does it do what you guessed?
3. Type in the following program and compile it. What error
do you receive?
|