300 400 lineto".PRECEDENCE OPERATORS highest NOT . *, /, DIV, MOD, AND . +, -, OR lowest <, <=, <, >, =, >=, >, INNow, not only does C++ have many more operators, but it defines many more precedence levels. Too many has the potential drawback that program behavior becomes difficult to predict without constantly referring to the precedenced table. Too few levels can cause unexpected behavior. For example , in Pascal
x > y OR z > 0 is equivalent to x > (y OR z) > 0which is counterintuitive to say the least!
Issue: is assignment an expression or a
statment? I.e. will something like 3 + (x=5) be
allowed, and what will it mean? Java and C/C++ allow this,
which shows that assignements are expressions in
those languages. In the above, x=5 has the side
effect of assigning 5 to x, and the result of the
expression is simply x after the assignement. So the type
and value come directly from x. In SPL, we've defined
assignement to be a statement, so something like
write x := 5; is illegal. (Is this a lexical
error, parse error or an error in the semantic analysis
phase?)
In scheme, set! returns a void value, so you
can't really compute meaningfully with the return value of
a set!. Thus, in essence, assignment is not an
expression.
x = x + 1;is OK, but most likely
x + 1 = x;is not. Why? Why is x something that can be assigned a value but not x + 1? Why it doesn't work depends on your model of variables. The value model thinks of variables as locations that can hold values, and one assigns values to locations. So x is a location, but x + 1 is just a value. The object on the left-hand-side of the assignment must be what's called an
l-value, a
location. Objects that can appear on the right-hand-side,
i.e. "objects" or "values" are r-values. A
variable like x can play both roles. In "x = x + 1", the x on
the left stands for the location, the x on the right stands
for the value stored at that location. The other model is
the reference model. It views variables as being
references (pointers) to actual objects. Look in the book or
your notes for a nice picture to see the difference.
int x, y, z; cin >> x; (x > 0 ? y : z) = 10;... which tells us that the ?: operator yields (at least sometimes) l-values. C++ even lets you "return by reference", so that the results of function calls can be l-values.
int foo(int &m, int &n) { return (n > m ? n : m); }
int& bar(int &m, int &n) { return (n > m ? n : m); }
...
foo(x,y) = 5; // Error, foo(x,y) not an l-value
bar(x,y) = 5; // OK
Much less exotically, though, how about X[2*i+1] = 5;?
This should work, so clearly some expressions yield l-values.
int a,b,c; a := 5; b := 2; c := a; a++;Under the value model c is still 5. Under the referenced model, if ++ really modifies the object a refers to, c now refers to 6. This is a bit counter to how we think of such things usually. With strings you have the same problem:
String a, b, c; a := "hello"; b := "goat"; c := a; a[0] := 'j';Now c refers to "jello". To avoid this in these fundamental types, systems with the reference model may make these types "immutable", i.e. unchangeable. This, ++ wouldn't modify the int a points to in the first example, it would create a new int and set a to point to it. The operation in the second example would be illegal. Functions for doing this kind of operation would actually return new strings. Since Java has the value model for int's, this doesn't come into play, but strings in Java follow the reference model, and they are indeed "immutable". Check it for yourself.
BankAcct a = new BankAccount(); c = a; a.setBal(100);c's bank account is 100, because c and a refer to the same thing. Sometimes you really want copies, though, and Java has the
clonable interface to give a standard way of
getting duplicate objects. If BankAcct implements clonable,
we can do this:
BankAcct a = new BankAccount(); c = a.clone(); a.setBal(100);... and c's balance will still be zero ... or whatever the default is.