Java Compound Assignment Operators
Other Compound Assignment Operators
![]()
This work is licensed under a Creative Commons Attribution-No Derivative
Works 3.0 United States License.
Copyright: Dennie Van Tassel 2008.
Please send suggestions and comments to dvantassel@gavilan.edu
Assignment (hours = 40) may seem like one of the simplest of operations, but assignment has such universal use, and thus results in wide solutions to some of the problems involved. Examples of choices are simple assignment (assign one value to one variable) or multiple assignments (assign one value to several variables). There are also conditional assignments of values and variables in some languages. When we have a language that has different forms of assignment (compound, multiple) there are serious issues about exactly when the operands are evaluated. Finally, there is the question about exactly what can be assigned, such as only simple variables, or maybe arrays, structures, or objects.
The assignment statement is the most common type of statement found in programs. In an early study of statement types, Knuth found that 51% of the statements used in FORTRAN programs are assignment statements. The next two percentages were 8.5% for IF statements and 8% for GOTO statements.[1] While these statistics are probably different in modern languages, assignment is still the most commonly used statement.
At its simplest form, assignment looks something like:
variable =
expression
count = 0
The expression or the right-hand value (called the r-value) is evaluated, and that value is placed in the item on the left-hand side (often called the l-value). The right expression needs to be a constant, variable, or expression that can produce a value. The l-value must be something that has memory to store a value. The expression on the right is also called the source of the assignment, and the left-hand side is called the destination of the assignment. L-value is also referred to as the location value, since that is the location where something is stored. And r-value is also called the read-value since that value needs to be read. But this last set of terminology seems rare.
Here are a few design issues for assignment:
Now we will look at these interesting questions about assignment. The first question is what do we use for the assignment operator? The related question is how do we differentiate assignment (count=1) from comparison? If you immediately jumped on the C bandwagon of using = for assignment and == for comparison, then I can ask if you have ever been burnt by something like this?
while (count=1) . . . // one
equal symbol.
which will probably get us a nice infinite loop since we meant to use
while (count==1) . . . // two
equal symbols.
This code is a good example of how a language design issue
can have major impact on programming productivity and program readability. [=== what is term for making sure things
are different enough so not mistaken???]
Since we (and the compiler) need to be able to distinguish
assignment (B
= 5) and comparison IF
(B==5)…,, then we need to look carefully at what we choose for these two
operators. The Pascal family (
COST := 5
for assignment. This use clearly indicates it is assignment and not equality, and avoids the problem of mixing up an assignment test in comparison operations with an equality test.
Table x.1 lists some of the operators used for assignment in various languages.
|
Assignment Operator |
Languages |
|
a = b |
Java, C++, Perl, FORTRAN, BASIC |
|
a := b |
Pascal, |
|
a <- b |
APL, Smalltalk |
|
(setq a b) |
Lisp |
|
MOVE B TO A |
COBOL |
|
set a b |
Tcl |
Assignment Operators
Table x.1
While the Pascal family use of := seems like the best choice to me, the simple = symbol has won in most modern languages.
Multiple assignment is one of the simplest assignment variations, but is not available in all languages. Early ALGOL contributed the concept.
x := y := z := 0;
ALGOL also used := to show assignment instead of =, which they use for equality tests. For present day languages, we indicate multiple assignments in its simple form as follows:
A = B = C = D = 0
We can make it slightly more complicated by including the same variable (B) in the variable list on the left and the expression:
A = B = C = B + 5
In this case B+5 is evaluated and all the variables are set to that value. This reminds us that assignment is evaluated from the right to the left.
In Python this is called chained assignment. We are assigning several variables to the same value. For example, if we have something similar to this:
x = y = fun();
it may not be the same as:
y = fun();
x = fun();
since the function fun()can return different values.
A conditional target is when a condition is used to decide which variable to use as the l-value or target. Java and C++ allow conditional targets by use of the conditional (ternary) operation. Thus we can do something similar to:
(n < 0) ? maxx : maxy = 0;
So either the variable maxx or maxy is set to zero depending on the condition. This can be done as follows with an if statement:
if (n < 0) maxx = 0; else maxy = 0;
but the first way is a lot neater and allowed me to bring up conditional targets.
The opposite of conditional target may be conditional value assignment, where a condition is used to determine which r-value is assigned to the single l-value. The ternary operation is also used for this as follows:
rates = (age <
21) ? 1.25 : 1.00;
In this statement the value 1.25 is assigned to the variable rates when age is less than 21. The general form of this type of statement is:
result = (condition) ? a: b;
So either value of variable a or value of variable b is assigned to variable result depending on the condition. This can be done as follows with an if statement:
if (condition) v = a; else
v = b;
if (age < 21) rates = 1.25; else rates = 1.00;
This is not actually a new type of an assignment statement, but a variation on normal assignment.
Perl, Ruby, and Python use a version of multiple assignment called simultaneous assignment, so different values are assigned “simultaneously.” In Perl, variable names start with a dollar sign, so instead of the variable tax, in Perl it would be $tax. So here is what Perl does:
($tax, $count, $size) = (0.085, 0, 100);
This sets $tax to 0.085, $count to zero, and $size to 100. Character strings can be assigned in the same ways:
($first, $middle, $last) = (“Edgar”, “Allan”, “Poe”);
This is called list assignment in Perl. In Perl, additional variables on the left side are assigned undef. For example:
($x, $y, $z) = (1, 2);
This will assign 1 to $x and assign 2 to $y, and then assign undef to $z since there are two values on the right side, and there are three variables on the left side.
Simultaneous assignment has several interesting uses. Besides statements like the above, we can do this in Python:
(x, y) = (y, x)
which will interchange the two variables, and it works the way we would want it to, switching the two values.
In Ruby parentheses are not necessary, so we do the following:
foo, bar, boo = 1, 2, 3
Which assigns 1 to foo, 2 to bar, and 3 to boo.
This type of assignment can also introduce some interesting problems. What happens in the following code?
($x, $x) = (5, 6);
In this example, we assign 5 to $x, and also assign 6 to variable $x. In this case, the variable $x will end up with the value 6 in it. Thus in all these assignment statements that are similar to this simultaneous assignment, we have the following:
(v1, v2) = (e1, e2)
There are at least two ways to process the above statement. The first way is evaluate expression-1 and then evaluate expression-2, and then do the assignments. The other way is to evaluate expression-1 on the right side, assign it to variable-1, then evaluate expression-2, and assign that value to variable-2 on the left side. If the expressions have side affects or change each other, we get different results depending on what method of evaluation is used.
Perl arrays use an @ symbol to precede the array name and use square brackets for the subscript or array index. Thus @a[$k] represents an array and $k is a valid index of a Perl array. Then what happens in the following two examples (assuming $k=0 to start with):
(@a[$k], $k) = (35, 2)
($k, @a[$k]) = (2, 35)
and is the result the same in both statements? Work through these by hand to see what result you get. Then you may want to find a Perl manual and Perl interpreter to find out how it works. There are some problems here about determining exactly when values are processed and assigned. For example, are the operands on the left side evaluated first or are the operands on the right side evaluated first?
Another interesting example is
(@a[$k], @a[$j]) = (5, 8)
What happens when the subscripts $k and $j are equal? I think the order of evaluation becomes very important here. Simultaneous assignment is a rather rare version of assignment, but available in a few languages.
The language Ruby does something similar to simultaneous assignment, but they call it parallel assignment. Their form looks as follows:
a, b, c = 1, 2, 3
So the variable a will be assigned the value 1, then the variable b will be assigned the value 2, etc. They carefully define exactly what happens. If there are extra values on the right, those extra values are ignored. If there are extra variables on the left, the extra variables are set to nil. We can do useful things like interchange two variables, as follows:
a, b = b, a
and what we hope will happen, will happen. Notice that the assignments must be done in parallel. Otherwise, both the variables would have the same value when done.
Ruby also carefully defines the order of the operations. The rules are the values on the right are evaluated in the order that they appear before any assignment is done to the variables on the left. Here is an example, where knowing exactly what happens is necessary:
w, x, y, = z, (z += 1), z += 1)
Assuming z starts with the value 5, what values will be assigned? If you are interested in parallel assignment it will be useful to look at exactly how Ruby does it. There is a bit more too it, especially when arrays are involved. Ruby also has nested assignment where the left-hand side of an assignment may contain a parenthesized list of terms.[2]
Pascal has a similar command. We can do the same sort of command as follows:
var1, var2 := 12, 15;
which will assign 12 to the var1 and 15 to var2. We can also do the useful
var1, var2 := var2, var1;
which will swap the two values without the need of a temporary variable. Trace through what has to happen here for this to work.
C++: int i = 10, j = 10;
In C++ we can assign different values to variables in the
same declaration, but in
C++: int x = 25, z = 76;
Z: INTEGER := 76;
When we declare two or more variables in one statement, both values get the same value. For example:
Since both variables on the left need a value, is the value on the right calculated once or twice? Either way seems reasonable:
The problem only appears when the expression on the right
has side effects such as a function call or increment. Here is some pseudocode
(not real
X, W: INTEGER := b++; -- Does X and W get the
same value?
M, N: INTEGER := PRT(P) -- PRT IS A FUNCTION THAT PRINTS.
What
Multiple assignment can be implemented in different ways. One way is just assigning all the variables the value on the far right:
a = b = c = 0;
Another way to implement multiple assignment is the way it is done in the C family, where assignment returns a value which is the same as the value assigned the target. This can be illustrated by printing an assignment statement as follows:
cout << “value = “ << k = 5 << endl;
The variable k will be assigned the value 5, and the result printed will be:
value = 5
Since assignment expressions return a value, we can use that to create:
a = b = c = 0;
and since assignment is associative from right to left we obtain:
a = (b = (c = 0));
So the variable c is assigned the value zero, then zero is returned and zero is assigned the variable b, and so forth.
While the above use of value from the assignment expression seems useful and correct, this characteristic can be used in stranger and more questionable ways:
price = cost + (profit = 10) + cost * 0.12;
In this somewhat bizarre use, the variable profit will be assigned 10, and then 10 will be added in the statement.
If you casually read a PL/I (or BASIC) program (which you probably do often), you might see something like this:
A = B = C;
and erroneously assume it is multiple assignment. But both BASIC and PL/I use the equal sign for both assignment and comparison. So the first “equal” sign (A = ... ) is assignment, and the second “equal” sign is comparison, so PL/I will compare the variable B and C, and assign variable A either true or false!
Early BASIC uses the = symbol for both assignment and comparison. For example:
a = 18
if (a = 18) then ....
Later Boolean type was added and also longer variable names. Now we have the following possible Visual Basic statements:
dim youth as boolean
youth = age < 18
which does not seem too unusual. Since age
< 18 is a comparison, we would expect a true
or