Download C++ 1: Introduction to C++ - O`Reilly School of Technology

Transcript
C++ 1: Introduction to C++ (PDF)
Lesson 1: Introduction
Learning C++
Hist ory of C++
About Eclipse
Perspect ives and t he Red Leaf Icon
Writ ing Your First Program
What Does It All Mean?
Adding t o Our Program
What Goes On Under t he Hood
Finishing t he Program
T he User Manual
T he T est Plan
A Few More Not es
Lesson 2: Expressions
Mat hemat ical Expressions
Creat ing t he Project and File
Edit ing and Running Your Program
T ypes of Numbers
Float ing-Point vs. Int eger Division
Dividing by Zero
Limit s on Numbers
Common Problems
Lesson 3: Variables
Basic Programs
Variables
Variable Def init ions
Variable T ypes: Int eger
Variable T ypes: Float ing Point
Variable T ypes: Charact ers
Escape Charact ers
Wide Charact ers
Boolean
Mixing T ypes
Lesson 4 : Arrays and For Loops
Using Arrays
T he const Modif ier
Our f irst array
f or loops
Array Saf et y
Lesson 5: C++ Strings
St rings in C++
Charact ers in st rings
Ot her Funct ions
Lesson 6: C-Style Strings
What is a C-St yle St ring?
Concat enat ion of C-St yle St rings
Comparing St rings
T ips
Convert ing C++ St rings t o C-St yle St rings
Unsaf e St ring Funct ions
T he f ut ure of st rcpy() and st rcat ()
Comparisons t o ot her t ypes
C St rings vs. Arrays of Charact ers
C-St yle vs. C++ St yle
Lesson 7: Reading Data and if
Reading St rings
Reading Int egers
if St at ement s
if Abuse
Equalit y or Assignment ?
Blocks
Condit ional Short cut s
Lesson 8: Shortcuts
Operat ors
For Loops
For Loop Misuse
Side Ef f ect s
Lesson 9: While Loops
while, break, and cont inue
Fibonacci numbers
Lesson 10: Scope
What is Scope?
Global Variables
St orage Class
f or Loop Scope
Hidden Variables
Lesson 11: Functions
What is a Funct ion?
Our First Funct ion
Void Funct ions and Array Paramet ers
Funct ion Overloading
Def ault Paramet ers
Lesson 12: Parameters and Return T ypes
Passing Paramet ers
Pass by Value
Array Paramet ers
Const Paramet ers
Ref erences
Const Ret urn Values
Problems wit h Ref erence Ret urns
Lesson 13: Final Project
Put t ing It All T oget her
Assignment
Code Design
Agile Development
Coding Not es
T est ing
Revisions
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Introduction
C++ 1: Introduction to C++ Lesson 1
Welco me to the O'Reilly Scho o l o f Techno lo gy's C++ co urse! We're glad yo u've decided to go o n this ride with us and learn
C++ pro gramming. By the time yo u finish the co urse, we're co nfident that yo u'll have firm grasp o n this really practical
pro gramming language.
If yo u've already taken an O'Reilly Scho o l o f Techno lo gy (OST) co urse, yo u're familiar with the useractive appro ach to learning.
It's an appro ach where yo u (the user) will be active! Yo u'll learn by do ing, building live pro grams, testing them, and then
experimenting with them, hands-o n!
Learning with O'Reilly School of T echnology Courses
As with every O'Reilly Scho o l o f Techno lo gy co urse, we'll take the useractive appro ach to learning. This means that
yo u (the user) will be active! Yo u'll learn by do ing, building live pro grams, testing them and experimenting with them—
hands-o n!
To learn a new skill o r techno lo gy, yo u have to experiment. The mo re yo u experiment, the mo re yo u learn. Our system
is designed to maximize experimentatio n and help yo u learn to learn a new skill.
We'll pro gram as much as po ssible to be sure that the principles sink in and stay with yo u.
Each time we discuss a new co ncept, yo u'll put it into co de and see what YOU can do with it. On o ccasio n we'll even
give yo u co de that do esn't wo rk, so yo u can see co mmo n mistakes and ho w to reco ver fro m them. Making mistakes
is actually ano ther go o d way to learn.
Here are so me tips fo r using O'Reilly Scho o l o r Techno lo gy co urses effectively:
T ype t he co de . Resist the temptatio n to cut and paste the example co de we give yo u. Typing the co de
actually gives yo u a feel fo r the pro gramming task. Then play aro und with the examples to find o ut what else
yo u can make them do , and to check yo ur understanding. It's highly unlikely yo u'll break anything by
experimentatio n. If yo u do break so mething, that's an indicatio n to us that we need to impro ve o ur system!
T ake yo ur t im e . Learning takes time. Rushing can have negative effects o n yo ur pro gress. Slo w do wn and
let yo ur brain abso rb the new info rmatio n tho ro ughly. Taking yo ur time helps to maintain a relaxed, po sitive
appro ach. It also gives yo u the chance to try new things and learn mo re than yo u o therwise wo uld if yo u
blew thro ugh all o f the co ursewo rk to o quickly.
Expe rim e nt . Wander fro m the path o ften and explo re the po ssibilities. We can't anticipate all o f yo ur
questio ns and ideas, so it's up to yo u to experiment and create o n yo ur o wn. Yo ur instructo r will help if yo u
go co mpletely o ff the rails.
Acce pt guidance , but do n't de pe nd o n it . Try to so lve pro blems o n yo ur o wn. Go ing fro m
misunderstanding to understanding is the best way to acquire a new skill. Part o f what yo u're learning is
pro blem so lving. Of co urse, yo u can always co ntact yo ur instructo r fo r hints when yo u need them.
Use all available re so urce s! In real-life pro blem-so lving, yo u aren't bo und by false limitatio ns; in OST
co urses, yo u are free to use any reso urces at yo ur dispo sal to so lve pro blems yo u enco unter: the Internet,
reference bo o ks, and o nline help are all fair game.
Have f un! Relax, keep practicing, and do n't be afraid to make mistakes! Yo ur instructo r will keep yo u at it
until yo u've mastered the skill. We want yo u to get that satisfied, "I'm so co o l! I did it!" feeling. And yo u'll have
so me pro jects to sho w o ff when yo u're do ne.
Lesson Format
We'll try o ut lo ts o f examples in each lesso n. We'll have yo u write co de, lo o k at co de, and edit existing co de. The co de
will be presented in bo xes that will indicate what needs to be do ne to the co de inside.
Whenever yo u see white bo xes like the o ne belo w, yo u'll type the co ntents into the edito r windo w to try the example
yo urself. The CODE TO TYPE bar o n to p o f the white bo x co ntains directio ns fo r yo u to fo llo w:
CODE TO TYPE:
White boxes like this contain code for you to try out (type into a file to run).
If you have already written some of the code, new code for you to add looks like this.
If we want you to remove existing code, the code to remove will look like this.
We may run pro grams and do so me o ther activities in a terminal sessio n in the o perating system o r o ther co mmandline enviro nment. These will be sho wn like this:
INTERACTIVE SESSION:
The plain black text that we present in these INTERACTIVE boxes is
provided by the system (not for you to type). The commands we want you to type look lik
e this.
Co de and info rmatio n presented in a gray OBSERVE bo x is fo r yo u to inspect and absorb. This info rmatio n is o ften
co lo r-co ded, and fo llo wed by text explaining the co de in detail:
OBSERVE:
Gray "Observe" boxes like this contain information (usually code specifics) for you to
observe.
The paragraph(s) that fo llo w may pro vide additio n details o n inf o rm at io n that was highlighted in the Observe bo x.
We'll also set especially pertinent info rmatio n apart in "No te" bo xes:
Note
T ip
No tes pro vide info rmatio n that is useful, but no t abso lutely necessary fo r perfo rming the tasks at hand.
Tips pro vide info rmatio n that might help make the to o ls easier fo r yo u to use, such as sho rtcut keys.
WARNING
Warnings pro vide info rmatio n that can help prevent pro gram crashes and data lo ss.
Learning C++
C++ is the wo rkho rse language o f the pro gramming wo rld. It's used fo r many different applicatio ns, fro m high-end
graphics systems to embedded pro cessing. Chances are yo u already o wn two o r three co mputers running C++
pro grams, o nly they aren't called co mputers, they're called cell pho nes, GPS systems, cameras, o r DVD players.
Our co urse is designed to teach yo u ho w to do real-wo rld, practical pro gramming. As such, it will teach no t o nly the
best practices when it co mes to design and co ding, but also ho w to deal with the "wo rst practices" that seem to seep
into many o f the pro grams o ut there in the real wo rld.
Fo r this co urse, we will use the Advanced O'Reilly Learning Sandbo x. This system allo ws yo u no t o nly to read the
lesso ns, but to interact with the examples. Yo u are enco uraged to experiment and try new things, all within the
enviro nment o f yo ur O'Reilly Learning Sandbo x.
Of co urse, in the real wo rld yo u'll make mistakes. Typing in a pro gram, finding that it's bro ken, and sweating o ver it until
2 o 'clo ck in the mo rning, o nly to find yo u've made a small mistake, is ano ther way o f learning. (We ho pe yo u will rarely
need to use this metho d o f learning!)
History of C++
C++ was bo rn in 19 70 when two pro grammers wanted a "high-level" language fo r a machine they were
wo rking o n. They designed a language similar to an o ld language they had been using called B. In the
pro gramming traditio n o f keeping things simple, they named their language C.
C was a go o d language fo r its day. It ran o n very limited hardware (4mhz, 6 4K memo ry) and did a pretty go o d
jo b. The language was also designed no t to get in the way o f the pro grammer. In o ther wo rds, if he wanted to
do so mething stupid, it let him.
C is a pro cedural language. The data and instructio ns are kept separate. Ten years after its inventio n, peo ple
realized that they co uld make better pro grams if they co mbined data and the instructio ns that o perated o n the
data into o ne thing called an o bject o r class.
In 19 8 0 Bjarne Stro ustrup started wo rking o n a new language called "C with classes." The go al o f the
language was to bring classes to C while no t breaking existing C co de (o r at least no t breaking it to o badly).
This language wo uld beco me C++.
About Eclipse
We're using an Integrated Develo pment Enviro nment (IDE) called Eclipse. It's the pro gram filling up yo ur screen right
no w. IDEs assist pro grammers by perfo rming many o f the tasks that need to be do ne repetitively. IDEs can also help
to edit and debug co de, and o rganize pro jects.
Perspectives and the Red Leaf Icon
The Ellipse plug-in fo r Eclipse, develo ped by the O'Reilly Scho o l o f Techno lo gy, adds an ico n to the to o lbar
in Eclipse. This ico n is yo ur "panic butto n." Eclipse is versatile and lets yo u mo ve things like views and
to o lbars. If yo u ever get co nfused and want to return to the default perspective (windo w layo ut), the Red Leaf
ico n is the mo st efficient way to do that.
Yo u can also change perspectives by clicking the dro p-do wn arro w beside the ico n, and then clicking a series
name (JAVA, PYTHON, C++, etc.). Mo st o f the perspectives lo o k similar, but subtle changes may be present
"under the ho o d," so it's best to use the perspective designed specifically fo r each co urse.
Fo r this co urse, select C++:
Okay, no w that yo u understand the basic structure o f an OST co urse, yo u're ready to enter and run co de!
Writing Your First Program
We want yo u to see a wo rking C++ pro gram as so o n as po ssible, so we'll resist the urge to explain to o much fo r this
first pro gram while yo u're creating and running it. Let's get go ing—we'll fill yo u in o n the details later!
To start yo ur pro ject, select File | Ne w | C++ Pro je ct , as sho wn here:
Note
If C++ Pro je ct isn't o n the menu, then the perspective hasn't been set pro perly. Click the do wn arro w
next to the Red Leaf ico n and then select C++
The C++ Pro ject type dialo g appears. Fo r Pro ject Name, enter he llo _wo rld.
Note
Due to limitatio ns in the GNU to o ls, all pro ject names and file names sho uld co nsist o f o nly letters,
digits, and undersco res. Do no t use punctuatio n o r spaces in a name. It co nfuses the to o ls and causes
things to break.
Fo r "Pro ject Type," select Exe cut able | Em pt y Pro je ct . Under "To o lchains," select MiniGW GCC (the default). Then,
click Finish:
If yo u are pro mpted to o pen the C++ perspective, check the "Remember my decisio n" bo x and click No :
New pro jects are added by default to the Other Pro jects wo rking set. To help keep yo ur pro jects o rganized, we'll mo ve
them to the C++1_Lesso ns wo rking set. Find the he llo _wo rld pro ject in the Other Pro jects set, right-click it, and select
Assign Wo rking Se t s.... In the dialo g bo x that appears, check the bo x fo r C++1_Le sso ns and click OK:
No w we'll set up the pro ject's building behavio r. Right-click the he llo _wo rld pro ject again, and then select
Pro pe rt ie s. Select C/C++ Build, then click the Be havio r tab. Check the Build o n re so urce save (Aut o build) bo x
and click OK:
Yo u will need to do this fo r every pro ject yo u create. If yo u do n't, when yo u try to run pro grams fro m the pro ject, yo u'll
see this message: "Launch failed. Binary no t fo und." It isn't po ssible to set this flag as the default. But just in case yo u
need to refresh yo ur memo ry o n o ccasio n, we've pro vided a checklist o f the steps yo u need to take in o rder to start a
pro ject.
Okay, we're ready to create o ur pro gram. Find the hello _wo rld pro ject in the C++1_Lesso ns wo rking set and select it,
then select File | Ne w | So urce File :
Enter the name he llo .cpp and click Finish:
The new file he llo .cpp appears, with a sho rt header co ntaining the filename, the date, and yo ur name. In he llo .cpp,
add co de as sho wn belo w:
CODE TO TYPE:
/*
* hello.cpp
*
* Created on: Dec 15, 2009
*
Author: smiller
*/
#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
return(0);
}
As yo u type, yo u'll no tice that the system auto matically co mpletes certain items. Fo r instance, when yo u type <, it adds
a >. And after yo u enter the line that co ntains int m ain() {, Eclipse auto matically indents the next line by fo ur spaces
and adds the clo sing bracket } o n the fo llo wing line. Eclipse is yo ur friend, and do es its best to help whenever it can!
Select File | Save All to save yo ur file:
Co ngratulatio ns, yo u've just written yo ur first C++ pro gram! No w let's run it. In the edito r windo w fo r yo ur he llo .cpp
pro gram, right-click and select Run as | Lo cal C++ Applicat io n:
Note
To run a pro gram, yo u can also select it in the Package Explo rer and click the Run ico n ( ) in the to o lbar
at the to p o f the screen. In the future, we'll use that ico n when we want to run the pro gram.
A Co nso le windo w appears, co ntaining the o utput fro m yo ur pro gram:
Excellent! Yo u've run yo ur first C++ pro gram!
No w let's screw it up. We're do ing that o n purpo se no w, so we'll kno w what it lo o ks like and ho w to fix it when we
screw up o ur pro grams later by accident.
Mo dify he llo .cpp as sho wn belo w:
CODE TO TYPE:
#include <iostream>
int main() {
standard::cout << "Hello World!" << std::endl;
return(0);
}
Note
We o mit the header co mments fro m so me o f o ur examples in o rder to save space. In yo ur real
pro grams, yo u sho uld always include descriptive co mments.
Save yo ur file (File | Save all). A red ico n appears o n the left side o f the panel near the line yo u just changed. If yo u put
the mo use po inter o n the ico n, yo u'll see this message:
This tells yo u that so mething bad happened. In particular, the co mpiler can't figure o ut what the symbo l st andard
means.
Fix the pro blem by changing st andard back to st d, then save the file. The red ico n sho uld go away.
No w let's create a new pro blem fo r o urselves. Mo dify he llo .cpp belo w as sho wn:
CODE TO TYPE:
#include <iostream>
int main() { int
std::cout << "Hello World!" << std::endl;
return(0);
}
Save the file. Yo u'll see an x erro r ico n o n the the st d::co ut line:
So what happened? Eclipse flags erro rs with an x erro r ico n. Ideally, it appears o n the line where yo u made the
mistake, but so metimes (like no w), it do esn't. (Ho wever, in this case yo u do see a small yello w bo x co ntaining a
questio n mark o n the int m ain line. Eclipse's internal parser detected an erro r o n this line and flagged it that way.)
When Eclipse flags erro rs in yo ur pro gram, yo u still might need to do so me investigative wo rk to find and fix them—
and it's a go o d idea to check the lines o f co de surro unding the flagged o nes as well.
Fix the pro blem in he llo .cpp by remo ving the misplaced int , then save yo ur wo rk.
What Does It All Mean?
Let's take a clo ser lo o k at the pro gram to see ho w it wo rks:
OBSERVE: hello .cpp
#include <iostream>
int main()
{
std::cout << "Hello World!" << std::endl;
return(0);
}
The first line is # include <io st re am >. This #include line tells C++ "I'm go ing to use yo ur standard streaming
I/O package (io stream)." The co mpiler brings in the definitio ns o f the items fo r this package.
The next line, int m ain(), is the start o f the co de fo r yo ur pro gram. The m ain() functio n is special in C++; it is
the first functio n that C++ executes. We'll get into functio n definitio ns later—fo r no w, yo u just need to kno w that
this special line starts the pro gram.
The curly brace { indicates the start o f the bo dy o f the co de. Co de enclo sed in braces is called a block. In this
pro gram, we have o ne blo ck o f statements and they make up the bo dy o f the m ain() functio n. In later lesso ns
we'll learn ho w to use multiple blo cks o f co de.
The next line co ntains st d::co ut << " He llo Wo rld!" << st d::e ndl;, which is a C++ executable statement. It
tells C++ to print a message. Yo u'll no tice that the line starts with fo ur spaces. C++ do esn't care ho w many
spaces yo u use to start a line, but go o d pro gramming style dictates that yo u use o ne level o f indentatio n fo r
each level o f lo gic. Here we indented fo ur spaces fo r each set o f braces we have nested. We cho se to indent
fo ur spaces as a standard because it's easy to read and we needed a standard fo r this co urse.
Let's break the st d::co ut statement do wn into co mpo nents.
The first item, st d::co ut , is the name o f a predefined variable that is used by C++ to write to the standard
o utput (the co nso le). (In the Eclipse pro gramming enviro nment, co nso le o utput sho ws up in a windo w at the
bo tto m o f the screen.) The st d::co ut variable is o ne o f the items bro ught in by the # include <io st re am >
statement.
The o perato r << tells C++ to take what fo llo ws it and send it so mewhere else, in this case to the o utput
(st d::co ut ). Next in o ur co de, we have the string " He llo Wo rld" . This is a literal string co ntaining the
characters we want to display o n the co nso le.
This is fo llo wed by << again (which sends whatever fo llo ws it to the o utput stream o n the left) and the symbo l
st d::e ndl. The st d::e ndl symbo l tells C++ to o utput an end-o f-line character. The statement ends with a
semico lo n.
Next, we have the return line re t urn(0 );, which tells C++ to end the pro gram and return a status o f 0 to the
o perating system. (Yo u'll learn mo re abo ut the return statement later, but fo r no w all yo u need to kno w is that
inside main, it ends the pro gram.) A return co de o f 0 indicates a no rmal exit. Co des 1-255 typically indicate
that the pro gram exited abno rmally—the bigger the number, the bigger the pro blem.
Again, the statement ends with a semico lo n.
At the very end we have a clo sing brace } . This ends the blo ck o f co de that started at the brace just after the
m ain() line.
Adding to Our Program
No w let's say we want to o utput ano ther line o f text. To do that, we can add ano ther line to o utput an additio nal
message. Edit yo ur pro gram as sho wn (using yo ur o wn name instead o f "Steve"):
CODE TO TYPE:
/*
#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
std::cout << "My name is Steve!" << std::endl;
return(0);
}
Save yo ur file, then run it by right-clicking in he llo .cpp in the edito r windo w and cho o sing Run as | Lo cal
C++ Applicat io n (alternatively yo u co uld click the Run ico n in the to o lbar). Yo u'll see this o utput:
OBSERVE:
Hello World!
My name is Steve!
Our o utput appears o n two lines because we used st d::e ndl. Ano ther way to make the o utput appear o n two
lines is to use the special escaped character \n. Mo dify he llo .cpp as sho wn:
CODE TO TYPE:
#include <iostream>
int main() {
std::cout << "Hello World!" << "\n";
std::cout << "My name is Steve!" << "\n";
return(0);
}
Save yo ur pro gram, and run it. The o utput lo o ks identical to the last run:
OBSERVE:
Hello World!
My name is Steve!
\n is called an escape character. The backslash (\) "escapes" fro m the regular interpretatio n o f keybo ard
characters to begin a special multi-character sequence, indicating a special character. In this case, it's a
"newline," o r end o f line, the equivalent o f pressing the Enter key.
Fo r mo re info rmatio n, see the glo ssary's descriptio n o f the escape character.
But the escape character is the o ld-fashio ned way to print a newline. The mo re mo dern practice is to use the
special symbo l st d::e ndl. There is a subtle difference between \n and st d::e ndl; the st d::e ndl symbo l
causes a buffer flush, which makes sure the o utput appears immediately. The \n is no t required to flush the
buffer (altho ugh o n mo st systems it do es).
We co ver buffering and flushing in mo re detail in later C++ co urses.
What Goes On Under the Hood
Eclipse is a type o f to o l called an IDE o r Integrated Development Environment. This so rt o f to o l is a wrapper aro und
many o ther to o ls. The idea o f the IDE is to hide the o ther to o ls and give yo u a single system in which to wo rk. But as a
pro fessio nal, yo u'll need to kno w what go es o n "under the ho o d" to make the mo st effective use o f all the to o ls
available.
When yo ur pro ject is built, Eclipse figures o ut what needs to be do ne to make yo ur pro grams executable,
auto matically. This co mes in handy fo r many types o f pro grams, including o ur small "hello wo rld" pro ject. To o ls like
Visual Studio wo rk much the same way.
So me pro grams use o ther builder to o ls to make them auto matically executable—in the C/C++ wo rld, a pro gram called
make is a co mmo n to o l fo r that. In java, Ant is a po pular to o l fo r that task. Bo th o f tho se to o ls require pro grammers to
specify a set o f "rules" o r "targets" that describe ho w a pro gram will be built.
To co nvert yo ur co de into co mputer instructio ns, Eclipse uses the GNU g++ co mpiler. This pro gram takes yo ur so urce
co de (.cpp file) and turns it into an executable. To do this, it needs to run a series o f pro grams. The first is the actual
C++ co mpiler. Its jo b is to take the human-readable so urce co de and turn it into an o bject file (.o file).
Yo u can see the o bject file created by the co mpiler. Switch to the Package Explo rer tab, then expand the De bug fo lder.
Inside that fo lder yo u'll see he llo .o (amo ng o ther things). If yo u try to o pen he llo .o , yo u wo n't find anything useful—
this file co ntains co mputer co de. The o bject file is readable by the co mputer, but no t by humans. The o bject file
co ntains only the co de fo r executing the task that yo u wro te. In the case o f hello _wo rld, that co de uses st d::co ut to
write o ut a message. The definitio n o f st d::co ut is no t in yo ur o bject file; instead it is part o f a standard library. This
library co ntains generally useful definitio ns like std::co ut and lo ts o f o ther things. The library itself is just a bunch o f
o bject files packaged to gether into o ne file (so mething like a zip file, but different).
The linker takes yo ur o bject file and the o bject files in the library and pro duces an executable pro gram. Here's a
graphical representatio n o f what it do es:
With so me co mpilers, yo u may no t see o bject files, because they delete o bject files after the link step.
With the GNU co mpiler, the co mpilatio n pro cess is actually acco mplished by multiple pro grams. The first thing g++
do es to yo ur pro gram is pass it thro ugh a pro gram called the pre-pro cesso r. This pro gram takes care o f things like the
# include directive. (We co ver lo ts mo re abo ut this pro gram in the next C++ co urse.)
The next stage turns the high-level C++ co de into lo w-level assembly co de. In high-level co de, o ne statement can
result in many machine instructio ns being created to pro cess that statement. In assembly language, there's o ne
statement per instructio n. Also , high-level languages are machine-independent (o r they are suppo sed to be.)
Assembly co de is machine-dependent. In o ther wo rds, the assembly language fo r an Intel x8 6 -co mpatible pro cesso r
(such as the Intel Co re 2 Duo o r Intel Pentium) is entirely different fro m the assembly co de fo r the iPho ne's ARM
pro cesso r.
Fo rtunately, all this co mplexity is hidden fro m yo u and yo u can igno re it mo st o f the time. But so metimes yo u may
need to take a peek under the ho o d to deal with any bugs yo u enco unter alo ng the way.
Finishing the Program
Our pro gram, altho ugh syntactically and lo gically co rrect, is no t co mplete because it only contains the default comments
produced by Eclipse. A co mment is text in the pro gram that tells peo ple reading the pro gram what's go ing o n.
Co mments are no t read by the co mputer and altho ugh it is po ssible to write a pro gram with no co mments in it, we will
no t do so in this co urse. Pro fessio nal pro gramming means creating pro fessio nal-quality pro grams with co mments—
even if that pro gram is "Hello Wo rld."
All o f yo ur pro grams sho uld begin with a co mment blo ck that co ntains these sectio ns:
The lesso n and pro ject number (so the instructo r kno ws which questio n yo u're answering).
A descriptio n sectio n that describes what the pro gram is suppo sed to do .
A usage sectio n.
Co mments begin with /* and end with */. Co mments can also begin with // and go to the end o f the line.
Our pro gram needs a set o f co mments. Mo dify he llo .cpp as sho wn:
CODE TO TYPE:
/*
* Lesson 1, Example 1 (Or Assignment 1 for programs you turn in)
*
* Description: The classic "Hello World" program. Prints
* out the message and that's all.
*
* Usage: Run it and get the message.
*/
// This is another way to comment a single line.
#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
return(0);
}
Save and run it to verify that it still wo rks as expected.
T he User Manual
Are we finished? No t yet—a pro gram isn't any go o d if no o ne kno ws ho w to use it, so we'll write a user
manual fo r every pro gram.
Yo u may wo nder ho w to go abo ut writing a manual fo r such a sho rt pro gram. Fo r a sho rt pro gram, we just
write a sho rt manual.
To create yo ur manual, select the hello _wo rld pro ject and then select File | Ne w | Ot he r. In the New File
Wizard, select Ge ne ral | File . Name yo ur file manual.txt. No w write the manual:
CODE TO TYPE:
Run the program.
See the message.
T he T est Plan
Finally, the pro gram needs a test plan. Our test plan sho uld have these attributes:
It sho uld test as much o f the pro gram as is feasible.
It must list a precise set o f steps to fo llo w (ambiguo us instructio ns lead to results that canno t be
repro duced).
Its results must be o bservable.
It must lead to a clearly o bservable pass/fail result.
Fo r example, a test plan that says, "Play aro und with the so ftware and see if yo u can break it," is a vague and
therefo re pretty bad test plan.
First, the term "Play aro und" is no t precise. Different peo ple co uld "play aro und" in different ways.
Seco nd, what happens if so meo ne breaks the so ftware? Can he do it again? Often, the answer to this
questio n is no .
Third, the term "break" is no t defined. If the system crashes, that certainly is a break. But what if it merely draws
so mething that lo o ks o dd? Is that "o dd" drawing a feature o r a bug?
No w we'll write o ur clear, brief, and excellent test plan. Create a file called test.txt, then type in the co de as
sho wn:
CODE TO TYPE:
1. Run the program.
2. Observe the message "Hello World!" (Yes -- Pass, No -- Fail)
A Few More Notes
We reco mmend that yo u use the Save All menu o ptio n to save yo ur wo rk; this will save everything yo u have o pened,
and it can prevent pro blems when running yo ur pro grams while yo u're wo rking o n them.
Do not put spaces o r o ther special characters in file names. Limit yo urself to a co mbinatio n o f letters, digits,
undersco res (_), and dashes (-) This helps to avo id pro blems with the to o l set being used.
When yo u create a new so urce file, it always co ntains the standard header, including the file name, date, and yo ur
name. Yo u sho uld replace tho se elements with mo re detailed and specific info rmatio n abo ut yo ur pro gram.
Remember, when using the O'Reilly sandbo x system, that Red Leaf ico n is yo ur emergency butto n. It will resto re yo ur
screen to the o riginal layo ut:
Co ngratulatio ns! Yo u have created yo ur first C++ pro gram and co mpleted lesso n 1 o f the co urse! In the next lesso n, we'll
investigate expressio ns. See yo u there!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Expressions
C++ 1: Introduction to C++ Lesson 2
Glad to see yo u're back! In this lesso n we'll learn to use mathematical expressio ns in C++.
Mathematical Expressions
C++ understands these o peratio ns:
+
Additio n
-
Subtractio n
*
Multiplicatio n
/
Divisio n
% Mo dulus (remainder after divisio n)
We can co mbine these o peratio ns with numbers into an expressio n to do useful lo ts o f really useful wo rk.
Let's get go ing and try an example to see ho w these o perato rs wo rk. Start a new pro ject and name it e xpe xpre ssio n. Assign it to the C++1_Le sso ns wo rking set. Then create a new so urce file in the new e xp-e xpre ssio n
pro ject and name it e xp-e xpre ssio n.cpp. No w create the pro ject and so urce file. Yo u can see a graphical
representatio n o f this pro cedure in the next sectio n. But if yo u feel co mfo rtable with the pro cess so far, go ahead and
skip to the fo llo wing sectio n.
Creating the Project and File
Select File | Ne w | C++ Pro je ct , enter the info rmatio n, and click Finish, as sho wn:
If yo u are pro mpted to change the perspective, check the Re m e m be r m y de cisio n bo x and click No :
Assign the C++1_Le sso ns wo rking set to the e xp-e xpre ssio n pro ject; right-click the pro ject, select Assign
Wo rking Se t s..., and assign the wo rking set as sho wn:
In the Package Explo rer, right-click the e xp-e xpre ssio n pro ject, select Pro pe rt ie s, and set the Build
pro perties as sho wn:
No w, in the e xp-e xpre ssio n pro ject, select File | Ne w | So urce File , and enter info rmatio n as sho wn:
Editing and Running Your Program
Open yo ur e xp-e xpre ssio n.cpp file and enter the fo llo wing co de (we'll o mit the auto matic co mments fro m
no w o n to save space):
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "The answer is " << (1 + 2) * 4 << std::endl;
return (0);
}
Save yo ur so urce file, then in the edito r windo w fo r e xp-e xpre ssio n.cpp, right-click and select Run as |
Lo cal C++ Applicat io n (o r select e xp-e xpre ssio n.cpp in the Package Explo rer and click the
the to o lbar). Yo u'll see this o utput:
ico n in
OBSERVE:
The answer is 12
The co mputer evaluated, o r calculated, the answer to the expressio n (1 + 2) * 4 (which is 12) and sho wed yo u
the results.
So , ho w did the parentheses affect the answer? I'm glad yo u asked! Let's remo ve them and see what
happens—edit yo ur co de as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "The answer is " << (1 + 2) * 4 << std::endl;
return (0);
}
Save and run yo ur pro gram. This time the answer is different:
OBSERVE:
The answer is 9
The co mputer reads the expressio n 1 + 2 * 4 fro m left to right, but it also fo llo ws the Order o f Operatio ns:
1. expo nents and ro o ts
2. multiplicatio n and divisio n
3. additio n and subtractio n
Multiplicatio n o ccurs befo re additio n, so the co mputer actually do es this:
2*4=8
1+8 =9
Yo u can change the Order o f Operatio ns by using parentheses ( ). In the first example, we used parentheses
to fo rce additio n to o ccur befo re multiplicatio n.
T ypes of Numbers
There are two majo r types o f numbers in C++: integers and floating point. (Yo u might also hear abo ut a complex type,
but that type isn't actually built into the language.)
Integers, also kno wn as whole numbers have no fractio nal value. Fo r example, these are all integers:
OBSERVE:
1
324290
42
-999
37
Flo ating-po int numbers co ntain a fractio nal part. Fo r example:
OBSERVE:
1.2
3.5
14.8
37.0
The last number presents a key co ncept: 37 .0 is a flo ating-po int number. Even tho ugh the fractio nal part is 0 , its
presence after the decimal po int makes 37 .0 a flo ating-po int number. The number 37 is an integer.
Note
When writing flo ating-po int numbers, always include a decimal po int. It tells anyo ne reading yo ur co de
that yo u intend the value to be flo ating po int. So 1.0 is go o d, and 1 is bad. 0 .0 is go o d; 0 is bad.
Flo ating-po int numbers can also co ntain an o ptio nal expo nent. Fo r example:
OBSERVE:
13.33E+5
This tells C++ that the value o f the number is 13.33 x 10 5 .
Floating-Point vs. Integer Division
Edit e xp-e xpre ssio n.cpp to co mpute (and print) the value o f the expressio n 1/3 as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "The answer is " << 1 / 3 << std::endl;
return (0);
}
Save and run it, then read the o utput:
OBSERVE:
The answer is 0
When C++ do es integer divisio n, the result is an integer—it truncates any fractio nal part o f the result.
No w, edit e xp-e xpre ssio n.cpp again, as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "The answer is " << 1.0 / 3.0 << std::endl;
return (0);
}
Save and run it and lo o k o ver the o utput:
OBSERVE:
The answer is 0.333333
When C++ sees that the arguments are flo ating-po int numbers, it perfo rms flo ating-po int divisio n and gives
flo ating-po int results.
But what if o ne number is flo ating po int and the o ther is an integer? Let's give that a try. Mo dify e xpe xpre ssio n.cpp as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "The answer is " << 1.0 / 3 << std::endl;
return (0);
}
Save and run it and read o ver yo ur results. Try 1 / 3.0 as well. No w that yo u've seen ho w mixed-mo de
arithmetic will affect yo ur pro grams, avo id using it if at all po ssible. Fo r no w, that may be difficult, but later we'll
learn abo ut casing, which will let us explicitly tell the co mpiler which types o f numbers (and therefo re
o peratio ns) to use.
Dividing by Zero
We canno t divide anything by zero —that o peratio n isn't defined and the expressio n has no meaning. So what
happens if we tell the co mputer to divide by zero ? Mo dify yo ur pro gram to co mpute a new expressio n that
divides by zero as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "Divide " << (1/0) << std::endl;
return (0);
}
Save yo ur pro gram, and igno re the warning message.
message:
Run it and o bserve that it terminates with this
The co mputer can't handle this type o f math, so the pro gram sto ps with a warning. Click OK to end the
pro gram.
But what happens when yo u divide by zero with a flo ating-po int number? Try it and find o ut; edit yo ur pro gram
belo w as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "Divide " << (1.0/0) << std::endl;
return (0);
}
Save and run it. Yo u'll see o utput like:
OBSERVE:
Divide inf
The flo ating-po int fo rmat used by basic Intel-co mpatible pro cesso rs has special "numbers" defined fo r erro r
co nditio ns such as inf , -inf , and NaN (no t a number). This is pro cesso r-dependent and altho ugh almo st all
mo dern pro cesso rs no w use this standard fo rmat, so me do n't. Results o n tho se co mputers co uld be
different.
So no w yo u may be wo ndering why integer divisio n by zero crashes yo ur pro gram, while flo ating po int
divisio n by zero do es no t. This is by design—Intel-co mpatible pro cesso rs have been used fo r decades, and
at first co uld o nly perfo rm integer arithmetic. Flo ating-po int arithmetic was handled separately, and thus it
co ntinues to generate different erro rs.
Instead o f wo rrying abo ut the differences in erro r handling, it is better no t to generate the erro r in the first place.
In future lesso ns we'll learn ho w to make sure o ur pro grams wo rk co rrectly. Stay tuned!
Limits on Numbers
Suppo se yo u have an o ld eight-digit calculato r. Yo u type in the number 9 9 ,9 9 9 ,9 9 9 and then add 1 to it. The
result is a nine-digit number, which the calculato r can't display. So the calculato r displays ERROR.
There are similar limits to the numbers in C++. Unfo rtunately, these are no t hard limits. They can vary
depending o n the pro cesso r type, co mpiler, and o perating system.
C++ has a file (named climits) that defines the limits o n its basic types. We'll # include this file, and then add
so me co de to use it. Edit yo ur e xp-e xpre ssio n.cpp pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
#include <climits>
int main()
{
std::cout << "INT_MAX " << INT_MAX << std::endl;
return (0);
}
Save and run it. Yo u'll see this:
OBSERVE:
INT_MAX 2147483647
Note
This example uses the C-style constant fo r the integer limit. The pure C++ way o f do ing this is to
include the header file <limits>. Then yo u can get the maximum integer with the expressio n
st d::num e ric_lim it s<int >::m ax(). We used the C metho d because it's sho rter. Also , to
understand the expressio n st d::num e ric_lim it s<int >::m ax(), yo u need to understand
classes, static member functio ns, templates and template specializatio n—all co ncepts we will
co ver in a future co urse.
Let's see what happens when we go past the limit. Change the pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
#include <climits>
int main()
{
std::cout << "INT_MAX+1 " << INT_MAX+1 << std::endl;
return (0);
}
Based o n the last executio n o f the pro gram, we might expect to see the number 214748 36 48 .
Instead we see:
Run it.
OBSERVE:
INT_MAX+1 -2147483648
This is called overflow. It o ccurs when a number beco mes to o big o r to o small to fit into its type (in this case,
integer). C++ do es no t check fo r o verflo w and will no t warn yo u when it o ccurs. Yo u wo n't enco unter this
pro blem to o o ften, but if yo u do , no w yo u'll be able to reco gnize and co rrect it.
Okay, no w let's see what happens when we have a flo ating-po int o verflo w. Because o f the way flo ating-po int
numbers are sto red and co mputed, it's hard to specify an exact maximum number. But the expressio n belo w
will definitely give yo u an o verflo w, so go ahead and add it to yo ur pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
#include <climits>
int main()
{
std::cout << "Float " << (9E399 * 9E399) << std::endl;
return (0);
}
Run it. Yo u'll see the special flo ating-po int number inf ; the flo ating system gives yo u so me indicatio n that
an o verflo w o ccurred.
Common Problems
There are so me co mmo n warnings and erro rs that yo u may enco unter when wo rking with C++. We'll experiment with
so me o f them by making a few mistakes o n purpo se. Change yo ur pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
#include <climits>
int main()
{
std::cout << "The answer is" << (1 + 2) * 4;
return (0);
}
C++ flags this line with an erro r message because it do esn't reco gnize st d::co ut .
The st d::co ut functio nality is defined in io st re am , so in o rder to use st d::co ut , we have to include io st re am in o ur
pro gram. Edit the pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
#include <climits>
int main()
{
(1 + 2) * 4;
return (0);
}
When yo u co mpile the pro gram, yo u'll no tice a warning triangle next to the line that co ntains the expressio n. Lo o k in
the Co nso le panel to see the text asso ciated with the warning:
The warning reminds us that o ur expressio n do esn't really do anything—we do no t o utput its results o r save them
anywhere.
Save and run it. The o utput windo w co ntains abso lutely no thing. In particular, it do es no t co ntain the result o f the
calculatio n. The line (1 + 2) * 4 tells C++ to co mpute the value o f the expressio n, but no thing mo re. It do esn't sto re the
result anywhere, do esn't make a decisio n based o n the result, and do esn't o utput it. C++ just co mputes the answer
and then thro ws it away.
This is perfectly legal, but pretty strange—so strange that the co mpiler issues a warning when yo u build it. That's why
yo u go t the "no effect" warning. Let's fix the pro gram by editing it as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "The answer is" << (1 + 2) * 4;
return (0);
}
Save and run it. Yo u'll see this:
OBSERVE:
The answer is12
Do yo u see a pro blem in this co de? That's right—we need a space between "is" and the answer. Add the space as
sho wn (we use an undersco re here to represent the space):
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "The answer is_" << (1 + 2) * 4;
return (0);
}
Save and run it. Hmm. There's still a pro blem. See if yo u can spo t it. We'll add ano ther o utput statement (as sho wn
in blue belo w) to help illuminate the pro blem:
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "The answer is " << (1 + 2) * 4;
std::cout << "The answer still is " << (1 + 2) * 4;
return (0);
}
Save and run it. The o utput lo o ks like this:
OBSERVE:
The answer is 12The answer still is 12
Any additio nal o utput statements will be appended to the end o f this o ne. Yo u need to add a newline at the end o f the
o utput line. Edit the pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
std::cout << "The answer is " << (1 + 2) * 4 << std::endl;
std::cout << "The answer still is " << (1 + 2) * 4 << std::endl;
return (0);
}
Save and run it to make sure that the pro blem has been co rrected.
We co vered a lo t in this lesso n! We went o ver expressio ns, integers, and flo ating po int numbers. No w yo u're ready to tackle the
next lesso n, where we'll discuss pro gram structure and variables. See yo u there!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Variables
C++ 1: Introduction to C++ Lesson 3
Basic Programs
We have to walk befo re we can run, so we're go ing to learn to pro gram fo r no w in a subset o f the C++ language. Our
basic pro gram structure is:
OBSERVE:
/* File heading comments */
#include directives
int main() {
data declarations
executable statements
return (0);
}
Note
In so me bo o ks and co de examples, the dat a de clarat io ns are placed befo re the int m ain line. In these
lesso ns, they co me after it. At this stage, fo r the types o f pro grams we can currently write, either o rder will
wo rk. (We'll learn the difference between the two types o f declaratio ns later.)
It is easier to use Eclipse if yo u put the dat a de clarat io ns just after the first brace ({).
The include dire ct ive s, dat a de clarat io ns, and e xe cut able st at e m e nt s sectio ns are o ptio nal, so the sho rtest
po ssible C++ pro gram wo uld have all three sectio ns o mitted:
OBSERVE:
int main()
{
return(0);
}
Such a pro gram may appear to be useless, but it's actually a standard Linux/Unix co mmand, true. It's used in shell
scripting as a co mmand that always returns a go o d status (0 ) to the currently running script.
Variables
A variable is a bit o f yo ur co mputer's memo ry, like a bo x, in which yo u can put a single item o f data. We must declare
variables befo re we use them. In o rder to declare a variable, C++ needs two pieces o f info rmatio n: the name and the
type (what the bo x is called, and what type o f bo x it is).
In o rder to pass this co urse, yo u'll need to add a third piece o f info rmatio n: A co mment explaining what the variable is
used fo r.
A variable name begins with a letter (upper o r lo wer case) o r an undersco re (_), then co ntinues with any co mbinatio n
o f letters, undersco res, o r digits. It canno t be the same as any C++ keywo rd.
Fo r example, these are legal variable names:
OBSERVE:
box_width
whatever
point_count
point3
These are no t legal variable names:
today
dataField
OBSERVE:
3times // Begins with a digit
box-top // Contains hyphen
Variable names are usually lo wer case (size , f ull_size o r mo stly lo wer case (Size , FullSize , f ullSize . Co nstants
are usually given upper-case-o nly names (PI, MAX_INT ). No thing in the language fo rces yo u to fo llo w this
co nventio n, but if yo u cho o se to igno re it, do n't be surprised if a mo b o f angry maintenance pro grammers sho ws up
o utside yo ur do o r with to rches and pitchfo rks.
Style No te: There are two majo r ways o f co nstructing variable names. The first is separating wo rds with undersco res:
OBSERVE:
box_width
point_count
data_size
The o ther is so mething called "CamelCase":
OBSERVE:
boxWidth
pointCount
dataSize
In practice, there's no t a lo t o f difference in the readability o f the two styles, but there is a great benefit to picking one
style and sticking to it.
The style guide fo r this co urse requires yo u to use the undersco re style.
Variable Definitions
A variable definitio n co nsists o f three parts:
OBSERVE:
{type} {name};
// {Comment explaining the variable}
The co m m e nt is not o ptio nal—at least no t in this co urse. The reaso n is that a pro gram is a set o f instructio ns to the
co mputer that uses a unique (to that pro gram!) vo cabulary. I mean if yo u see a variable named ce nt e r_po int in co de,
the first questio n yo u are go ing to ask yo urself is "Center o f what?" By co mmenting every variable declaratio n, yo u
pro duce a mini-dictio nary describing every specialized wo rd (variable) yo u use in yo ur pro gram. It makes
understanding the pro gram much easier.
Variable T ypes: Integer
The C++ keywo rd fo r the integer type is int (Glo ssary integer, int). A integer variable declaratio n lo o ks like this:
OBSERVE:
int x;
// example variable
The int declaratio n tells C++ to declare an integer variable using the o ptimal size o f an integer fo r the machine. On
most machines, this allo ws numbers fro m 214748 36 47 to -214748 36 48 to be used. On so me o lder systems, this is
just 3276 7 to -3276 8 and o n so me newer systems, it's −9 ,223,372,0 36 ,8 54,775,8 0 8 to
+9 ,223,372,0 36 ,8 54,775,8 0 7.
This is the difference between 32-bit, 16-bit, and 64-bit integers. Unless yo u are interested in the technical details
regarding the physical sto rage o f integers within yo ur co mputer's pro cesso r, yo u do n't need to remember the
difference between bit sizes and number ranges. Instead, remember there are different ways to sto re this data and
remember to use the co nstants we saw earlier, such as INT _MAX.
Think o f a variable as a bo x. Yo u can put a single integer in it and yo u can lo o k in it and see what's in it. Let's lo o k at
this in actio n. Create a pro ject named assign-e xp in yo ur C++1_Le sso ns wo rking set, and a pro gram named
assign-e xp.cpp that co ntains the fo llo wing co de:
CODE TO TYPE:
// Put in the regular heading comments
#include <iostream>
int main() {
int play;
// An integer to play around with
play = 5;
std::cout << "The value of play is " << play << std::endl;
return(0);
}
Save and run it. This pro gram assigns the variable play a single value and then uses it in an o utput. Yo u'll see the
results:
OBSERVE:
The value of play is 5
The pro gram sto res "5" in the variable named play and then displays that value to yo u.
Variables can change values as pro grams execute, and play is no exceptio n. Let's see ho w the value o f play changes
as the pro gram executes. Change yo ur pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
int main() {
int play; // An integer to play around with
std::cout << "At first, the value of play is " << play << std::endl;
play = 5;
std::cout << "The value of play is " << play << std::endl;
play = -999;
std::cout << "Finally, the value of play is " << play << std::endl;
return(0);
}
Save and run it. Yo u sho uld see the fo llo wing o utput:
OBSERVE:
At first, the value of play is 0
The value of play is 5
Finally, the value of play is -999
If we stepped thro ugh the pro gram, we'd see the value o f play after each line is executed. We might see the fo llo wing:
Line
int play;
value o f play
undefined
std::co ut << "At first, the value o f play is " << play << std::endl; undefined
play = 5;
5
std::co ut << "The value o f play is " << play << std::endl;
5
play = -9 9 9 ;
-9 9 9
std::co ut << "The value o f play is " << play << std::endl;
-9 9 9
return(0 );
-9 9 9
BUT WAIT! This table sho ws that the initial value o f play is undefined, but the o utput sho ws that it was 0 !
Befo re we assign play a value fo r the first time—befo re the play = 5 line—its value is no t kno wn, and canno t be
assumed to be anything. With this specific co mputer, co mpiler, and executio n, the value happened to be 0 . A different
co mputer, co mpiler, o r executio n co uld pro duce any o ther result, such as 10 0 , 9 0 0 , o r -214748 36 48 !
The bo tto m line: don't assume your variable has a value before you give it a value!
In C++, yo u can declare and initialize variables in o ne statement. Change assign-exp.cpp as sho wn:
CODE TO TYPE:
#include <iostream>
int main() {
int play = 2; // An integer to play around with
std::cout << "At first, the value of play is " << play << std::endl;
play = 5;
std::cout << "The value of play is " << play << std::endl;
play = -999;
std::cout << "Finally, the value of play is " << play << std::endl;
return(0);
}
Save and run it. Yo u sho uld see the fo llo wing o utput:
OBSERVE:
At first, the value of play is 2
The value of play is 5
Finally, the value of play is -999
Variable T ypes: Floating Point
The int is just o ne o f C++'s built-in types. Ano ther majo r type is the flo ating-po int number. Here's an example o f a
typical flo ating po int (f lo at ) declaratio n and use. Create a pro ject named f lo at -play, assign it to the C++1_Le sso ns
wo rking set, and in it, create a f lo at -play.cpp pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
// Floating-point variable declaration...
float area = 5.2 * 3.5; // Area of a rectangle
std::cout << "The area is " << area << std::endl;
return(0);
}
Save and run it. Yo u sho uld see the fo llo wing result:
OBSERVE:
The area is 18.2
Here we saved a step—we declared a variable named are a and assigned it the value o f the expressio n 5 .2 * 3.5 all in
a single line o f co de. C++ do es the math—it evaluates the expressio n and assigns 18.2 to the are a variable.
Variable T ypes: Characters
The character (char) data type sto res a single character. To be mo re specific, it sto res a single character fro m the ASCII
character set. This character set pro vides fo r the letters a-z (upper and lo wer case), the digits 0 -9 , a set o f punctuatio n
characters, and special control characters.
Glo ssary: ASCII Character Set.
Co ntro l characters are no t printed, but instead co ntro l ho w the o utput appears o n the screen.
Character co nstants are enclo sed in single quo tes: 'A', 'B', '?'.
Create a char-play pro ject, assign it to the C++1_Le sso ns wo rking set, and in it, create char-play.cpp as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
char ch1; // First play character
char ch2; // Second play character
char ch3; // Third play character
ch1 = 'A';
ch2 = 'B';
ch3 = 'C';
std::cout << "The characters are " << ch1 << ch2 << ch3 << std::endl;
return(0);
}
Save and run it. Yo u sho uld see the fo llo wing:
OBSERVE:
The characters are ABC
What happens if we try to sho ve mo re than o ne character into a variable? Try it! Change yo ur pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
char ch1; // First play character
char ch2; // Second play character
char ch3; // Third play character
ch1 = 'A';
ch2 = 'B';
ch3 = 'CDEF';
std::cout << "The characters are " << ch1 << ch2 << ch3 << std::endl;
return(0);
}
See the warning? This is the first indicatio n that so mething isn't quite co rrect.
Try running the pro gram. Yo u'll see so mething like:
OBSERVE:
The characters are ABF
Lo o ks like the co mputer wasn't happy with o ur 'CDEF' character, so it dro pped CDE witho ut telling us. Warnings exist
fo r a reaso n—do n't igno re them!
Escape Characters
There is a special character, the backslash (\), which is used to specify characters that canno t be typed inside
single quo tes easily, such as tab ('\t') and newline ('\n'). In these cases, the backslash "escapes" fro m no rmal
rendering o f t and n, allo wing yo u to represent tabs and newlines in pro gram o utput.
So me o f the escape characters are:
\b
Backspace
Mo ve the curso r to the left o ne character.
\f
Fo rm feed
Go to to p o f a new page.
\n
New line
Go to the next line.
\r
Return
Go to the beginning o f the current line.
\t
Tab
Advance to the next tab sto p (eight-co lumn bo undary).
\'
Apo stro phe o r single quo tatio n mark The character ' .
\"
Do uble quo te
The character ".
\\
Backslash
The character \.
\nnn some character
The character number nnn (o ctal).
\xNN some character
The character number NN (hexadecimal).
Edit the pro gram belo w, replacing the value we assign to ch2 as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
char ch1; // First play character
char ch2; // Second play character
char ch3; // Third play character
ch1 = 'A';
ch2 = '\n';
ch3 = 'C';
std::cout << "The characters are " << ch1 << ch2 << ch3 << std::endl;
return(0);
}
Save and run it and o bserve the o utput:
OBSERVE:
The characters are A
C
No w let's try so mething a little different. Change the value o f ch2 to \b, the backspace, as sho wn belo w:
CODE TO TYPE:
#include <iostream>
int main()
{
char ch1; // First play character
char ch2; // Second play character
char ch3; // Third play character
ch1 = 'A';
ch2 = '\b';
ch3 = 'C';
std::cout << "The characters are " << ch1 << ch2 << ch3 << std::endl;
return(0);
}
Save and run it and o bserve the o utput:
OBSERVE:
The characters are A☐C
The display pro bably do esn't lo o k co rrect—depending o n ho w yo ur co mputer handles the backspace
character, yo u might see anything fro m AC to A, so me funny character, and then C.
Wide Characters
The char type suffers fro m the fact that it canno t deal with internatio nal alphabets. To help so lve this pro blem,
the wide character (wchar) type was created. While the char type defines 256 characters, wchar defines
6 5536 .
Ho wever, there are languages (such as Chinese, Japanese, Farsi, Hebrew, and many o thers) that co ntain
even mo re than 6 5536 characters. To display characters fro m tho se languages, a character enco ding system
called Unicode was created.
Suppo rt fo r wide and Unico de characters is dependent o n the co mpiler and o perating system that yo u are
using. We'll discuss this in a future lesso n.
Boolean
The bo o lean type (bo o l) can have the value t rue (which is also o ne, o r 1) o r f alse (which is also zero , o r 0 ).
Create a pro ject named play-bool, assign the C++1_Le sso ns wo rking set to it, and create the pro gram file playbo o l.cpp as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
bool flag; // Boolean to play around with
flag = true; // Set it to true
std::cout << "Flag is " << flag << std::endl;
flag = false; // Set it to false
std::cout << "Flag is " << flag << std::endl;
flag = (1 == 1); // == is the test for equality operator (expression is true)
std::cout << "Flag is " << flag << std::endl;
return(0);
}
Save and run it. Yo u sho uld see the fo llo wing o utput:
OBSERVE:
Flag is 1
Flag is 0
Flag is 1
The co mputer printed the underlying values fo r flag as it was set to true, then false, then true.
Originally, C did no t have a bo o lean type, so peo ple defined their o wn. As a result, yo u may see things like BOOL,
BOOLEAN, Bo o l, T RUE, and FALSE in o lder bo o ks o r co de. Be aware that these are lo cal, no n-standard items.
No w the questio n co mes up, "What sho uld I do abo ut legacy types in my co de?" The best answer is, if the co de wo rks,
leave it alo ne. Yo u co uld waste a lo t o f time and effo rt trying to impro ve wo rking co de and bring it up to current
standards, merely to make it do what it already do es.
If yo u do have to go in and change so mething, and bringing the types up to date will not cause too much trouble, by all
means do so . But do n't change anything just fo r the sake o f changing it.
Mixing T ypes
C++ is very flexible when it co mes to mixing types. If it can figure o ut a co nversio n, it will silently allo w yo u to assign a
co nstant o f o ne type (such as bo o lean) to ano ther (such as integer).
Here are the co nversio ns that o ccur when mixing types:
Result
type
Expressio n
Co nversio n
type
integer
bo o lean
1 fo r true, 0 fo r false (no t guaranteed by the standard, but everyo ne I kno w o f implements it
that way).
flo at
bo o lean
Same as integer.
char
integer
The character who se character number is the number being assigned. This depends o n the
character set o n yo ur system. Fo r mo st systems, this is ASCII, so assigning ch = 6 5 makes
ch an 'A' (ASCII character number 6 5).
integer
flo at
Integer after truncatio n. No te: If the value o f the flo at is bigger than the maximum size the
integer can handle, the integer will get the maximum value.
integer
char
The numeric value o f the character in the current character set.
flo at
char
The numeric value o f the character in the current character set.
bo o lean Numeric
If the number 0 (zero ), the bo o lean variable gets f alse . If no n-zero , the value t rue is
assigned.
Let's try this. Change yo ur pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
bool flag; // Boolean to play around with
flag = true; // Set it to true
float test = flag; // will this work?
flag = false;
std::cout << "Flag is " << flag << std::endl;
std::cout << "Test is " << test << std::endl;
return(0);
}
Save and run it. Yo ur pro gram happily sto res the bo o lean value 1 fro m f lag into t e st . Also no te that, even when
the value o f f lag changes to false (0 ), t e st retains the value o riginally assigned to it:
OBSERVE:
Flag is 0
Test is 1
We learned a lo t abo ut variables and types in this lesso n! In the next lesso n, we'll learn ho w to sto re many values o f the same
data type using arrays. See yo u then!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Arrays and For Loops
C++ 1: Introduction to C++ Lesson 4
Using Arrays
So far, we've o nly learned basic data types and every datum had a name. But suppo se we want to calculate the
average grade fo r twenty students in a class. It's a lo t o f wo rk to define twenty different variables, o ne fo r each number:
OBSERVE:
int student1;
int student2;
int student3;
// I'm not going
...
int student20;
//
//
//
to
A number we are going to average
A number we are going to average
A number we are going to average
write out the whole thing.
// A number we are going to average
Arrays allo w us to define a set o f data—like a gro up o f mailbo xes at an apartment building. Co mpare this to a regular
variable (o ne that isn't an array)—it is like a mailbo x o utside o f a single ho use.
A regular (no n-array) variable is just a single part o f yo ur co mputer's memo ry, but an array is a chunk o f co ntinuo us
memo ry lo catio ns.
Here is ho w we'd declare an array to sto re the same set o f numbers:
OBSERVE:
int students[20];
// The numbers we are going to average
The elements o f the array are st ude nt s[0 ] thro ugh st ude nt s[19 ]. Yo u might expect them to be 1 thro ugh 20 , but in
C++, array element numbering starts at 0 . The numbers—0 , 1, o r 19 —are indexes to the array.
T he const Modifier
Our class might always have twenty students in it, but what if it changes, say, to 35? We wo uld have to go
thro ugh o ur pro gram, find all o f the 20 values relating to o ur st ude nt s array, and change them manually to
35 . This pro cess is erro r-pro ne—after all, there may be o ccurrences o f 20 unrelated to the number o f
students, that we do n't want to change!
Go o d pro gramming practice dictates that we specify the size o f o ur class in o ne place, as a variable, and then
use that variable rather than the literal number in o ur pro gram. Since o ur class size do esn't change very o ften,
we can tell C++ that the variable is a constant.
The co nst mo difier defines a "variable" (actually a co nstant) who se value canno t be changed by the pro gram
when it's running. C/C++ style co nventio ns call fo r the names o f co nstants to be all upper case; fo r example,
co nst int CLASS_SIZ E = 35 .
Ho w do co nstants wo rk? Let's find o ut! Start a new pro ject named co nst ant s, assign it to the
C++1_Le sso ns wo rking set, and in it, create a new so urce file named co nst ant s.cpp as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
const int CLASS_SIZE = 20;
std::cout << "I have " << CLASS_SIZE << " students in my class." << std::end
l;
return(0);
}
Save and run it. If yo u typed everything co rrectly yo u will see the fo llo wing:
OBSERVE:
I have 20 students in my class.
What happens if the pro gram tries to change the value o f CLASS_SIZ E? Try it:
CODE TO TYPE:
#include <iostream>
int main()
{
const int CLASS_SIZE = 20;
std::cout << "I have " << CLASS_SIZE << " students in my class." << std::end
l;
CLASS_SIZE = 35;
std::cout << "Now I have "<< CLASS_SIZE << " students in my class." << std::
endl;
return(0);
}
Save yo ur co de. This time yo ur pro gram wo n't co mpile, because yo u are trying to change a co nstant.
If yo ur number is go ing to change in the middle o f a pro gram run like this, it sho uldn't be defined as a
co nstant. To fix this pro blem, yo u'd need to remo ve the wo rd co nst fro m the variable declaratio n and change
the variable name to an appro priate style, fo r example, class-size .
Yo u sho uld use named co nstants to specify the dimensio ns o f arrays; fo r example, int
st ude nt s[CLASS_SIZ E].
Go o d pro gramming style dictates that yo u sho uld always use named co nstants in this way. In o ther wo rds,
the dimensio n specificatio n o f an array sho uld never be just a number like 20 .
Our first array
No w let's lo o k at arrays in actio n. Create a new pro ject named ave rage , assign it to the C++1_Le sso ns
wo rking set, and in it, create ave rage .cpp as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
const int CLASS_SIZE = 5;
float average = 0.0;
// average of the items
float total = 0.0;
// the total of the data items
float students[CLASS_SIZE]; // data to average and total
students[0]
students[1]
students[2]
students[3]
students[4]
=
=
=
=
=
34.0;
27.0;
46.5;
82.0;
22.0;
total = students[0] + students[1] + students[2] + students[3] + students[4];
average = total / CLASS_SIZE;
std::cout << "Total " << total << " Average " << average << std::endl;
return (0);
}
Save and run it. Yo u sho uld see the fo llo wing result:
OBSERVE:
Total 211.5 Average 42.3
Remember ho w we co uld declare a variable and set its value at the same time? Yo u can also do that fo r
arrays, using {braces}. Change yo ur pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
const int CLASS_SIZE = 5;
float
float
float
erage and
average = 0.0;
// average of the items
total = 0.0;
// the total of the data items
students[CLASS_SIZE] = { 34.0, 27.0, 46.5, 82.0, 22 };
total
students[0]
students[1]
students[2]
students[3]
students[4]
=
=
=
=
=
// data to av
34.0;
27.0;
46.5;
82.0;
22.0;
total = students[0] + students[1] + students[2] + students[3] + students[4];
average = total / CLASS_SIZE;
std::cout << "Total " << total << " Average " << average << std::endl;
return (0);
}
Save and run it. Yo u sho uld see the same results as befo re.
Our co de so far lo o ks go o d, but o ur to tal calculatio n is a bit unwieldy because we'll have to change the
fo rmula each time we change the CLASS_SIZ E. Let's see ho w we can fix that!
for loops
We can have the co mputer calculate the to tal fo r us—after all, it kno ws ho w big CLASS_SIZE is! To do this, we can use
a for loop—which executes a blo ck o f co de a specified number o f times. Change yo ur pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
int main()
{
const int CLASS_SIZE = 5;
int x;
float average = 0.0;
// average of the items
float total = 0.0;
// the total of the data items
float students[CLASS_SIZE] = { 34.0, 27.0, 46.5, 82.0, 22 };
nd total
// data to average a
total = students[0] + students[1] + students[2] + students[3] + students[4];
for (x = 0 ; x < CLASS_SIZE ; x = x + 1)
{
total = total + students[x];
}
average = total / CLASS_SIZE;
std::cout << "Total " << total << " Average " << average << std::endl;
return (0);
}
Save and run it. Yo u sho uld see the same o utput as befo re:
OBSERVE:
Total 211.5 Average 42.3
So ... ho w do es the f o r lo o p wo rk? Take a lo o k at the co de:
OBSERVE:
for (x = 0 ; x < CLASS_SIZE ; x = x + 1)
{
total = total + students[x];
}
In English, this lo o p might be written this way: "fo r x st art ing at ze ro , while x is le ss t han CLASS_SIZ E, x is
incre m e nt e d by o ne after we add e ach st ude nt value t o t he t o t al.
Since x starts at zero and o ur CLASS_SIZE is 5, the co de t o t al = t o t al + st ude nt s[x] will run five times—with x
having the values 0 , 1, 2, 3, and 4.
A fo r lo o p typically has these parts:
OBSERVE:
for (/* Initialization */ ; /* Test */ ; /* Increment */)
{
/* body of loop */
}
In o ur lo o p:
x = 0 is the init ializat io n co de . Arrays start at zero , so x must start at zero as well.
x < CLASS_SIZ E is the t e st co de . Our array o nly has the number o f elements (5) specified by
CLASS_SIZE, but the indexes start at 0 so the last index will be 4; therefo re, we want to sto p lo o ping befo re
x is equal to CLASS_SIZE.
x = x + 1 is the incre m e nt co de. x will increase by o ne after each iteratio n.
t o t al = t o t al + st ude nt s[x] is the bo dy o f lo o p co de, which updates the to tal.
To really see what the fo r lo o p is do ing, let's add so me co de to sho w the values o f x and t o t al inside the lo o p while
it's running:
CODE TO TYPE:
#include <iostream>
int main()
{
const int CLASS_SIZE = 5;
int x;
float average = 0.0;
// average of the items
float total = 0.0;
// the total of the data items
float students[CLASS_SIZE] = { 34.0, 27.0, 46.5, 82.0, 22 };
nd total
// data to average a
for (x = 0 ; x < CLASS_SIZE ; x = x + 1)
{
total = total + students[x];
std::cout << "Students[x = " << x << "]: " << students[x] << "; total: "
tal << std::endl;
}
<< to
average = total / CLASS_SIZE;
std::cout << "Total " << total << " Average " << average << std::endl;
return (0);
}
Save and run it and o bserve the o utput:
OBSERVE:
Students[x = 0]: 34; total: 34
Students[x = 1]: 27; total: 61
Students[x = 2]: 46.5; total: 107.5
Students[x = 3]: 82; total: 189.5
Students[x = 4]: 22; total: 211.5
Total 211.5 Average 42.3
A fo r lo o p can really make sho rt wo rk o f a big list! Suppo se o ur class size gro ws to ten. We can quickly update o ur
pro gram to handle this, simply by updating CLASS_SIZ E and entering values fo r the additio nal students. Update yo ur
pro gram as sho wn. Remember, arrays are zero -based, so we are adding students 5 thro ugh 9 .
CODE TO TYPE:
#include <iostream>
int main()
{
const int CLASS_SIZE = 10;
int x = 0;
float average = 0.0;
// average of the items
float total = 0.0;
// the total of the data items
float students[CLASS_SIZE] =
{ 34.0, 27.0, 46.5, 82.0, 22, 72.3, 55.9, 91.2, 90.0, 43.8 };
ge and total
// data to avera
for (x = 0 ; x < CLASS_SIZE ; x = x + 1)
{
total = total + students[x];
std::cout << "Students[x = " << x << "]: " << students[x] << "; total: "
tal << std::endl;
}
<< to
average = total / CLASS_SIZE;
std::cout << "Total " << total << " Average " << average << std::endl;
return (0);
}
Save and run it. See ho w we didn't have to change the rest o f the pro gram—it just wo rked! Yo ur o utput sho uld lo o k
like this:
OBSERVE:
Students[x = 0]: 34; total: 34
Students[x = 1]: 27; total: 61
Students[x = 2]: 46.5; total: 107.5
Students[x = 3]: 82; total: 189.5
Students[x = 4]: 22; total: 211.5
Students[x = 5]: 72.3; total: 283.8
Students[x = 6]: 55.9; total: 339.7
Students[x = 7]: 91.2; total: 430.9
Students[x = 8]: 90; total: 520.9
Students[x = 9]: 43.8; total: 564.7
Total 564.7 Average 56.47
Array Safety
C++ makes it easy to sto re a lo t o f info rmatio n in an array. What happens if yo u make a mistake—like accidentally lo o p
o ver to o many array elements? Edit the pro gram as sho wn:
CODE TO TYPE:
//********************************************
//*** WARNING: In order to see what happens when we violate the rules, this program del
iberately overflows an array.
//********************************************
#include <iostream>
int main()
{
const int CLASS_SIZE = 10;
int x = 0;
float average = 0.0;
// average of the items
float total = 0.0;
// the total of the data items
float students[CLASS_SIZE] =
{ 34.0, 27.0, 46.5, 82.0, 22 72,3, 55.9, 91.2, 90.0, 43.8 };
e and total
// data to averag
for (x = 0 ; x < 15 ; x = x + 1) // OOPS!!
{
total = total + students[x];
std::cout << "Students[x = " << x << "]: " << students[x] << "; total: "
tal << std::endl;
}
<< to
average = total / CLASS_SIZE;
std::cout << "Total " << total << " Average " << average << std::endl;
return (0);
}
Save the file. No erro r o r warnings will be generated, because the co mputer assumes yo u kno w what yo u are do ing,
and has no t checked to make sure yo u are staying within the bo unds o f the st ude nt s array. What happens when yo u
try to run the pro gram? Run it to find o ut!
Yo ur pro gram may run, and it may crash. If it runs, yo u might see o utput like this:
OBSERVE:
Students[x = 0]: 34; total: 34
Students[x = 1]: 27; total: 61
Students[x = 2]: 46.5; total: 107.5
Students[x = 3]: 82; total: 189.5
Students[x = 4]: 22; total: 211.5
Students[x = 5]: 72.3; total: 283.8
Students[x = 6]: 55.9; total: 339.7
Students[x = 7]: 91.2; total: 430.9
Students[x = 8]: 90; total: 520.9
Students[x = 9]: 43.8; total: 564.7
Students[x = 10]: 3.21401e-039; total: 564.7
Students[x = 11]: 5.95261e-039; total: 564.7
Students[x = 12]: 1129.4; total: 1129.4
Students[x = 13]: 0; total: 1129.4
Students[x = 14]: 1.96182e-044; total: 1129.4
Total 211.5 Average 21.15
See the junk added at the end? Yo ur specific o utput may lo o k different. C++ didn't check to make sure yo u were
staying within the bo unds o f yo ur array, and happily went o n with the pro gram. It is like trying to get mail o ut o f 15
mailbo xes, when o nly 10 physical mailbo xes exist in yo ur apartment building.
What happens if we try to write to an array lo catio n o utside o f CLASS_SIZE? Try it:
Co de to Edit: average.cpp
//********************************************
//*** WARNING: In order to see what happens when we violate the rules, this program del
iberately overflows an array.
//********************************************
#include <iostream>
int main()
{
const int CLASS_SIZE = 10;
int x = 0;
float average = 0.0;
// average of the items
float total = 0.0;
// the total of the data items
float students[CLASS_SIZE] =
{ 34.0, 27.0, 46.5, 82.0, 22 72,3, 55.9, 91.2, 90.0, 43.8 };
e and total
// data to averag
students[500] = 500.0;
for (x = 0 ; x < 15 ; x = x + 1) // OOPS!!
{
total = total + students[x];
std::cout << "x: " << x << " students[x]: " << students[x] << " total: "
tal << std::endl;
}
<< to
average = total / CLASS_SIZE;
std::cout << "Total " << total << " Average " << average << std::endl;
return (0);
}
Save the file. Once again, no erro r o r warnings are generated, because the co mputer assumes yo u kno w what yo u are
do ing and has no t checked to make sure yo u are staying within the bo unds o f the st ude nt s array. What happens
when yo u try to run the pro gram?
Run it to find o ut! Yo ur pro gram will crash, and give an erro r like this:
C++ did no t check to make sure yo ur array index o f 50 0 was valid. Instead, that line executed, and crashed yo ur
pro gram. In C++, when yo u try to access o r write so mething yo u are no t suppo sed to access, any o f these things
might happen:
yo ur pro gram co uld crash.
yo ur co mputer co uld crash, depending o n the o perating system.
yo ur pro gram co uld run and calculate things inco rrectly.
yo ur pro gram co uld run no rmally, o nly to crash later (perhaps waiting until it's shipped to 10 ,0 0 0
custo mers, when it suddenly decides to wipe o ut all their impo rtant data!).
If yo u remember the go o d o ld days o f co mputers and o perating systems—MS-DOS, Windo ws 9 5, and MacOS 7, to
name a few—yo u pro bably remember bugs in applicatio ns that co uld crash the entire co mputer. Tho se bugs were
o ften array pro blems just like this!
In so me o ther languages, yo u might no t need to wo rry so much abo ut checking yo ur array indices. In C++, yo u do . In a
future co urse, we will discuss ways to do uble-check yo ur pro grams to make sure yo u are accessing arrays co rrectly.
Note
In the real wo rld, almo st no o ne checks the array indices befo re using them to access an array. Instead,
they run witho ut checking and spend millio ns o f do llars later to debug the strange and hard-to -find bugs
caused by bad index values. CHECK YOUR CODE!
We co vered a lo t in this lesso n! We learned ho w to use arrays, and ho w to lo o p o ver arrays using fo r lo o ps. In the next lesso n
we'll learn abo ut ano ther type o f variable: strings. See yo u then!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
C++ Strings
C++ 1: Introduction to C++ Lesson 5
Strings in C++
Strings are sequences o f characters yo u can use in a co mputer pro gram. There are two basic ways to use strings—the
newer C++ style strings (which we will learn abo ut in this lesso n), and o lder "C-Style" strings that we will review in the
next lesso n.
To use C++ strings, we need to # include <st ring> at the to p o f o ur pro grams. We can then declare a string with a
statement like:
OBSERVE:
std::string variableName; // comment
Let's see ho w this wo rks. Create a pro ject named st ring, assign it to the C++1_Le sso ns wo rking set, create a so urce
file named st ring.cpp, and enter the fo llo wing co de:
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first;
std::string last;
// First name
// Last name
first = "Joyce";
last = "Kilmer";
std::cout << "My name is " << first << " " << last << std::endl;
return(0);
}
Replace we'll use Jo yce Kilmer in the examples, but yo u sho uld replace Joyce and Kilmer with any names yo u like. As
yo u can see, string co nstants are enclo sed in do uble quo tes ("). Remember that character co nstants are enclo sed in
single quo tes ('). It might help to remember that o ne tick (') is fo r a single character and multiple ticks (") fo r multiple
characters (strings).
Save and run the pro gram. Yo u'll see so mething like:
OBSERVE:
My name is Joyce Kilmer
Excellent! So far, strings wo rk exactly like any o ther variable such as an int o r f lo at .
We learned ho w to add two numbers in a previo us lesso n. Yo u can perfo rm a similar o peratio n o n strings—using the
plus o perato r (+), yo u can concatenate two strings. To see ho w this wo rks, change yo ur pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first;
std::string last;
std::string full;
// First name
// Last name
// The full name
first = "your first name";
last = "your last name";
full = first + " " + last;
std::cout << "My name is " << full << std::endl;
return(0);
}
Save and run it. Yo u'll see the same o utput:
OBSERVE:
My name is Joyce Kilmer
In this pro gram, we co ncatenated the two variables f irst and last (with the space " " in between). What if we tried to
co ncatenate " J o yce " , a space, and " Kilm e r" directly? Change yo ur pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first;
std::string last;
std::string full;
// First name
// Last name
// The full name
first = "Joyce";
last = "Kilmer";
full = "Joyce" + " " + "Kilmer";
std::cout << "My name is " << full << std::endl;
return(0);
}
Oo ps! Lo o ks like C++ isn't happy with us. It gives the fo llo wing erro r:
This is because o f the way the co ncatenate (+) o perato r is defined. There must be a st d::st ring o n at least o ne side o f
the +.
Change yo ur pro gram to fix this pro blem:
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first;
std::string last;
std::string full;
// First name
// Last name
// The full name
first = "Joyce";
last = "Kilmer";
full = first + " " + "Kilmer";
std::cout << "My name is " << full << std::endl;
return(0);
}
Save and run it; yo u'll see the same results as befo re.
Characters in strings
Yo u can access any character in the string using the subscript ([]) o perato r. Change st ring.cpp as sho wn:
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first; // First name
std::string last;
// Last name
std::string full;
// The full name
char first_initial;
// The first initial
first = "Joyce";
last = "Kilmer";
full = first + " " + last;
first_initial = first[0];
// Assigns first_initial the value 'J'.
std::cout << "My first initial is " << first_initial << std::endl;
return(0);
}
Save and run it, and o bserve the o utput:
OBSERVE:
My first initial is J
This [] syntax might remind yo u o f an array. This is because a string is just like an array o f characters!
There is a pro blem here—the index is no t checked in this o peratio n. So if the index is o ut o f range, the
expressio n returns an undefined value. In o ther wo rds, this o peratio n is no t safe—and yo u kno w ho w we feel
abo ut safety!
Fo rtunately, there is ano ther way o f getting the character, the at () functio n. Change the pro gram as sho wn:
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first;
std::string last;
std::string full;
char first_initial;
//
//
//
//
First name
Last name
The full name
The first initial
first = "Joyce";
last = "Kilmer";
full = first + " " + last;
first_initial = first.at(0); // Assigns first_initial the value 'J'. This is
the safe way of doing this.
std::cout << "My first initial is " << first_initial << std::endl;
return(0);
}
Save and run it. Yo u'll see the same o utput as befo re:
OBSERVE:
My first initial is J
No w just fo r fun, change the line that gets the first initial to attempt to grab character 9 9 (an illegal index), as
sho wn belo w:
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first; // First name
std::string last;
// Last name
std::string full;
// The full name
char first_initial;
// The first initial
first = "Joyce";
last = "Kilmer";
full = first + " " + last;
first_initial = first.at(99); // Assigns first_initial the value 'J'. This i
s the safe way of doing this
std::cout << "My first initial is " << first_initial << std::endl;
return(0);
}
Save and run it. Yo u'll see the fo llo wing o n the co nso le:
OBSERVE:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
The pro gram can't access the 9 9 th character in the string, so it threw in the to wel. This isn't quite a crash, but it
isn't a go o d way to end yo ur pro gram.
Other Functions
One o f the mo re co mmo n things to do with a string is to extract a substring; fo r example, so me substrings o f
the full name " J o yce Kilm e r" are "Jo yce," "e Ki," and "Kilmer."
C++ strings let yo u take substrings using the subst r functio n. Let's try it!
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first; // First name
std::string last;
// Last name
std::string full;
// The full name
char first_initial;
// The first initial
first = "Joyce";
last = "Kilmer";
full = first + " " + last;
first_initial = first.at(99); // Assigns first_initial the value 'S'. This i
s the safe way of doing this
std::cout << "My substring is " << full.substr(4, 5) << std::endl;
return(0);
}
Save and run it. Yo u will see the fo llo wing o utput:
OBSERVE:
My substring is e Kil
Let's take a lo o k at the substr co de:
OBSERVE:
full.substr(4, 5)
The 4 is the po sitio n o f the starting character fo r the substring—in this case, the 'e' in Jo yce. The 5 is the
length o f the substring—in this example, the pro gram returns the characters 'e,' space, 'K,' 'i,' and 'l.'
If yo u o mit the seco nd number, a different substring is returned. Try it:
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first;
std::string last;
std::string full;
// First name
// Last name
// The full name
first = "Joyce";
last = "Kilmer";
full = first + " " + last;
std::cout << "My substring is " << full.substr(4, 5) << std::endl;
return(0);
}
Save and run it. This time yo u will see:
OBSERVE:
My substring is e Kilmer
C++ also has a functio n to tell yo u ho w many characters are in a string. It's called le ngt h()—let's try it:
CODE TO TYPE:
#include <iostream>
#include <string>
int main()
{
std::string first;
std::string last;
std::string full;
// First name
// Last name
// The full name
first = "Joyce";
last = "Kilmer";
full = first + " " + last;
std::cout << "My name has " << full.length() << " characters in it." <<std::
endl;
return(0);
}
Save and run it. Sure eno ugh, it co unts the characters, including spaces!
OBSERVE:
My name has 12 characters in it.
In the next lesso n we will learn mo re abo ut strings and discuss C-Strings. See yo u then!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
C-Style Strings
C++ 1: Introduction to C++ Lesson 6
What is a C-Style String?
In the last lesso n we learned abo ut C++ strings. There is an additio nal, different type o f string—the C-style string.
C-style strings are the primary string type o f the C language. Since C++ is a superset o f C, it to o has use C-style
strings. In previo us lesso ns we examined characters and arrays—a C-style string is essentially an array o f characters
with the special character null ('\0 ') at the end.
Since C-style strings are arrays, they have a fixed maximum length. "Dynamic" strings are po ssible, but they require
the pro grammer to manually manage memo ry—a pro cess that is full o f pitfalls and go tchas. Many security pro blems
and bugs refer to buffer o verflo ws—which are typically erro rs with C-style strings that result in memo ry co rruptio n.
There are many who believe that yo u sho uld never have a C-style string in a C++ pro gram. Unfo rtunately "sho uld" and
the "real wo rld" are two quite different things. There is still a lo t o f legacy co de o ut there that uses C-style strings. As a
pro grammer in the real wo rld, yo u will see this type o f string and have to deal with it.
So let's start with an experimental C-style string pro gram. Create a pro ject named c-st ring, assign it to yo ur
C++1_Le sso ns wo rking set, and create a pro gram c-st ring.cpp co ntaining the fo llo wing:
Co de to Type: c-string.cpp
#include <iostream>
int main()
{
char name[] = {'S', 'a', 'm', '\0'};
// The name for this example
std::cout << "The name is " << name << std::endl;
return(0);
}
This assigns the value "Sam" to a C string nam e , which can be o utput to st d::co ut .
Save and run it, and o bserve the o utput:
OBSERVE:
The name is Sam
No w what wo uld happen if yo u didn't end the string with '\0 '? Let's see. Change yo ur pro gram as sho wn:
Co de to Edit: c-string.cpp
#include <iostream>
int main()
{
char name[] = {'S', 'a', 'm', '\0'};
// The name for this example
char other[] = {'J', 'o', 'e'};
// Another name with an error
std::cout << "The name is " << name << " and other is " << other
return(0);
}
Save and run it, and o bserve the o utput:
OBSERVE:
The name is Sam and other is Joew
<< std::endl;
Yo ur actual o utput might differ fro m this example—in fact, it might even lo o k no rmal. This is ano ther situatio n where the
behavio r is undefined. If yo u do no t put an end-o f-string marker (\0 ) in yo ur C-style string, it is anybo dy's guess what
will o ccur.
Remember when we accidentally used an array element we weren't suppo sed to use? What happened? Because there
was no end-o f-string marker, C++ did no t sto p at the end o f o t he r. It co ntinued to write o ut characters fro m rando m
memo ry until it actually fo und an end-o f-string character.
C++ allo ws fo r even mo re co mpact initializatio n, using do uble quo tes ("). Let's use it to fix the erro r:
Co de to Edit: c-string.cpp
#include <iostream>
int main()
{
char name[] = {'S', 'a', 'm', '\0'};
// The name for this example
char other[] = "Joe";
// Another name with an error
std::cout << "The name is " << name << " and other is " << other
return(0);
<< std::endl;
}
This fo rm o f initializatio n creates an array four characters lo ng and assigns it fo ur character values, the fo urth and last
being the end-o f-string character.
Save and run it, and o bserve the o utput:
OBSERVE:
The name is Sam and other is Joe
Yo u canno t assign a value to an existing C-style string. This is because a C string is an array and yo u canno t change
its value like yo u can with o ther variables. Try it:
Co de to Edit: c-string.cpp
#include <iostream>
int main()
{
char name[] = "Sam";
// The name for this example
char other[] = "Joe";
// Another name with an error
name = "Joe"; // Will this work?
std::cout << "The name is " << name << " and other is " << other
return(0);
}
When yo u save this file yo u will see an erro r:
<< std::endl;
This erro r is generated because C strings require the pro grammer to wo rry abo ut memo ry and do extra wo rk when
co pying them. Think o f the mailbo x analo gy fro m the array lesso n—here we created a mailbo x with three slo ts,
co ntaining the values "S," "a," and "m." Using nam e = " J o e " ; is like buying a new mailbo x with three slo ts and trying
to sho ve the new mailbo x with slo ts "J", "o " and "e" where the o ld mailbo x is still hanging.
Instead o f trying to smash o ne mailbo x in place o f ano ther, we must manually o pen each slo t and co py the co ntents
fro m the new to the o ld. This is do ne using the st rncpy() functio n (see the reference info rmatio n at cplusplus.co m).
No te this reference uses an o ld header file (st ring.h) instead o f the current o ne (cst ring).
This functio n has three parameters:
strncpy() Syntax
std::strncpy( destination , source , size );
de st inat io n is where the data is to be put, so urce is the so urce o f the data, and size is the maximum number o f
characters to put in the destinatio n.
Befo re we can use st rncpy, we need to get o ut o ur tape measure—an o perato r named size o f (). sizeo f() returns the
size o f so mething in "char" units. If we use it o n a C-style string, it will return the maximum number o f characters that
can be sto red in the string.
This is very impo rtant because o ur strings (mailbo xes) are fixed in size. If we try to co py to o many characters fro m o ur
new mailbo x to the o ld, bad things co uld happen. Co pying to o many characters is yet ano ther way to o verflo w the
buffer and po ssibly cause the pro gram to crash.
Let's see an example. Edit c-st ring.cpp as sho wn:
Co de to Edit: c-string.cpp
#include <cstring>
#include <iostream>
int main()
{
char name[4];// Short name
std::cout << "Size is " << sizeof(name) << std::endl;
std::strncpy(name, "Joe", sizeof(name));
std::cout << "Name is now " << name << std::endl;
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
Size is 4
Name is now Joe
Yo u might be wo ndering why yo u see Size is 4 —after all, J o e is o nly three letters lo ng! The fo urth character is the end
o f string ('\0 ') null character. Remember: this character is required, so yo u must take it into acco unt.
What happens when we try to co py a larger string into a smaller variable? Let's try it:
Co de to Edit: c-string.cpp
#include <cstring>
#include <iostream>
int main()
{
char name[4]; // Short name
std::cout << "Size is " << sizeof(name) << std::endl;
std::strncpy(name, "Joe", sizeof(name));
std::cout << "Name is now " << name << std::endl;
std::strncpy(name, "Steve", sizeof(name));
std::cout << "Name is now " << name << std::endl;
return (0);
}
Save and run it. This time, yo u'll see so mething like this:
OBSERVE:
Size is 4
Name is now Joe
Name is now Stev a"
The o utput fro m yo ur pro gram may be slightly different, see ho w "Steve" wasn't co pied co rrectly, and the o utput
co ntains extra characters?
We used the size o f o perato r to co mpute the maximum number o f characters that can be sto red in the variable nam e .
This included the null character. "Steve" is six characters—"Steve" plus the end-o f-string character.
If the so urce string has fewer characters than the size o f the array, then st d::st rncpy() co pies the string and adds an
end-o f-string ('\0 ') to the end. But since the so urce is bigger here, it co pies size's number o f characters and do es no t
append the end-o f-string. So in o rder to make things wo rk, we must do so o urselves:
Co de to Edit: c-string.cpp
#include <cstring>
#include <iostream>
int main()
{
char name[4]; // Short name
std::cout << "Size is " << sizeof(name) << std::endl;
std::strncpy(name, "Joe", sizeof(name));
std::cout << "Name is now " << name << std::endl;
std::strncpy(name, "Steve", sizeof(name));
name[sizeof(name)-1] = '\0';
std::cout << "Name is now " << name << std::endl;
return (0);
}
Since size o f (nam e ) is 4 in o ur example, size o f (nam e )-1 will be 3. Remember arrays (and C-style strings, which
are arrays o f characters) are zero -based, so 3 is the last mailbo x in the nam e string.
Save and run it. This time yo u'll see:
OBSERVE:
Size is 4
Name is now Joe
Name is now Ste
We o nly see the first three characters o f "Steve" because nam e is o nly big eno ugh to co ntain fo ur characters—"Ste"
plus the null character. Believe it o r no t, changing the size o f C-style strings is no t as straightfo rward as yo u might
expect. That to pic will be co vered in a future co urse.
Concatenation of C-Style Strings
In the last lesso n, we co vered the le ngt h() functio n fo r C++-style strings. The functio n st d::st rle n() returns the length
o f a C-style string. In o ther wo rds, it returns the number o f characters actually in the string, as o ppo sed to size o f (),
which returns the capacity.
The functio n to perfo rm co ncatenatio n o f C-style strings is st d::st rncat (). Unlike co ncatenatio n o f C++ strings,
co ncatenatio n o f C-style strings requires so me planning to make sure yo u do n't o verflo w any buffers. The functio n
takes three parameters:
OBSERVE:
std::strncat( destination , source, size );
Yo u must carefully calculate size in o rder to make sure yo u do n't o verflo w the de st inat io n. The easiest way to do
this is to always use the fo llo wing co de:
Co ncatenatio n Design Pattern
std::strncat( destination , source, sizeof(dest) - std::strlen(dest) - 1 );
destination[sizeof(destination)-1] = '\0';
The calculatio n fo r the size parameter fo r st d::st rncat () wo rks like this:
Co de
sizeo f(destinatio n)
De script io n
Start with the size o f the destinatio n string in characters.
- std::strlen(destinatio n) Subtract the number o f characters already in the string.
-1
Subtract o ne mo re fo r the end-o f-string ('\0 ') character.
Let's try an example! Edit c-st ring.cpp as sho wn:
Co de to Edit: c-string.cpp
#include <cstring>
#include <iostream>
int main()
{
char name[25]; // Short name with plenty of space
std::cout << "Size is " << sizeof(name) << std::endl;
std::strncpy(name, "Joe", sizeof(name));
std::cout << "Name is now " << name << std::endl;
std::strncat(name, " Smith", sizeof(name) - std::strlen(name) - 1);
name[sizeof(name)-1] = '\0';
std::cout << "Name is now " << name << std::endl;
return (0);
}
Save and run it, and o bserve the o utput:
OBSERVE:
Size is 25
Name is now Joe
Name is now Joe Smith
Success!
Comparing Strings
The C-style string co mpariso n functio n is st d::st rcm p(). It takes two parameters:
OBSERVE:
std::strcmp( string1, string2)
It returns:
0 if the strings are equal
A po sitive value if the first character that do es no t match has a greater value in string1 than in string2
A negative value if the first character that do es no t match has a greater value in string2 than in string1
Let's see ho w it wo rks. Create a co m pare -c pro ject and assign it to yo ur C++1_Le sso ns wo rking set. Then, create a
pro gram named co m pare -c.cpp as sho wn:
Co de to Type: co mpare-c.cpp
#include <cstring>
#include <iostream>
int main()
{
char str1[] = "Steve";
char str2[] = "Steven";
int result = std::strcmp(str1, str2);
std::cout << "Result is " << result << std::endl;
return (0);
}
Save and run it, and o bserve the o utput:
OBSERVE:
Result is -1
Yo u might be asking yo urself why we can't use the == equality o perato r to check to see if two strings are the same.
Let's try it to see ho w it might wo rk:
Co de to Edit: co mpare-c.cpp
#include <cstring>
#include <iostream>
int main()
{
char str1[] = "Steve";
char str2[] = "Steve";
if (str1 == str2)
{
std::cout << "Same!" << std::endl;
}
else
{
std::cout << "Not the same!" << std::endl;
}
return (0);
}
Save and run it, and o bserve the o utput:
OBSERVE:
Not the same!
Why is this? The two strings o bvio usly have the same value.
Using o ur mailbo x metapho r, the == equality o perato r checks to see if the two mailbo xes are the same (like if they
have the same serial number)—it do esn't check their co ntents. This fails because the mailbo xes are no t the same.
T ips
Converting C++ Strings to C-Style Strings
Yo u can co nvert fro m C-style strings to C++ style strings, and vice versa. To get a C-style string fro m a C++style string, use the c_st r() functio n. Yo u can assign a C-style string to a C++-style string. Try it:
Co de to Edit: c-string.cpp
#include <iostream>
int main()
{
char name[] = "Sam";
char other[] = "Joe";
char c_style[4];
// The name for this example
// Another name
// New variable to hold C++ string
std::string cpp_style;
cpp_style = name;
// Assigning to a C++-style string
std::strncpy(c_style, cpp_style.c_str(), 4);
// Copy C-string to a variabl
e
std::cout << "The name is " << name << " and other is " << other
<< std::en
dl;
std::cout << "cpp_style as a C-style string is " << c_style << std::endl;
return(0);
}
In this example we:
1. Co pied a C-style string to a C++ style string, using direct assignment: cpp_style = name
2. Co pied a C++ string to a C-style string, using c_str() and std::strncpy
Save and run it, and o bserve the o utput. To us, the results lo o k the same:
OBSERVE:
The name is Sam and other is Joe
cpp_style as a C-style string is Sam
Unsafe String Functions
Many peo ple do n't use the string co py design pattern we pro vided, and thus buffer o verflo w pro blems o ccur in
many pro grams. Instead, they use the functio n std::strcpy(). The standard fo rm o f this functio n is:
Unsafe Use o f strcpy()
// Unsafe. Do not use.
std::strcpy(destination, source);
Where de st inat io n is where the data will be co pied into and so urce is the string to co py.
Parano id pro grammers will ask themselves "What happens if the so urce is bigger that the destinatio n?" The
st rcpy() functio n do es no t check length and if the so urce is to o big, it will happily write rando m memo ry,
co rrupting yo ur pro gram.
T ip
Parano ia, in pro grammers, is actually a good quality.
In the style guide, we reco mmend that yo u not use the st rcpy() functio n.
In the real wo rld, yo u might enco unter legacy co de co ntaining st rcpy()—a lo t o f co de still uses this functio n.
So , what sho uld yo u do when yo u see it? Ideally, to make the pro gram safe, replace all st rcpy() functio ns
with st rncpy(), but any time yo u change a pro gram there is risk—fo r example, yo u may no t make the change
co rrectly. If the co de is wo rking, even if it is messy, the best thing to do is to leave it alone. Unless there is a
bug in the pro gram that fo rces yo u to rewrite the co de, leave working code alone.
There are two times yo u wo uld want to upgrade st rcpy() to the C-string st rncpy() design pattern. The first is
if yo u are changing the co de anyway. (Always leave co de better than when yo u fo und it.) The seco nd is when
yo u are trying to track do wn a memo ry co rruptio n bug—in this case, the change might fix the bug.
Ano ther unsafe functio n is std::strcat(). It perfo rms much the same functio n as st d::st rcpy(), except that it
do es co ncatenatio n instead o f co pying.
std::strcat (unsafe)
// Unsafe. Do not use.
std::strcat(destination, source);
This functio n adds the so urce string to the end o f the de st inat io n with no regard for the size of the
destination.
T he future of strcpy() and strcat()
Peo ple have do ne all so rts o f things to get aro und the limitatio ns o f st rcpy() and st rcat () fo r years.
Currently, the OpenBSD fo lks have devised new functio ns, st rlcpy() and st rlcat (), designed to o verco me
the safety pro blems with st rcpy() and st rcat (), respectively. Ho wever, their effo rt has no t made it into the
standard yet.
Fo r mo re info rmatio n, see strlco py in Wikipedia.
Comparisons to other types
C Strings vs. Arrays of Characters
C-style strings and arrays o f characters are two different things. An array o f characters is o f fixed length and
co ntains no markers o r o ther special characters. In o ther wo rds, char nam e [5 0 ] co ntains 50 characters o f
any type, no mo re o r less.
Note
In a character array, the null character ('\0 ') need no t be present; it's just ano ther character, with
no special meaning.
A C-style string is built o n the character array type. It states that yo u have an array o f characters, with an endo f-string marker ('\0 ') to end it. So , null ('\0 ') canno t be part o f the string.
So all C-style strings are arrays o f characters, but all arrays o f characters are no t C-style strings. Let's try an
example. Edit yo ur co m pare -c.cpp pro gram as sho wn:
Co de to Edit: co mpare-c.cpp
#include <cstring>
#include <iostream>
int main()
{
char state[2] = {'C','A'};
std::cout << "This probably looks funny: " << std::endl;
std::cout << state << std::endl;
std::cout << "This looks better: " << std::endl;
std::cout << state[0] << state[1] << std::endl;
return (0);
}
Yo u might lo o k at the state declaratio n and think it is an erro r, that it sho uld be char st at e [3] in o rder to
reserve o ne character fo r the end o f string.
But this is no t a mistake. st at e is not a C-style string; it's a character array. It ho lds two characters. No mo re,
no less (there are no o ne-character state name abbreviatio ns).
Save and run it, and o bserve the o utput. Generally, yo u'll see so mething like:
OBSERVE:
This probably looks funny:
CA ÿ"
This looks better:
CA
When yo u use st d::co ut << st at e <<, C++ will assumes that state is a C-style string (it's no t). It will then
lo o k fo r the end-o f-string marker (there is no ne) and write the state abbreviatio n fo llo wed by so me rando m
garbage.
Yo u must write a character array o ne character at a time:
Writing a Character Array
std::cout << state[0] << state[1] << std::endl;
T he bo t t o m line : Yo u can write o ut a C-style string using << but no t a character array.
C-Style vs. C++ Style
There are advantages and disadvantages to using each type o f string.
Size
C++ strings can sto re any length string auto matically. Yo u must explicitly declare the
Size
maximum size o f C-style strings.
Memo ry
The memo ry used by C-style strings is precisely co ntro lled. They do no t gro w o r shrink
depending o n what data yo u put into them. C++ style strings manage their o wn memo ry.
They can gro w and shrink. They can also use memo ry in surprising ways if yo u are no t
careful.
Almo st all o f the o peratio ns yo u can use o n C++ style strings are safe. Almo st all o f the
Operatio ns o peratio ns yo u can use o n C-style strings can be dangero us. Yo u must be very careful abo ut
safety so yo u do no t cause any buffer o verflo ws.
Efficiency
C-style strings are mo re efficient that C++ style strings. Ho wever, as a practical matter, mo st
pro grams are no t CPU limited so efficiency makes little difference in a pro gram. Safety do es,
and that's where C++ style strings win.
OS
Interactio n
If yo u are interacting directly with an o perating system like Windo ws o r Linux, yo u will find that
many o f the lo wer-level o perating system functio ns (raw re ad and o thers) use C-style
strings as arguments. This means that if yo u pass data fro m o ne part o f the OS to ano ther,
C-style strings are mo re efficient.
Have yo u had eno ugh o f strings yet? In o ur next lesso n we'll finally mo ve o n fro m o utput to input, and we'll start learning ho w to
make decisio ns in o ur pro grams. See yo u there!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Reading Data and if
C++ 1: Introduction to C++ Lesson 7
Reading Strings
In earlier lesso ns we used st d::co ut to o utput data to the co nso le. If we want to read data in fro m the co nso le, we can
use—surprise!—st d::cin.
Let's lo o k at a sho rt pro gram that demo nstrates the use o f st d::cin. Create a pro ject named re ading, assign it to the
C++1_Le sso ns wo rking set, then type a re ading.cpp pro gram in it as sho wn:
Co de to Type: reading.cpp
#include <iostream>
int main() {
std::string name;
std::cout << "Enter your name: ";
std::cin >> name;
std::cout << "You typed " << name << std::endl;
return (0);
}
Save and run it. Enter a first name, a space, and a last name (separated by a space) and press Ent e r. Yo u see
so mething like:
OBSERVE:
Enter your name: Jimi Hendrix
You typed Jimi
The pro gram o nly reads the first name. Yo u pro bably kno w "Jimi" by his first name, but that wo n't wo rk fo r everyo ne!
But all is no t lo st! The so lutio n is to use the standard functio n std::getline. The general fo rm o f this functio n is:
getline syntax
std::getline( input-stream , string );
The input-stream is the so urce o f the data—in o ur case, it's st d::cin. Change yo ur reading pro gram as sho wn:
Co de to Edit: reading.cpp
#include <iostream>
int main() {
std::string name;
std::cout << "Enter your name: ";
std::getline(std::cin, name);
std::cout << "You typed " << name << std::endl;
return (0);
}
Save and run it again. Enter the first and last name and press Ent e r. This time the result is much better:
OBSERVE:
Enter your name: Jimi Hendrix
You typed Jimi Hendrix
st d::ge t line reads a full line up to and including the end-o f-line character. The result (minus the end o f line) is sto red
in the string.
Reading Integers
st d::cin and the >> o perato r wo rk fo r all so rts o f variables, including integers. Edit yo ur reading pro gram as sho wn:
reading.cpp
#include <iostream>
int main() {
int value = 0;
// a value to double
std::cout << "Enter a value: ";
std::cin >> value;
std::cout << "Twice " << value << " is " << value * 2 << std::endl;
return (0);
}
Save and run it, then click in the co nso le windo w, type 123 and press Ent e r. Yo u will see:
OBSERVE:
Enter a value: 123
Twice 123 is 246
Let's lo o k at this co de mo re clo sely.
Observe: reading.cpp
#include <iostream>
int main() {
int value = 0;
// a value to double
std::cout << "Enter a value: ";
std::cin >> value;
std::cout << "Twice " << value << " is " << value * 2 << std::endl;
return (0);
}
Back in the first lesso n, we learned that the << o perato r means to "put whatever's o n the right into whatever's o n the
left." Since we are using st d:cin and want to get data fro m the co nso le, we use >> to go the o ther directio n and "get
whatever's o n the right from whatever's o n the left." In o ur case, we get data fro m st d::cin and put it in the variable
named value .
Also , lo o k at the line st d::co ut << " Ent e r a value : " ;. No tice that there's no st d::e ndl at the end. We o mitted this
deliberately to make this o utput line a pro mpt.
In real-wo rld pro gramming, parano ia is part o f the jo b. So o ne questio n yo u need to ask at this po int is "What happens
if I type so mething that isn't a number?" Let's try it! Run yo ur pro gram again, enter "Jimi Hendrix," and press Ent e r.
This time yo u'll see the fo llo wing:
OBSERVE:
Enter a value: Jimi Hendrix
Twice 0 is 0
When yo u try to assign an inappro priate type o f data to the value variable, it do esn't change.
if Statements
No w that we can read data, we are go ing to create a pro gram that reads a number and tells yo u if it's even. Create a
pro ject named if , assign it to yo ur C++1_Le sso ns wo rking set. In that pro ject, create a pro gram named if .cpp as
sho wn:
Co de to Type: if.cpp
/*
* if Show the use of the if statement
*
* In this case the program will tell you if a number
* is even or odd.
*
* Usage:
*
Run the program.
*
Type in a number when prompted.
*
Get the answer.
*
*/
#include <iostream>
int main()
{
int number; // A number we are going to check
std::cout << "Enter a number: ";
std::cin >> number;
if ( (number % 2) == 0)
{
std::cout << number << " is even" << std::endl;
}
return(0);
}
Save and run the pro gram. Enter an even number like 8. Yo u will see the fo llo wing o utput:
OBSERVE:
Enter a number: 8
8 is even
If yo u enter an o dd number like 7, yo u wo n't see any o utput at all.
Ho w do es the if statement wo rk? The key line is:
if Statement in Use
if ((number % 2) == 0)
This says to C++, "co mpute the value o f the expressio n num be r % 2." The % is the mo dulus o perato r—it calculates
the remainder after divisio n. If the value is equal to (==) zero , the pro gram executes the statements in the fo llo wing
blo ck (enclo sed in curly braces {}).
if statements have the fo llo wing structure:
OBSERVE:
if ( conditional test )
{
Code to execute when conditional test is true.
}
else
{
Code to execute when conditional test is false. You do not need to have an "else."
}
There are o ther co mpariso n o perato rs yo u can use (in if statements and elsewhere):
== Equal to
!=
No t equal to
>
Greater than
<
Less than
>= Greater than o r equal to
<= Less than o r equal to
Let's try a different co mpariso n. Change yo ur pro gram as sho wn:
Co de to Edit: if.cpp
#include <iostream>
int main()
{
int number; // A number we are going to check
std::cout << "Enter a number: ";
std::cin >> number;
if ( number >= 100 )
{
std::cout << number << " is big!" << std::endl;
}
else
{
std::cout << number << " is not so big." << std::endl;
}
return(0);
}
In this pro gram, we changed o ur co nditio nal test slightly and added an "else" clause.
Save and run it. Enter 25 0 ; yo u will see:
OBSERVE:
Enter a number: 250
250 is big!
If yo u enter a smaller number, like -250 , yo u'll see the o ther message instead:
OBSERVE:
Enter a number: -250
-250 is not so big.
if Abuse
if Abuse
Equality or Assignment?
In o ur first example o f the if statement, we used the == equality o perato r to see if a number was even o r no t.
What wo uld happen if yo u used a single = instead? Try it:
Co de to Edit: if.cpp
#include <iostream>
int main()
{
int number; // A number we are going to check
std::cout << "Enter a number: ";
std::cin >> number;
if ( number = 100 )
{
std::cout << number << " is one hundred!" << std::endl;
}
else
{
std::cout << number << " is not one hundred." << std::endl;
}
return(0);
}
Save and run it, and enter 25 . Yo u'll see:
OBSERVE:
Enter a number: 25
100 is big!
Try it with o ther numbers: -0 , -25, 150 . No matter what yo u type, the co mputer thinks yo u entered 10 0 !
This is because we didn't use the e qualit y o pe rat o r—instead, we changed the value o f num be r. In o ther
wo rds, this line:
OBSERVE:
if (number = 100)
was essentially interpreted as:
OBSERVE:
number = 100;
if (number != 0) {
This so rt o f erro r can be tricky to spo t. An easy way to avo id this issue is to always place co nstants o n the left
side o f the co mpariso n. Change yo ur co de to the fo llo wing:
Co de to Edit: if.cpp
#include <iostream>
int main()
{
int number; // A number we are going to check
std::cout << "Enter a number: ";
std::cin >> number;
if ( 100 = number )
{
std::cout << number << " is one hundred!" << std::endl;
}
else
{
std::cout << number << " is not one hundred." << std::endl;
}
return(0);
}
Save yo ur pro gram. See ho w there is a new erro r:
This erro r indicates yo u are trying to change the value o f "10 0 " to whatever is sto red in num be r, but "10 0 "
isn't a variable, so yo u canno t do that so rt o f assignment.
Fix the erro r by using the == equality o perato r:
Co de to Edit: if.cpp
#include <iostream>
int main()
{
int number; // A number we are going to check
std::cout << "Enter a number: ";
std::cin >> number;
if ( 100 == number )
{
std::cout << number << " is one hundred!" << std::endl;
}
else
{
std::cout << number << " is not one hundred." << std::endl;
}
return(0);
}
Blocks
C++ allo ws yo u to write if statements in a co mpact way. Change yo ur pro gram as sho wn:
Co de to Edit: if.cpp
#include <iostream>
int main()
{
int number; // A number we are going to check
std::cout << "Enter a number: ";
std::cin >> number;
if ( 100 == number )
{
std::cout << number << " is one hundred!" << std::endl;
}
else
{
std::cout << number << " is not one hundred." << std::endl;
}
return(0);
}
Save and run yo ur pro gram a few times with different numbers. Yo u will see this pro gram wo rks just like
the prio r versio n. The if statement do es no t require yo u to use braces {}—it executes the statement
immediately fo llo wing the if o r e lse .
OBSERVE:
if ( conditional test )
Code to execute when conditional test is true.
else
(Optional) Code to execute when conditional test is false. You do not need t
o have an "else."
This can be very pro blematic, tho ugh. Change yo ur pro gram as sho wn (including spaces):
Co de to Edit: if.cpp
#include <iostream>
int main()
{
int number; // A number we are going to check
std::cout << "Enter a number: ";
std::cin >> number;
if ( 50 <= number ) // if #1
if ( 100 == number ) // if #2
std::cout << number << " is one hundred!" << std::endl;
else // else #1
std::cout << number << " is not so big." << std::endl;
else // else #2
std::cout << number << " is ??? " << std::endl;
return(0);
}
Co nfused? Yo u sho uld be! Witho ut braces (and pro per indentatio n), it is very hard to figure o ut what exactly
will happen in this pro gram. Which e lse go es with which if ? Po ssible answers include:
if #1 go es with else #1
if #2 go es with else #1
if #1 go es with else #2
If yo u do n't write co de like this, yo u wo n't have to wo rry abo ut silly questio ns like this.
The co rrect answer is number 4 !
Yo u need to kno w this so yo u can debug o ther peo ple's co de. Peo ple who value co mpact co de o ver
readability, understandability, and safety. Ho wever, since we find readability, understandability, and safety
valuable and we write go o d co de, we will never write co de like this.
Note
So me peo ple tell yo u to always use {} fo r the statements affected by an if . The Perl language
requires it. We co nsidered this, but decided that, fo r the mo st part, letting the pro grammer decide
whether {} o r a single statement is clearer.
Conditional Shortcuts
If statements also let yo u take sho rtcuts in the co ndit io nal t e st . In the C++ wo rld, 0 is false, and anything
else is true. With this in mind, peo ple have devised sho rtcuts, such as the fo llo wing:
Co de to Edit: if.cpp
#include <iostream>
int main()
{
int number; // A number we are going to check
std::cout << "Enter a number: ";
std::cin >> number;
if ( ! number )
{
std::cout << number << " is zero!" << std::endl;
}
else
{
std::cout << number << " is not zero." << std::endl;
}
return(0);
}
The ! is the lo gical negatio n o perato r—it adds a "no t" to the co nditio n. The co nditio nal statement in this
pro gram might read like "if no t number"—which is pretty co nfusing.
Save and run the pro gram. Enter 0 (zero ); yo u'll see this:
OBSERVE:
Enter a number: 0
0 is zero.
If yo u enter a no n-zero number (even -25), yo u'll see the fo llo wing:
OBSERVE:
Enter a number: -25
-25 is not zero.
This co de is no t go o d because it isn't clear exactly what is go ing o n. Instead, be explicit with yo ur if
statements. Change yo ur pro gram as sho wn:
Co de to Type: if.cpp
#include <iostream>
int main()
{
int number; // A number we are going to check
std::cout << "Enter a number: ";
std::cin >> number;
if ( 0 != number )
{
std::cout << number << " is not zero." << std::endl;
}
else
{
std::cout << number << " is zero." << std::endl;
}
return(0);
}
This pro gram is clearer—the co nditio n reads "if number is no t equal to zero ." Much better!
Yo u made it! In the next lesso n we will shift gears and discuss so me sho rtcuts that are co mmo n in C++ pro grams. See yo u
then!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Shortcuts
C++ 1: Introduction to C++ Lesson 8
There are many different ways to acco mplish the same task in C++. So me co de patterns o ccur very o ften, so the develo pers o f
C and C++ have included sho rtcuts that can make co de sho rter and easier to understand.
Operators
Co nsider the fo llo wing o peratio n:
Incrementing a Variable's Value
x = x + 5;
This co de pattern o ccurs frequently in C++ (and o ther languages), so the makers o f C++ added a sho rtcut o perato r to
the language:
Incrementing with a Sho rtcut
x += 5;
Other sho rtcut o perato rs are:
Lo nghand Sho rt cut
a = a - b;
a -= b;
a = a * b;
a *= b;
a = a / b;
a /= b;
a = a % b;
a %= b;
a = a + 1;
a++;
a = a - 1;
a--;
Let's experiment with so me sho rtcut o perato rs. Start a new pro ject named sho rt cut , and assign it to yo ur
C++_Le sso ns wo rking set. In the new pro ject, create a so urce file named sho rt cut .cpp.
Co de to Type: sho rtcut.cpp
#include <iostream>
int main() {
int x = 0; // to play
std::cout << "x is " << x << std::endl;
x += 5;
std::cout << "x is " << x << std::endl;
x++;
std::cout << "x is " << x << std::endl;
return(0);
}
Save and run yo ur pro gram. Yo u'll see the value o f x change:
OBSERVE:
x is 0
x is 5
x is 6
One o f the mo st co mmo n uses o f these sho rtcuts is in f o r lo o ps. Let's take a lo o k:
Co de to Edit: sho rtcut.cpp
#include <iostream>
int main() {
int x = 0; // to play
for (x = 0 ; x < 25; x++ )
{
std::cout << "x is " << x << std::endl;
}
return(0);
}
Save and run it. Yo u'll see:
OBSERVE:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
is
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
We can use += to have o ur lo o p skip by five instead:
Co de to Edit: sho rtcut.cpp
#include <iostream>
int main() {
int x = 0; // to play
for (x = 0 ; x < 25; x += 5 )
{
std::cout << "x is " << x << std::endl;
}
return(0);
}
Save and run it. See the difference:
OBSERVE:
x
x
x
x
x
is
is
is
is
is
0
5
10
15
20
For Loops
It turns o ut the fo r lo o p has a few mo re tricks. Suppo se we wanted to write a pro gram to add several numbers, but no
mo re than ten. We do n't want to include any negative numbers, and if we enco unter a zero , we will kno w o ur list is
do ne.
We can make this happen with two sho rtcuts: co nt inue and bre ak. Clear yo ur pro gram and type the fo llo wing:
Co de to Edit: sho rtcut.cpp
#include <iostream>
int main() {
int total;
int count;
int number;
// Total so far
// Count of the numbers
// A number to read
total = 0;
for (count = 0; count < 10; ++count)
{
std::cout << "Enter a number: ";
std::cin >> number;
// Skip all negative numbers
if (number < 0) {
std::cout << "Negative numbers don't count." << std::endl;
continue;
}
if (number == 0) {
std::cout << "I guess you want to end the list" << std::endl;
break;
}
total += number;
std::cout << "The new total is " << total << std::endl;
}
std::cout << "The grand total is " << total << std::endl;
return(0);
}
Save and run it. Enter a few po sitive numbers, a negative number, and finally a zero . Yo u'll see so mething like this:
OBSERVE:
Enter a number: 1
The new total is 1
Enter a number: 1
The new total is 2
Enter a number: 1
The new total is 3
Enter a number: 1
The new total is 4
Enter a number: 1
The new total is 5
Enter a number: -5
Negative numbers don't count.
Enter a number: 9
The new total is 14
Enter a number: 0
I guess you want to end the list
The grand total is 14
When the pro gram enco unters a negative number, it o utputs a message and then runs co nt inue . This skips the rest
o f the fo r lo o p, and go es o n to the next number.
When yo u enter a zero , the pro gram o utputs a message and then runs bre ak, which co mpletely exits the fo r lo o p and
o utputs the grand to tal.
Instead o f using co nt inue and bre ak, yo u co uld have acco mplished similar results by using if statements and
perhaps ano ther variable, but co ntinue and break make the lo o p much easier to understand.
Suppo se yo u want to allo w users to enter as many numbers as they want—and o nly quit the pro gram when they enter
a zero . Yo u can change yo ur fo r lo o p to acco mplish this as well:
Co de to Edit: sho rtcut.cpp
#include <iostream>
int main() {
int total;
int count;
int number;
// Total so far
// Count of the numbers
// A number to read
total = 0;
for (;;)
{
std::cout << "Enter a number: ";
std::cin >> number;
// Skip all negative numbers
if (number < 0) {
std::cout << "Negative numbers don't count." << std::endl;
continue;
}
if (number == 0) {
std::cout << "I guess you want to end the list" << std::endl;
break;
}
total += number;
std::cout << "The new total is " << total << std::endl;
}
std::cout << "The grand total is " << total << std::endl;
return(0);
}
Save and run it. It will co ntinue until yo u enter a zero .
Earlier, we discussed the sectio ns o f a fo r lo o p:
OBSERVE:
for (/* Initialization */ ; /* Test */ ; /* Increment */)
{
/* body of loop */
}
The initializatio n, test, and increment sectio ns are all o ptio nal. Only the semico lo ns (;) are required.
WARNING
This can create an infinite lo o p if yo u do n't have an appro priate bre ak in yo ur co de!
For Loop Misuse
The go al o f pro gramming is to be as clear and co rrect as po ssible. Ho wever, so me peo ple think it's to use as
few characters as po ssible. I ho pe yo u never have to debug their co de.
One o f the tricks they have is to put the co mma (,) o perato r into a f o r statement.
Co ding Ho rro r
for (twos = 0, threes = 0; twos < 100; twos +=2, threes += 3)
The co mma (,) o perato r can be used to string two C++ statements to gether and have the co mpiler treat them
as o ne. Do not use it! All it really do es is make it easy to write bad co de. In this case, we have two initializatio n
statements: t wo s = 0 and t hre e s = 0 . Because o f the co mma o perato r, C++ do es no t o bject to them bo th
being inside a f o r initializatio n.
The same ho lds true fo r the increment sectio n. Two statements have been stuffed into a place where o nly o ne
sho uld go .
What this lo o p is suppo sed to do is to co unt up two variables, t wo s by 2 and t hre e s by 3, all in o ne lo o p.
What it really do es is to cause go o d pro grammers to curse the peo ple who think they are being clever by
writing such co de.
Side Effects
A side effect is an effect that o ccurs in additio n to the main effect o f a statement. C++ allo ws yo u to use the ++ and -o perato rs inside o ther expressio ns. Let's take a lo o k. Clear yo ur pro gram and enter the fo llo wing:
Co de to Edit: sho rtcut.cpp
#include <iostream>
int main() {
int total_size;
// Total so far
int current_size; // Count of the numbers
total_size = 5;
current_size = -3;
current_size = ++total_size;
std::cout << "current_size: " << current_size << std::endl;
std::cout << "total_size: " << total_size << std::endl;
return(0);
}
Do yo u kno w what the pro gram will do ?
Save and run it. The results may surprise yo u:
OBSERVE:
current_size: 6
total_size: 6
This is bad co de! The line curre nt _size = ++t o t al_size ; do es two things (in this o rder):
1. Increments to tal_size.
2. Assigns the value o f to tal_size to current_size.
This is bad pro gramming style because it makes the co de harder to read. Two sho rt o peratio ns are much easier to
maintain and understand than o ne co mplex o ne.
There is ano ther pro blem with side effects. Change yo ur pro gram as sho wn:
Co de to Edit: sho rtcut.cpp
#include <iostream>
int main() {
int total_size;
// Total so far
int current_size; // Count of the numbers
total_size = 0;
current_size = 1;
total_size = (++current_size * 5) + (++current_size * 3);
std::cout << "current_size: " << current_size << std::endl;
std::cout << "total_size: " << total_size << std::endl;
return(0);
}
Save and run it. Once again, the o utput may surprise yo u:
OBSERVE:
current_size: 3
total_size: 19
The co de total_size = (++current_size * 5) + (++current_size * 3) tells C++ to :
1. Increment current_size and multiply the result by 5
2. Increment current_size and multiply the result by 3
3. Add the results fro m steps 1 and 2 to gether.
There is no rule that tells C++ which step (step 1 o r step 2) to execute first. Depending o n the co mpiler, the executio n
o rder co uld:
1. Increment the FIRST current_size fro m 1 to 2 and multiply the result by 5 and get 10 .
2. Increment the SECOND current_size and multiply the result by 3 and get 9 .
3. Add the results fro m steps 1 and 2 to gether and get 19 .
Or, it co uld:
1. Increment the SECOND current_size fro m 1 to 2 and multiply the result by 3 and get 6 .
2. Increment the FIRST current_size fro m 2 to 3 and multiply the result by 5and get 15.
3. Add the results fro m steps 1 and 2 to gether and get 21.
So , which result is right? They bo th are! The C++ standard allo ws fo r this ambiguity. That's o ne o f the reaso ns the style
guide pro hibits this type o f co ding. We want to make the co de safer and mo re reliable.
Yo u sho uld never use the increment (++) and decrement (--) o perato rs inside ano ther expressio n, especially an
assignment statement. But so me peo ple do , so it's impo rtant to kno w ho w they wo rk.
The prefix increment (++x) o perato r increments the variable and returns the result af t e r incrementing.
The po stfix increment (x++) o perato r increments the variable and returns the result be f o re incrementing.
The mnemo nic I use is that if yo u see the ++ first, then C++ increments first, then returns the value. If yo u see the value
first, C++ returns the value first, then increments it.
No w let's rewrite o ur pro gram, so it do es o ne thing at a time, with no side effects.
Co de to Edit: sho rtcut.cpp
#include <iostream>
int main() {
int total_size;
// Total so far
int current_size; // Count of the numbers
int first_term; // for first term
int second_term; // for second term
total_size = 0;
current_size = 1;
current_size += 1;
first_term = current_size * 5;
current_size += 1;
second_term = current_size * 3;
total_size = first_term + second_term;
std::cout << "current_size: " << current_size << std::endl;
std::cout << "total_size: " << total_size << std::endl;
return(0);
}
This pro gram is a little lo nger than the last, but it is very clear what is happening.
Save and run it. Yo u'll see:
OBSERVE:
current_size: 3
total_size: 19
We co vered a lo t in this lesso n! In the next we will examine ano ther lo o p we can use in o ur pro grams: while lo o ps. See yo u
then!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
While Loops
C++ 1: Introduction to C++ Lesson 9
while, break, and continue
Welco me back! In the previo us lesso ns we have used fo r lo o ps to do so me repetitive wo rk. In this lesso n, we'll learn
abo ut while lo o ps—ano ther way to do repetitive wo rk.
The basic fo rm o f the while lo o p is:
while Syntax
while (condition)
{
statement;
}
In the last lesso n, we used an "empty" fo r lo o p that wo uld let us input as many numbers as we wanted, and give us the
grand to tal after we entered a zero . We can do the same thing using a while lo o p instead. Start a new pro ject named
while , and assign it to the C++1_Le sso ns wo rking set. In the new pro ject, create a new file named while .cpp as
sho wn:
Co de to Type: while.cpp
#include <iostream>
int main() {
int total;
int number;
// Total so far
// A number to read
total = 0;
while( true )
{
std::cout << "Enter a number: ";
std::cin >> number;
// Skip all negative numbers
if (number < 0) {
std::cout << "Negative numbers don't count." << std::endl;
continue;
}
if (number == 0) {
std::cout << "I guess you want to end the list" << std::endl;
break;
}
total += number;
std::cout << "The new total is " << total << std::endl;
}
std::cout << "The grand total is " << total << std::endl;
return(0);
}
Save and run yo ur pro gram. Yo u'll so o n no tice it runs exactly the same as the fo r lo o p we used befo re—right do wn
to the co nt inue and bre ak statements.
Suppo se we want o ur pro gram to run until we enter a zero OR o ur grand to tal is greater than 50 . We can alter the
co ndit io n in o ur lo o p to acco mplish this:
Co de to Edit: while.cpp
#include <iostream>
int main() {
int total;
int number;
// Total so far
// A number to read
total = 0;
while( total <= 50 )
{
std::cout << "Enter a number: ";
std::cin >> number;
// Skip all negative numbers
if (number < 0) {
std::cout << "Negative numbers don't count." << std::endl;
continue;
}
if (number == 0) {
std::cout << "I guess you want to end the list" << std::endl;
break;
}
total += number;
std::cout << "The new total is " << total << std::endl;
}
std::cout << "The grand total is " << total << std::endl;
return(0);
}
Save and run it. Enter the numbers 5, 10 , 15, 20 , and 1—yo u sho uld see yo ur pro gram sto p:
OBSERVE:
Enter a number: 5
The new total is 5
Enter a number: 10
The new total is 15
Enter a number: 15
The new total is 30
Enter a number: 20
The new total is 50
Enter a number: 1
The new total is 51
The grand total is 50
Fibonacci numbers
The Fibo nacci numbers are numbers in a sequence starting with "0 1," where each subsequent number is the sum o f
the previo us two :
Fibo nacci Number Calculatio ns
0 + 1 = 1
1 + 1 = 2
1 + 2 = 3
2 + 3 = 5
3 + 5 = 8
5 + 8 = 13... and so on.
Thus, the first Fibo nacci numbers are 0 , 1, 1, 2, 3, 5, 8 , and 13. (Yes, 1 is in there twice.)
We can use a while lo o p to calculate the sequence o f Fibo nacci numbers less than 10 0 . Create a new pro ject named
f ib and assign it to yo ur C++1_Le sso ns wo rking set, and in that pro ject, create a so urce file named f ib.cpp as
sho wn:
Co de to Type: fib.cpp
#include <iostream>
int main()
{
int
old_number;
// previous Fibonacci number
int
current_number; // current Fibonacci number
int
next_number;
// next number in the series
// start things out
old_number = 0;
current_number = 1;
std::cout << "0 "; // Output first number
while (current_number < 100) {
std::cout << current_number << ' ';
next_number = current_number + old_number;
old_number = current_number;
current_number = next_number;
}
std::cout << std::endl;
return (0);
}
Save and run it. Yo u sho uld see the Fibo nacci sequence:
OBSERVE:
0 1 1 2 3 5 8 13 21 34 55 89
Ho w did we do that? Let's lo o k at the pro gram mo re clo sely.
fib.cpp
#include <iostream>
int main()
{
int
old_number = 0;
int
current_number = 1;
int
next_number;
// previous Fibonacci number
// current Fibonacci number
// next number in the series
std::cout << old_number; // Output first number
while (current_number < 100) {
std::cout << current_number << ' ';
next_number = current_number + old_number;
old_number = current_number;
current_number = next_number;
}
std::cout << std::endl;
return (0);
}
Fro m the fo rmula fo r Fibo nacci numbers, we kno w the starting values and that the next number is the sum o f the
previo us ("o ld") and current numbers, so we created variables fo r the o ld_num be r (set to 0 ), the curre nt _num be r
(set to 1), and ne xt _num be r (which we'll set in o ur lo o p).
The first Fibo nacci number is 0 —the initial value o f o ld_num be r—so we'll just o utput it befo re we start the lo o p. (But
rather than print "0 ", we'll use the variable, so if we ever ant to change it, we o nly need to change it in o ne place in the
pro gram.)
We want to co ntinue lo o ping while the number is less than 10 0 , so we can add a while lo o p to o ur pro gram.
Inside the while lo o p, we display t he curre nt num be r, then add t he o ld and curre nt num be rs t o ge t t he value
o f t he ne xt num be r.
No w, to mo ve the sequence alo ng, we shift the values: m o ve t he curre nt _num be r value t o o ld_num be r and
t he ne xt _num be r value t o curre nt _num be r befo re the next calculatio n.
Finally, we do a little ho usekeeping. Our pro gram o utputs everything o n a single line, so we add an e nd-o f -line
charact e r after the lo o p finishes.
Excellent! To get a better idea ho w Fibo nacci numbers, and while lo o ps wo rk, let's add so me co ut statements. Add
the co lo rized co de:
Co de to Edit: fib.cpp
#include <iostream>
#include <iomanip>
int main()
{
int
old_number = 0;
// previous Fibonacci number
int
current_number = 1; // current Fibonacci number
int
next_number;
// next number in the series
int
iteration_count = 1;
std::cout << "Iteration
old
current next <100?" << std::endl;
while (current_number < 100) {
std::cout << std::setw(2) << iteration_count;
std::cout << std::setw(12) << old_number;
std::cout << std::setw(9) << current_number;
next_number = current_number + old_number;
old_number = current_number;
current_number = next_number;
std::cout << std::setw(5) << next_number;
if (current_number < 100)
{
std::cout << " T";
}
else
{
std::cout << " F";
}
std::cout << std::endl;
iteration_count = iteration_count + 1;
}
std::cout << std::endl;
return (0);
}
We included io m anip—specifically the st d::se t w() functio n—to help fo rmat o ur o utput. This functio n sets the padded
width o f the next item in the co ut chain. Fo r example, the fo llo wing co de ensures that it e rat io n_co de is o utput as
exactly two characters:
OBSERVE:
std::cout << std::setw(2) << iteration_count;
Save and run it. This time, yo u'll see a beautifully fo rmatted table:
OBSERVE:
Iteration
1
2
3
4
5
6
7
8
9
10
11
old
0
1
1
2
3
5
8
13
21
34
55
current next <100?
1
1 T
1
2 T
2
3 T
3
5 T
5
8 T
8
13 T
13
21 T
21
34 T
34
55 T
55
89 T
89 144 F
The o utput sho ws ho w variables are saved fo r the next trip aro und the while lo o p. By the tenth iteratio n we have the first
Fibo nacci number (sto red in curre nt _num be r) that is greater than o r equal to 10 0 , so the pro gram sto ps.
Yo u've added so me extremely helpful to o ls to yo ur C++ to o l kit! In the next lesso n, we'll discuss the scope o f o ur variables. See
yo u then!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Scope
C++ 1: Introduction to C++ Lesson 10
What is Scope?
Up to this po int, we've used very basic variable declaratio ns. We've declared variables at the to p o f o ur pro grams and
used them thro ugho ut the entire pro gram. In o ther wo rds, all variables existed thro ugh the entire pro gram.
In this lesso n, we'll see ho w to create variables that exist fo r o nly a po rtio n o f the pro gram.
We'll start with a sho rt pro gram. Create a pro ject named var-e xp and assign it to yo ur C++1_Le sso ns wo rking set. In
this new pro ject, create a pro gram named var-e xp.cpp as sho wn:
Co de to Type: var-exp.cpp
#include <iostream>
int main()
{
std::string state = "Texas";
std::cout << "State is " << state << std::endl;
return (0);
}
Save and run this pro gram. As yo u might expect, yo u will see the fo llo wing o utput:
OBSERVE:
State is Texas
No w, edit the pro gram as sho wn:
#include <io stream> int main() { std::string state = "Texas"; std::co ut << "State is " << state << std::endl; return (0 ); }
Co de to Edit: var-exp.cpp
#include <iostream>
int main()
{
std::string state = "Texas";
std::cout << "State #1 is " << state << std::endl;
{
std::string city = "Austin";
std::cout << "City is " << city << std::endl;
}
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
State #1 is Texas
City is Austin
Edit the pro gram again as sho wn:
Co de to Edit: var-exp.cpp
#include <iostream>
int main()
{
std::string state = "Texas";
std::cout << "State #1 is " << state << std::endl;
{
std::string city = "Austin";
std::cout << "City is " << city << std::endl;
}
std::cout << "City #2 is " << city << std::endl;
return (0);
}
Save yo ur pro gram; this time yo u'll no tice an erro r:
The co mpiler is telling us that cit y isn't defined—but we did define it... didn't we?
No t quite. The variable cit y has a local scope. Sco pe is the po rtio n o f a pro gram in which the variable is kno wn. cit y
o nly exists within the curly brace ({}) blo ck enclo sing it—no t o utside o f it.
Co mpare this to the st at e variable. It also has a lo cal sco pe, but its enclo sing braces include the entire pro gram.
Is the st at e variable accessible fro m the middle o f o ur pro gram? Let's see. Change yo ur pro gram:
}
Co de to Edit: var-exp.cpp
#include <iostream>
int main()
{
std::string state = "Texas";
std::cout << "State #1 is " << state << std::endl;
{
std::string city = "Austin";
std::cout << "City is " << city << std::endl;
std::cout << "State #2 is " << state << std::endl;
}
std::cout << "City #2 is " << city << std::endl;
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
State #1 is Texas
City is Austin
State #2 is Texas
Tho ugh we added a blo ck in braces and a lo cal variable to o ur list o f variables, st at e is still within the sco pe o f the
pro gram.
No w, let's see if we can access st at e AFTER the blo ck in braces. Change yo ur pro gram:
Co de to Edit: var-exp.cpp
#include <iostream>
int main()
{
std::string state = "Texas";
std::cout << "State #1 is " << state << std::endl;
{
std::string city = "Austin";
std::cout << "City is " << city << std::endl;
std::cout << "State #2 is " << state << std::endl;
}
std::cout << "State #3 is " << state << std::endl;
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
State #1 is Texas
City is Austin
State #2 is Texas
State #3 is Texas
Global Variables
Like their geo graphical co unterparts, yo u're in the state when yo u're in the city, but yo u're no t (necessarily) in
the city when yo u're in the state.
In o ur example, the st at e variable is actually a lo cal variable. It exists o nly inside the curly braces that
enclo se it (but it's still available within o ther braces nested in tho se braces). Right no w that happens to be o ur
entire pro gram, but we will deal with mo re co mplex pro grams in the next few lesso ns.
A variable that exists o utside o f m ain() and in fact exists everywhere is called a global variable. st d::co ut ,
fo r example, is a glo bal variable. It exists befo re m ain() starts and after it ends.
Let's declare o ur o wn glo bal variable named co unt ry. Edit yo ur pro gram as sho wn:
Co de to Edit: var-exp.cpp
#include <iostream>
std::string country = "USA";
// A global variable
int main()
{
std::string state = "Texas";
std::cout << "State #1 is " << state << std::endl;
std::cout << "Country #1 is " << country << std::endl;
{
std::string city = "Austin";
std::cout << "City is " << city << std::endl;
std::cout << "State #2 is " << state << std::endl;
std::cout << "Country #2 is " << country << std::endl;
}
std::cout << "State #3 is " << state << std::endl;
std::cout << "Country #3 is " << country << std::endl;
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
State #1 is Texas
Country #1 is USA
City is Austin
State #2 is Texas
Country #2 is USA
State #3 is Texas
Country #3 is USA
In the city, yo u can "see" the state and the co untry. In the state, yo u can "see" the co untry but no t the city. In the
co untry, yo u can't see the state o r city. It's an imperfect anao lo gy, but it's o kay fo r the purpo se o f illustratio n,
right?
Storage Class
The sto rage class o f a variable can be permanent o r tempo rary. The lo cal variables we've defined are
tempo rary. They are created when they are declared and disappear when their enclo sing blo ck ends.
Glo bal variables are permanent. They are created (and initialized) when the pro gram starts, and are no t
destro yed until the pro gram ends.
Let's create a quick pro gram to take a lo o k at this situatio n. Create a pro ject named var-t ype s and assign it
to the C++1_Le sso ns wo rking set. In the new pro ject, create a pro gram named var-t ype s.cpp as sho wn:
Co de to Type: var-types.cpp
#include <iostream>
int global = 1; // Global variable to play around with
int main()
{
int loop;
// A loop counter
for (loop = 0; loop < 3; ++loop) {
int temp = 1; // A local variable to play around with
std::cout << "global is " << global << std::endl;
std::cout << "temp is " << temp << std::endl;
++global;
++temp;
// Almost useless comment
}
return (0);
}
Save and run it and o bserve the o utput:
Output o f var-types
global is 1
temp is 1
global is 2
temp is 1
global is 3
temp is 1
The value of temp never changes—but why? The answer: scope. Let's take a clo ser lo o k at the life cycle o f
t e m p.
var-types.cpp
#include <iostream>
int global = 1; // Global variable to play around with
int main()
{
int loop;
// A loop counter
for (loop = 0; loop < 3; ++loop) {
int temp = 1; // A local variable to play around with
std::cout << "global is " << global << std::endl;
std::cout << "temp is " << temp << std::endl;
++global;
++temp;
// Almost useless comment
}
return (0);
}
The variable is created by the line int t e m p = 1;. It then is incremented by the line ++t e m p, so its value is 2.
It then is destro yed just after the line // Alm o st use le ss co m m e nt , so it no w has no value because it
do esn't exist. The f o r lo o p starts ano ther lo o p. The variable is bo rn again with the line int t e m p = 1;.
It's impo rtant to remember that the sco pe o f t e m p is lo cal and the sto rage class is tempo rary.
We can make a lo cal variable permanent by putting the keywo rd st at ic in fro nt o f it. Edit yo ur pro gram as
sho wn:
Co de to Edit: var-types.cpp
#include <iostream>
int global = 1; // Global variable to play around with
int main()
{
int loop;
// A loop counter
for (loop = 0; loop < 3; ++loop) {
int temp = 1; // A local variable to play around with
static int perm = 1; // A local, permanent variable to play with
std::cout
std::cout
std::cout
++global;
++temp;
++perm;
// Almost
<< "global is " << global << std::endl;
<< "temp is " << temp << std::endl;
<< "perm is " << perm << std::endl;
useless comment
}
return (0);
}
No w, save and run it again and o bserve the o utput:
Output o f var-types
global is 1
temp is 1
perm is 1
global is 2
temp is 1
perm is 2
global is 3
temp is 1
perm is 3
The sto rage class o f pe rm is permanent. It is created and initialized when the pro gram is created, and that
means that it is initialized o nce. Every time thro ugh the lo o p it is incremented by o ne, unlike t e m p, which is
re-initialized every time thro ugh the lo o p.
On the o ther hand, the variable pe rm always stays aro und.
Note
The st at ic keywo rd is the mo st o verlo aded keywo rd in C++. It has many different meanings,
depending o n where yo u use it. Fo r lo cal variables, it changes the sto rage class to permanent.
We will examine its o ther uses as they arise.
for Loop Scope
In general, the sco pe o f a lo cal variable is restricted to the blo ck ({}) in which it resides. The f o r statement is
special in that yo u can declare the lo o p variable right inside the f o r itself.
Edit var-types.cpp as sho wn:
Co de to Edit: var-types.cpp
#include <iostream>
int global = 1; // Global variable to play around with
int main()
{
int loop;
// A loop counter
for (int loop = 0; loop < 3; ++loop) {
int temp = 1; // A local variable to play around with
static int perm = 1; // A local, permanent variable to play with
std::cout
std::cout
std::cout
std::cout
++global;
++temp;
++perm;
// Almost
<<
<<
<<
<<
"loop is "
"global is
"temp is "
"perm is "
<< loop << std::endl;
" << global << std::endl;
<< temp << std::endl;
<< perm << std::endl;
useless comment
}
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
loop is 0
global is 1
temp is 1
perm is 1
loop is 1
global is 2
temp is 1
perm is 2
loop is 2
global is 3
temp is 1
perm is 3
In this case, the lo o p variable has a sco pe o f the entire bo dy o f the f o r lo o p.
Hidden Variables
No w we'll discuss hidden variables. First let's see them in actio n. Create a pro gram called hidden.cpp and
type in the pro gram belo w.
Co de to Type: hidden.cpp
/*
* hidden -- A very good demonstration of what not to do.
* More of a puzzle than a useful program.
*/
#include <iostream>
int main()
{
int a_var = 2;
int b_var = 5;
std::cout << "a_var #1 is " << a_var << std::endl;
std::cout << "b_var #1 is " << b_var << std::endl << std::endl;
{
int a_var = 3;
std::cout << "a_var #2 is " << a_var << std::endl;
std::cout << "b_var #2 is " << b_var << std::endl << std::endl;
}
std::cout << "a_var #3 is " << a_var << std::endl;
std::cout << "b_var #3 is " << b_var << std::endl;
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
a_var #1 is 2
b_var #1 is 5
a_var #2 is 3
b_var #2 is 5
a_var #3 is 2
b_var #3 is 5
It lo o ks like a_var switched values in the middle o f the pro gram to 3 and then back to 2. But did it?
No t quite. So what's happening? Let's start by lo o king at the sco pe o f b_var since we haven't played any
games with it.
Sco pe o f b_var
int main()
{
int a_var = 2;
int b_var = 5;
std::cout << "a_var #1 is " << a_var << std::endl;
std::cout << "b_var #1 is " << b_var << std::endl << std::endl;
{
int a_var = 3;
std::cout << "a_var #2 is " << a_var << std::endl;
std::cout << "b_var #2 is " << b_var << std::endl << std::endl;
}
std::cout << "a_var #3 is " << a_var << std::endl;
std::cout << "b_var #3 is " << b_var << std::endl;
return (0);
}
b_var's sco pe includes all o f the co de sho wn in gre e n. No w we'll sho w the sco pe o f int a_var = 3;—we
need to say int a_var = 3; to identify the variable instead o f a_var, because there are two a_var variables.
This co nfusio n sho uld pro vide a clue as to why hidden variables are a bad thing.
Here's the sco pe o f int a_var = 3;:
Sco pe o f a_var(3)
int main()
{
int a_var = 2;
int b_var = 5;
std::cout << "a_var #1 is " << a_var << std::endl;
std::cout << "b_var #1 is " << b_var << std::endl << std::endl;
{
int a_var = 3;
std::cout << "a_var #2 is " << a_var << std::endl;
std::cout << "b_var #2 is " << b_var << std::endl << std::endl;
}
std::cout << "a_var #3 is " << a_var << std::endl;
std::cout << "b_var #3 is " << b_var << std::endl;
return (0);
}
No w let's add int a_var = 2 to the mix:
Sco pe o f a_var(2) and a_var(3)
int main()
{
int a_var = 2;
int b_var = 5;
std::cout << "a_var #1 is " << a_var << std::endl;
std::cout << "b_var #1 is " << b_var << std::endl << std::endl;
{
int a_var = 3;
std::cout << "a_var #2 is " << a_var << std::endl;
std::cout << "b_var #2 is " << b_var << std::endl << std::endl;
}
std::cout << "a_var #3 is " << a_var << std::endl;
std::cout << "b_var #3 is " << b_var << std::endl;
return (0);
}
Because a_var(3) has the innermo st sco pe where it is defined, it hides a_var(2) in the middle o f the pro gram.
Thus, the sco pe fo r a_var(2) has a ho le in it.
In o ther wo rds, the declaratio n o f a_var(3) hides a_var(2) in the dark re d area.
Avo id using hidden variables whenever po ssible. That's because if yo u say so mething like "And here I print
the value o f a_var," so meo ne has to ask yo u, "Which a_var?" There's eno ugh co nfusio n in the pro graming
wo rld no w witho ut us adding mo re!
Yo u made it! In the next lesso n we will put sco pe to wo rk with functions. Stay tuned!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Functions
C++ 1: Introduction to C++ Lesson 11
What is a Function?
In prio r lesso ns, o ur pro grams were fairly sho rt. Repetitio n so far has been limited to fo r and while lo o ps.
In this lesso n we'll learn ho w to use functions to o rganize frequently-used co de. A functio n is like a black bo x—yo u
pro vide the bo x with so me parameters, and it returns the result.
Our First Function
Let's suppo se we want to co mpute the area o f a right triangle (the fo rmula is are a = (base * he ight ) / 2).
Create a pro ject named t riangle and assign it to yo ur C++1_Le sso ns wo rking set. In the new pro ject, create
a so urce file named t riangle .cpp as sho wn:
Co de to Type: triangle.cpp
#include <iostream>
int main()
{
float width;
float height;
float area;
width = 5.0;
height = 2.0;
area = (width * height) / 2.0;
std::cout << "Area of the first triangle is " << area << std::endl;
return(0);
}
Save and run the pro gram. Yo u'll see:
OBSERVE:
Area of the first triangle is 5
Excellent! Suppo se yo u no w want to calculate area fo r two mo re triangles. Extend yo ur pro gram as sho wn:
Co de to Edit: triangle.cpp
#include <iostream>
int main()
{
float width;
float height;
float area;
width = 5.0;
height = 2.0;
area = (width * height) / 2.0;
std::cout << "Area of the first triangle is " << area << std::endl;
width = 3.8;
height = 5.9;
area = (width * height) / 2.0;
std::cout << "Area of the second triangle is " << area << std::endl;
width = 2.8;
height = 1.6;
area = (width * height) / 2.0;
std::cout << "Area of the third triangle is " << area << std::endl;
return (0);
}
Save and run the pro gram. Yo u'll see:
OBSERVE:
Area of the first triangle is 5
Area of the second triangle is 11.21
Area of the third triangle is 2.24
In o ur pro gram, we have lines o f co de that repeat:
OBSERVE:
area = (width * height) / 2.0;
std::cout << "Area of the (nth) triangle is " << area << std::endl;
Let's take tho se lines o f co de and turn them into a functio n. Edit yo ur pro gram:
Co de to Edit: triangle.cpp
#include <iostream>
/*
* triangle -- compute the area of a triangle
*
* Parameters
*
width -- the width of the triangle
*
height -- the height of the triangle
*
* Returns
*
the area of the triangle
*/
float triangle(float width, float height) {
float area = (width * height) / 2.0;
return (area);
}
int main()
{
float width;
float height;
float area;
width = 5.0;
height = 2.0;
area = (width * height) / 2.0;
std::cout << "Area of the first triangle is " << area << std::endl;
width = 3.8;
height = 5.9;
area = (width * height) / 2.0;
std::cout << "Area of the second triangle is " << area << std::endl;
width = 2.8;
height = 1.6;
area = (width * height) / 2.0;
std::cout << "Area of the third triangle is " << area << std::endl;
return (0);
}
Let's take a clo ser lo o k at the triangle() functio n:
OBSERVE:
float triangle(float width, float height) {
float area = (width * height) / 2.0;
return (area);
}
The first line specifies the re t urn t ype , nam e , and param e t e rs o f the functio n. Our functio n named
t riangle will return a f lo at value. It requires two parameters—the first is a f lo at nam e d widt h, the seco nd
is a f lo at nam e d he ight . After calculating the are a, the functio n re t urns it.
No w that we've defined o ur functio n, let's update o ur pro gram to call it:
Co de to Edit: triangle.cpp
#include <iostream>
/*
* triangle -- compute the area of a triangle
*
* Parameters
*
width -- the width of the triangle
*
height -- the height of the triangle
*
* Returns
*
the area of the triangle
*/
float triangle(float width, float height) {
float area = (width * height) / 2.0;
return (area);
}
int main()
{
float width;
float height;
float area;
width = 5.0;
height = 2.0;
area = (width * height) / 2.0;
area = triangle(5.0, 2.0);
std::cout << "Area of the first triangle is " << area << std::endl;
width = 3.8;
height = 5.9;
area = (width * height) / 2.0;
area = triangle(3.8, 5.9);
std::cout << "Area of the second triangle is " << area << std::endl;
width = 2.8;
height = 1.6;
area = (width * height) / 2.0;
area = triangle(2.8, 1.6);
std::cout << "Area of the third triangle is " << area << std::endl;
return (0);
}
Save and run it. Yo u'll see the same o utput as befo re:
OBSERVE:
Area of the first triangle is 5
Area of the second triangle is 11.21
Area of the third triangle is 2.24
Fo r each triangle calculated, we replaced three lines o f co de with o ne. We're making pro gress! Do yo u
ano ther area where we co uld save a few lines o f co de?
Void Functions and Array Parameters
In o ur pro gram, we co uld also add co de to the t riangle () functio n to display the message like::
OBSERVE:
float triangle(float width, float height) {
float area = (width * height) / 2.0;
std::cout << "Area of the triangle is " << area << std::endl;
return (area);
}
This message wo uld be a side effect o f the t riangle () functio n. A functio n has a side effect if it o utputs
messages, mo difies files, o r o therwise perfo rms so me actio n besides returning a value. Generally speaking,
side effects are no t a go o d idea.
Instead, let's create a separate functio n to o utput the message. Change yo ur pro gram:
Co de to Edit: triangle.cpp
#include <iostream>
/*
* triangle -- compute the area of a triangle
*
* Parameters
*
width -- the width of the triangle
*
height -- the height of the triangle
*
* Returns
*
the area of the triangle
*/
float triangle(float width, float height) {
float area = (width * height) / 2.0;
return (area);
}
/*
* print_it -- output a message
*
* Parameters
*
area -- the area of the triangle
*
what -- the name of the triangle
*/
void print_it(float area, char what[])
{
std::cout << "The area of the " << what << " triangle is " << area << std::e
ndl;
}
int main()
{
float area; // Area of a triangle
area = triangle(5.0, 2.0);
std::cout << "Area of the first triangle is " << area << std::endl;
area = triangle(3.8, 5.9);
std::cout << "Area of the second triangle is " << area << std::endl;
area = triangle(2.8, 1.6);
std::cout << "Area of the third triangle is " << area << std::endl;
return (0);
}
Let's take a clo ser lo o k at print _it ():
OBSERVE:
void print_it(float area, char what[])
{
std::cout << "The area of the " << what << " triangle is " << area << std::e
ndl;
}
This functio n named print _it () returns vo id, which means "no thing" in C++. In o ther wo rds, o ur functio n
do es no t return any value. It has two parameters—a f lo at nam e d are a and a C-St yle st ring nam e d what
(a character array named what). The character array parameter has no dimensio n. That is because the
dimensio n is determined by the co de that calls the print _it (), as yo u will see sho rtly.
Note
So me o ther languages might call print _it () a pro cedure, because it do es no t return a value,
and call t riangle a functio n because it do es return a value. C++ just has o ne co nstruct, a
functio n.
Our functio n do es no t have a re t urn statement because it isn't required inside a vo id functio n. Let's add it,
and revise o ur pro gram to call print _it ():
Co de to Edit: triangle.cpp
#include <iostream>
/*
* triangle -- compute the area of a triangle
*
* Parameters
*
width -- the width of the triangle
*
height -- the height of the triangle
*
* Returns
*
the area of the triangle
*/
float triangle(float width, float height) {
float area = (width * height) / 2.0;
return (area);
}
/*
* print_it -- output a message
*
* Parameters
*
area -- the area of the triangle
*
what -- the name of the triangle
*/
void print_it(float area, char what[])
{
std::cout << "The area of the " << what << " triangle is " << area << std::e
ndl;
return;
}
int main()
{
float area; // Area of a triangle
area = triangle(5.0, 2.0);
std::cout << "Area of the first triangle is " << area << std::endl;
print_it(area, "first");
area = triangle(3.8, 5.9);
std::cout << "Area of the second triangle is " << area << std::endl;
print_it(area, "second");
area = triangle(2.8, 1.6);
std::cout << "Area of the third triangle is " << area << std::endl;
print_it(area, "third");
return (0);
}
Save and run it. Yo u'll see the same o utput again:
OBSERVE:
The area of the first triangle is 5
The area of the second triangle is 11.21
The area of the third triangle is 2.24
Function Overloading
Our print _it () functio n wo rks fine, but what if we didn't always want to pass the seco nd parameter? In C++,
we can overload a functio n, which means that we can have two o r mo re different functio ns with the same
name and different parameters.
Let's define a new print _it () with o nly o ne parameter instead o f two . Edit yo ur pro gram as sho wn:
Co de to Edit: triangle.cpp
#include <iostream>
/*
* triangle -- compute the area of a triangle
*
* Parameters
*
width -- the width of the triangle
*
height -- the height of the triangle
*
* Returns
*
the area of the triangle
*/
float triangle(float width, float height) {
float area = (width * height) / 2.0;
return (area);
}
/*
* print_it -- output a message
*
* Parameters
*
area -- the area of the triangle
*
what -- the name of the triangle
*/
void print_it(float area, char what[])
{
std::cout << "The area of the " << what << " triangle is " << area << std::e
ndl;
return;
}
/*
* print_it -- output a message without the "what"
*
* Parameters
*
area -- the area of the triangle
*/
void print_it(float area)
{
std::cout << "The area of the triangle is " << area << std::endl;
return;
}
int main()
{
float area; // Area of a triangle
area = triangle(5.0, 2.0);
print_it(area, "first");
area = triangle(3.8, 5.9);
print_it(area, "second");
area = triangle(2.8, 1.6);
print_it(area, "third");
return (0);
}
Save and run it. Yo u'll see this slightly different result:
OBSERVE:
The area of the triangle is 5
The area of the second triangle is 11.21
The area of the third triangle is 2.24
The first time we call print _it () with o nly o ne parameter, and C++ runs the co rrect print _it () functio n that
accepts o ne parameter (the seco nd o ne in the pro gram). The next two times, we call it with two parameters,
and C++ runs the co rrect functio n that accepts two parameters (the first o ne in the pro gram).
C++ keeps track o f this by using function signatures. A functio n signature is the co mbinatio n o f the functio n
name, return data type, parameter data types, and names. In o ur pro gram, there are actually fo ur functio ns:
1. flo at triangle(do uble width, do uble height)
2. vo id print_it(flo at area, char what[])
3. vo id print_it(flo at area)
4. int main()
In C++, the functio n name and parameters must be unique. In o ther wo rds, yo u canno t define two separate
functio ns like this:
1. vo id print_it(flo at area)
2. int print_it(flo at area)
Default Parameters
C++ lets yo u define functio ns with default parameters. Fo r example, yo u co uld decide that triangles have a
default height o f 2.0 . Yo u can add a small bit o f co de to the parameter list to specify this:
OBSERVE:
float triangle(float width, float height = 2.0) {
To see this change in actio n, edit yo ur pro gram:
Co de to Edit: triangle.cpp
#include <iostream>
/*
* triangle -- compute the area of a triangle
*
* Parameters
*
width -- the width of the triangle
*
height -- the height of the triangle
*
* Returns
*
the area of the triangle
*/
float triangle(float width, float height = 2.0) {
float area = (width * height) / 2.0;
return (area);
}
/*
* print_it -- output a message
*
* Parameters
*
area -- the area of the triangle
*
what -- the name of the triangle
*/
void print_it(float area, char what[])
{
std::cout << "The area of the " << what << " triangle is " << area << std::e
ndl;
return;
}
void print_it(float area)
{
std::cout << "The area of the triangle is " << area << std::endl;
return;
}
int main()
{
float area; // Area of a triangle
area = triangle(5.0, 2.0);
print_it(area);
area = triangle(3.8, 5.9);
print_it(area, "second");
area = triangle(2.8, 1.6);
print_it(area, "third");
return (0);
}
Save and run it. Yo u'll see the same results as befo re:
OBSERVE:
The area of the first triangle is 5
The area of the second triangle is 11.21
The area of the third triangle is 2.24
If we DO pro vide a height, the functio n uses it; o tehrwise, it uses the default 2.0 .
WARNING
Using default parameters hides info rmatio n and can make pro grams co nfusing. While
yo u may enco unter default parameters in existing pro grams, yo u wo uld be wise to avo id
using them in new pro grams.
We co vered a lo t o f info rmatio n in this lesso n! In the next lesso n, we'll co ntinue o ur discussio n o f parameters and types. Stay
tuned!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Parameters and Return Types
C++ 1: Introduction to C++ Lesson 12
Welco me back! In the last lesso n we discussed functio ns, and learned ho w to write o ur o wn functio ns with parameters. In this
lesso n, we'll explain just ho w parameters wo rk.
Passing Parameters
C++ pro vides many ways o f passing parameters to functio ns. Kno wing what cho ices yo u have and ho w to use them is
key to writing go o d C++ co de.
Pass by Value
Let's start with a sho rt pro gram. Create a pro ject named var-pass and assign it to yo ur C++1_Le sso ns
wo rking set. In the new pro ject, create a pro gram named var-pass.cpp as sho wn:
Co de to Type: var-pass.cpp
#include <iostream>
void test(int a)
{
std::cout << "test: a is " << a << std::endl;
a = 5;
std::cout << "test: a is " << a << std::endl;
}
int main()
{
int i;
// Variable to play around with
i = 2;
test(i);
std::cout << "main: i is " << i << std::endl;
return(0);
}
Save and run the pro gram, and o bserve the o utput:
Output o f var-pass
test: a is 2
test: a is 5
main: i is 2
We passed i as a parameter to t e st (), where it was labeled a. We changed the value o f a inside t e st (), but
that change did no t make its way back to i. Why did this happen?
It happened because the parameters to the t e st () functio n were passed by value. Internally, C++ co pies the
values o f any variables passed by value and passes the co py to the functio n. Any changes to this co py will
no t be reflected in the calling pro cedure. This is the default way C++ passes parameters to functio ns.
Remember when we discussed ho w variables were like mailbo xes? Passing by value is like making
pho to co pies o f yo ur mail, then putting the co pies in the mailbo x (the functio n), keeping the o riginals safe.
C++ lets yo u pass by re f e re nce as well, using the reference (&) o perato r. Edit yo ur pro gram as sho wn:
Co de to Edit: var-pass.cpp
#include <iostream>
void test(int& b)
{
std::cout << "test: b is " << b << std::endl;
b = 6;
std::cout << "test: b is " << b << std::endl;
}
int main()
{
int i;
// Variable to play around with
i = 2;
test(i);
std::cout << "main: i is " << i << std::endl;
return(0);
}
Save and run it. Yo u see:
Output o f var-pass
test: b is 2
test: b is 6
main: i is 6
In this pro gram, i passed by reference, so the t e st () functio n changed its value: m ain: i is 6 !
With pass by reference, C++ makes the parameter b a reference to main's lo cal variable i. A reference means
that these variables are the same thing. As a result, any change to b is a change to i.
Using the mailbo x analo gy again, passing by reference is like putting the o riginal letter in the mailbo x, so the
recipient (the functio n) can lo o k at and po tentially change it.
Array Parameters
No w let's see ho w functio ns wo rk with arrays. We'll add an array parameter to o ur pro gram.
Co de to Edit: var-pass.cpp
#include <iostream>
void test(int k[])
{
std::cout << "test: k[0] is " << k[0] << std::endl;
k[0] = 7;
std::cout << "test: k[0] is " << k[0] << std::endl;
}
int main()
{
int k[3] = {10, 20, 30}; // Array to play around with
test(k);
std::cout << "main: k[0] is " << k[0] << std::endl;
return(0);
}
Save and run it. Yo u'll see:
OBSERVE:
test: k[0] is 10
test: k[0] is 7
main: k[0] is 7
No tice that the value o f k[0 ] is changed, even tho ugh we didn't use the & reference o perato r. That's because
arrays are auto matically passed by reference. In fact, there is no way to make them pass by value.
What happens if yo u pass k[0 ] to a functio n instead? Let's try it:
Co de to Edit: var-pass.cpp
#include <iostream>
void test(int a)
{
std::cout << "test: a is " << a << std::endl;
a = 5;
std::cout << "test: a is " << a << std::endl;
}
int main()
{
int k[3] = {10, 20, 30}; // Array to play around with
test(k[0]);
std::cout << "main: k[0] is " << k[0] << std::endl;
return(0);
}
Save and run it. Yo u'll see:
OBSERVE:
test: a is 10
test: a is 5
main: k[0] is 10
A single array element is just like a single variable—so by default, C++ passes by value.
Const Parameters
Let's no w pro duce a pro gram with a functio n that returns the maximum o f two integers. Start a new pro ject
named m ax and assign it to yo ur C++1_Le sso ns wo rking set. Create a so urce file named m ax.cpp as
sho wn:
Co de to Type: max.cpp
#include <iostream>
// Function comments
int max(int i1, int i2)
{
if (i1 > i2)
return (i1);
return(i2);
}
int main()
{
int i = 1;
int j = 2;
std::cout << "Max is " << max(i,j) << std::endl;
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
Max is 2
No tice that the values o f i1 and i2 are never changed in the m ax() functio n. Given the nature o f the functio n,
they never sho uld be changed.
But what if so meo ne decided to change the parameter? Edit the pro gram as sho wn:
Co de to Edit: max.cpp
#include <iostream>
// Function comments
int max(int i1, int i2)
{
i1 = 99;
if (i1 > i2)
return (i1);
return(i2);
}
int main()
{
int i = 1;
int j = 2;
std::cout << "Max is " << max(i,j) << std::endl;
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
Max is 99
The functio n sho uld no t change the value o f the parameters! To help ensure that the parameters do n't change,
put the mo difier co nst in fro nt o f them. Edit yo ur pro gram as sho wn:
Co de to Edit: max.cpp
#include <iostream>
int max(const int i1, const int i2)
{
i1 = 99;
if (i1 > i2)
return (i1);
return(i2);
}
int main()
{
int i = 1;
int j = 2;
std::cout << "Max is " << max(i,j) << std::endl;
return (0);
}
Save yo ur pro gram—yo u'll see this erro r:
Co de that attempts to change the value o f a co nstant parameter results in a co mpile-time erro r. In this case,
the co de i1 = 9 9 is the o ffender.
References
References let different variables po int to the same underlying value. It is like having a two -sided mailbo x—
the po stal wo rker o pens the bo x o n o ne side to depo sit mail, and yo u o pen the bo x o n the o ther side to
retrieve it. Bo th do o rs po int to the same co ntents. Let's take a deeper lo o k at references. Change yo ur co de
as sho wn:
Co de to Edit: max.cpp
#include <iostream>
int& max(const int& i1, const int& i2)
{
i1 = 99;
if (i1 > i2)
return (i1);
return(i2);
}
int main()
{
int i = 1;
int j = 2;
std::cout << "Max is " << max(i,j) << std::endl;
return (0);
}
Save and run it—yo u'll see the o riginal message again.
No w, let's add a new variable (l), which is a reference to j. We'll then zero this reference, which sho uld cause i
to be zero ed. Change the co de as sho wn:
Co de to Edit: max.cpp
#include <iostream>
int& max(int& i1, int& i2)
{
if (i1 > i2)
return (i1);
return(i2);
}
int main()
{
int i = 1;
int j = 2;
std::cout << "Max is " << max(i,j) << std::endl;
{
int& l = j; // l now refers to j
l = 0; // Since l is j, j is now zero
std::cout << "j #1 is " << j << std::endl;
}
std::cout << "j #2 is " << j << std::endl;
return (0);
}
Save and run it. Sure eno ugh, l and i bo th po int to the same place, and i ends up being set to 0 :
OBSERVE:
Max is 2
j #1 is 0
j #2 is 0
This is because o ur latest and greatest m ax() functio n returns a reference to i. Because it's a reference, we
can use it o n the left side o f the equals sign (=) as well as the right.
Make the changes indicated in the pro gram to remo ve the reference k and replace it with the reference max(i,
j).
Co de to Edit: max.cpp
#include <iostream>
int& max(int& i1, int& i2)
{
if (i1 > i2)
return (i1);
return(i2);
}
int main()
{
int i = 1;
int j = 2;
std::cout << "Max is " << max(i,j) << std::endl;
{
max(i, j) = 0;
// Assigning a reference
l = 0; // Since l is j, j is now zero
std::cout << "j #1 is " << j << std::endl;
}
std::cout << "j #2 is " << j << std::endl;
return (0);
}
Save and run it. Yo u'll see:
OBSERVE:
Max is 2
j #1 is 0
j #2 is 0
Sure eno ugh, the reference returned by m ax(i,j), which po inted to the same place as j, was changed to zero .
Const Return Values
In the last example, we co uld assign a value to the reference returned by m ax(i,j). To keep this fro m
happening, let's change the functio n so it returns a co nst reference.
Co de to Edit: max.cpp
#include <iostream>
const int& max(int& i1, int& i2)
{
if (i1 > i2)
return (i1);
return(i2);
}
int main()
{
int i = 1;
int j = 2;
std::cout << "Max is " << max(i,j) << std::endl;
{
max(i, j) = 0;
// Assigning a reference
std::cout << "j #1 is " << j << std::endl;
}
std::cout << "j #2 is " << j << std::endl;
return (0);
}
Once yo u save yo ur file yo u will no tice that we can no lo nger assign a value to m ax(). Because it is a
co nstant, we can o nly retrieve the result, no t change it:
Problems with Reference Returns
Returning a reference as an int has its benefits, but it can be very tricky to use. Let's change o ur co de so that
m ax() assigns the result to a lo cal variable and returns that variable instead.
Co de to Edit: max.cpp
#include <iostream>
const int& max(int& i1, int& i2)
{
int result; // Which one to use
if (i1 > i2)
result = i1;
else
result = i2;
// This is a bad thing to do
return(result);
}
int main()
{
int i = 1;
int j = 2;
std::cout << "Max is " << max(i,j) << std::endl;
{
max(i, j) = 0; // Assigning a reference
std::cout << "i is " << i << std::endl;
}
return (0);
}
Save it—yo u'll see a warning:
The co mpiler warns yo u that yo u are returning a reference to a local variable. This is reminding yo u that the
variable re sult will be destro yed when m ax() returns. This is like remo ving yo ur mailbo x fro m the wall—the
po stal wo rker can't put anything into the bo x, and yo u can't either.
So ... what do es the reference generated by the re t urn statement refer to ? Absolutely nothing. The value
referenced is no t in sco pe, so it is no t legal to reference it. This is yet ano ther area o f undefined behavio r in
C++. Yo ur pro gram might wo rk just fine, o r it co uld crash, o r it co uld cause strange and mysterio us data
erro rs.
When a reference refers to so mething that is no lo nger in sco pe, it's called a dangling reference. Yo u can't
(le gally) re t urn a re f e re nce t o a lo cal variable f ro m inside a f unct io n.
No w let's try ano ther experiment with o ur pro gram. Edit the pro gram so that it uses expressio ns as
parameters to m ax():
Co de to Edit: max.cpp
#include <iostream>
const int& max(int& i1, int& i2)
{
int result; // Which one to use
if (i1 > i2)
return (i1);
return(i2);
}
int main()
{
int i = 1;
int j = 2;
int answer;
answer = max(i+1, j+1);
std::cout << "Max is " << answer << std::endl;
return (0);
}
This pro gram to o has a dangling reference that is hard to spo t, but the co mpiler wo n't let it by.
Save it and yo u'll see:
When a functio n expects a reference parameter such as m ax(), the co mpiler perfo rms a number o f
o peratio ns behind the scenes:
1. It creates a tempo rary variable and assigns it the value o f the expressio n.
2. It perfo rms the functio n call.
3. It destro ys the tempo rary variable.
So the co de the co mpiler generates lo o ks so mething like:
The co mpiler's versio n o f max.cpp
#include <iostream>
int& max(int& i1, int& i2)
{
if (i1 > i2)
return (i1);
return(i2);
}
int main()
{
int i = 1;
int j = 2;
int answer;
{
int tmp1 = i + 1;
int tmp2 = j + 1;
answer = max(tmp1, tmp2);
// At this point answer is a reference to tmp2
}
// At this point tmp2 does not exist
std::cout << "Max is " << answer << std::endl;
return (0);
}
Yo u will rarely need to use references to variables as return values, but when yo u do need to use them, be
very careful abo ut what yo u are do ing.
Yo u made it! In the next lesso n we'll discuss yo ur final pro ject fo r the co urse. Go o d luck!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Final Project
C++ 1: Introduction to C++ Lesson 13
Putting It All T ogether
At this po int we've learned eno ugh to create yo ur very o wn pro gram fro m scratch.
Assignment
To start, create a pro ject named f inal_pro je ct assigned to yo ur C++1_Ho m e wo rk wo rking set, with a
so urce file named f inal_pro je ct .cpp.
Yo ur assignment is to create a pro gram that will co unt the number o f wo rds in a file. It is up to yo u to define
what a "wo rd" is. "hello " is a wo rd. But what abo ut "high-five"—is that o ne wo rd o r two ? And ho w abo ut
so mething like "gro und_po int"? So me pro grammers might co nsider that o ne wo rd and o thers think it was
two . Did yo u co nsider so mething like "O'Reilly"?
Whatever yo u decide to co nsider a wo rd, do cument yo ur decisio n in a file named re quire m e nt s.t xt .
The specificatio n is as exact a descriptio n as yo u can get o f what the pro gram is go ing to do . So metimes yo u
do n't kno w ho w a pro gram is go ing to end up until yo u start co ding. In that case, yo u start with a preliminary
specificatio n and refine it as yo u go o n.
At the end o f co ding, the specificatio n sho uld be detailed eno ugh that yo u can use it as a user guide.
Create a file named spe c.t xt and write yo ur specificatio n in it.
Code Design
The design is a general o utline o f ho w yo u are go ing to create yo ur pro gram.
The design fo r this wo rd co unt pro gram sho uld be fairly sho rt. A go o d paragraph describing the general
o peratio n o f the co de sho uld do it. Create a file named de sign.t xt and enter yo ur design.
Agile Development
Years ago there was pro gramming technique called "fast pro to typing." To day, it has been renamed "agile
develo pment." Basically, it means that yo u create the smallest wo rking pro gram yo u can. Test it, enhance it,
and repeat until yo u get what yo u want. The idea is that yo u start with a wo rking co py and build a wo rking
pro gram o n to p o f that. That way, yo u have a wo rking pro gram to see where yo u are and to give yo u an idea
o f what the co mputer can do . This lets yo u refine yo ur specificatio n as yo u learn mo re abo ut what's
happening with yo ur system.
In this case, there are three stages that we go thro ugh in o ur develo pment:
1. Make a pro gram that reads a character at a time, co unting no thing.
2. Make the pro gram co unt characters.
3. Change the pro gram to co unt wo rds.
Coding Notes
To help yo u get started, the fo llo wing is co de that will read each character fro m a file called input .t xt and will
o utput it. It uses f st re am .
Co de to Type: final_pro ject.cpp
#include <iostream>
#include <fstream>
int main () {
char c;
std::ifstream myfile ("input.txt");
// Make sure the file can be read from
if (myfile.is_open())
{
// While we have not reached the end of file (EOF)
while (! myfile.eof() )
{
c = myfile.get();
std::cout << c;
}
myfile.close();
}
else std::cout << "Unable to open file";
return 0;
}
Create a file named input .t xt in yo ur pro ject, add so me appro priate text to it, and then save and run this
co de to see ho w it wo rks. Yo ur pro gram will pro mpt fo r user input instead o f using a file.
T esting
Testing co mes next. Write up a test plan fo r yo ur pro gram named t e st .t xt . Take care to test all majo r
co mpo nents o f yo ur pro gram.
I wo uld suggest that yo u create a file named "input.txt" co ntaining the input that yo u want to use fo r testing the
pro gram.
To actually test the pro gram:
1. Open the input.txt file.
2. Select Edit | Se le ct All.
3. Select Edit | Co py.
4. Run the pro gram.
5. Click in the co nso le and select Edit | Past e to paste the test file's co ntents into yo ur pro gram's
input.
6 . Type [Ct rl+Z ] to signal end o f file.
Revisions
Yo ur pro gram co unts wo rds. Think o f ho w yo u might want to enhance it. Create a file named "rev.txt"
co ntaining the wish list fo r yo ur new pro gram. Then be thankful that yo u've reached the end o f the lesso n and
yo u do n't have to implement any o f tho se revisio ns!
When yo u finish, hand in yo ur pro ject. GOOD LUCK!
Copyright © 1998-2013 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.