Once we are able to declare variables, the next useful operation is
to be able to change the value of those variables. We can change a
value by reading in a new one from cin
(as in
Experiment #2), but we definitely do not want to get all
of our information that way.
The value of a variable is changed most often through an assignment expression. Like an input or output expression, an assignment expression is complete in itself, so we can just tack on a semicolon for a statement:
Here,Variable
=Expression
;
Expression
is any valid C++ statement
and Variable
is an identifier that has been
declared as a variable, whose type matches that
of Expression
.
Looks familiar, doesn't it? It's a declaration without the data type.
When execution reaches this statement:
Expression
is evaluated.Variable
.For now, declare every variable once, just before you use it the first time. We'll see later on that there many situations where you'll use the same identifier in two or more declarations. We're not there yet. So, declare your variable once, and then use assignment statements to change the value.
Recognizing a declaration is simple: look for a data type. If you
see a data type (e.g., int
, double
, char
,
etc.) in your statement, the compiler thinks you have a declaration.
All operators in C++ actually evaluate to and return a value. Some operators also have a side effect, a change seen outside the statement. For example, the output operator as an operator evaluates to an output stream. Changing the contents of the screen is a side effect.
Similarly, an assignment operator has a side effect: change the
contents of a variable. But it also has a value. Let's figure out
what that value is by printing assignment expressions. Add this to
your program, after your declaration of i
:
cout << "555: " << ( i = 555 ) << endl << "-36: " << ( i = -36 ) << endl << "2+3: " << ( i = 2+3 ) << endl;
Question #3.9.1: What does this output statement display?
Because the assignment symbol =
is an actual operator that
produces a value in addition to making a side effect, we can chain
it along:
i = j = k = 78;This is known as assignment chaining.
But what are the values of i
, j
, and k
after
the assignment?
Modify your program to declare i
, j
, and k
,
initializing them to different values all less than 10. Right after
this declaration, put in the assignment chain from above. Then print
out the values of i
, j
, and k
. Compile and
run your program.
Question #3.9.2: What are the values ofi
,j
, andk
?
Surprised? Consider the implications of this result.
If =
were left associative, the compiler would implicitly
parenthesize the expression like so:
(((i = j) = k) = 78);which seems a bit confusing. Sure, we'd start by assigning
i
the value in j
, but then what? A tempting suggestion would
be to assign the value of k
to j
, but that's not what
the parenthesized code says. It turns out that this expression with
these parentheses does compile in C++. Try it out.
Explicitly parenthesize the assignment chain as left associative. Recompile and execute the code.
Question #3.9.3: What are the values ofi
,j
, andk
?
Wacky. Doesn't seem particularly useful since there's a much simpler statement we could use instead.
Question #3.9.4: What's the simpler expression that would give us that same result?
Well, if the assignment operator is not left associative, it must be right associative ("middle associative" would be really wacky and too often ambiguous!):
(i = (j = (k = 78)));Do the inner parentheses first: assign 78 to
k
. Sounds
good. As an expression, that assignment evaluates to 78, so we can
also assign that value to j
. Sounds even better. Is i
any different? Let's try it out.
Explicitly parenthesize the assignment chain right associative. Recompile and execute the code.
Question #3.9.5: What are the values ofi
,j
, andk
?