CS210
Answer 3 9/12/01
OUTPUT:
1 (Operators 3.1)
1 (Operators 3.2)
2 (Operators 3.3)
0
3 (Operators 3.4)
0
? (Operators 3.5)
Derivation
Operators 3.1
initially x=2, y=1, z=0 |
|
x = x ∓∓ y || z |
|
x = (x∓∓y) || z |
Bind operators to operators according to precedence.
|
x = ((x∓∓y)||z) |
|
(x=((x∓∓y)||z)) |
|
(x=((TRUE∓∓TRUE)||z)) |
Logical operators are evaluated from left to right.
An operand to a logical operator is FALSE if it is
zero and TRUE if it is anything else.
|
(x=(TRUE||z)) |
The logical AND, &&, yields TRUE only when
both its operands are TRUE, otherwise FALSE.
|
(x=(TRUE||whatever)) |
Once one argument to the OR, ||, is known to be TRUE
we know the result of the || will be TRUE regardless
of the other operand. Hence there is no need to
evaluate the expression further.
|
(x=TRUE) |
|
(x=1) |
|
1 |
|
More about define.
The define
statement that begins this program
is a little fancier than that in the previous program. Here,
PRINT is the name of a macro with arguments, not just
a simple string. The preprocessor performs two levels of
substitution on macros with arguments: first the actual arguments
are substituted for the formal arguments in the
macro body, and then the resulting macro body is substituted for the
macro call.
For example, in this program PRINT has one formal argument, int.
PRINT(x) is a call of PRINT with the actual argument x. Thus, each
occurrence of int in the macro body is first replaced by x, and
then the resulting string, printf("%d\n",x)
, is substituted
for the call, PRINT(x). Notice that the formal parameter int
did not match the middle letters in printf. This is because the formal
arguments of a macro are identifiers; int only matches the indentifier
int
.
Operators 3.2
Initially x=1, y=1, z=0 |
|
x || ! y && z |
|
x || (!y) && z |
Binding operands to operators
|
x || ((!y)&&z) |
|
(x||((!y)&&z)) |
|
(TRUE||((!y)&&z)) |
Evaluating from left to right
|
(TRUE||whatever) |
|
TRUE , or 1 |
|
Operators 3.3
Initially x=1, y=1 |
|
z = x ++ - 1 |
|
z = (x++) - 1 |
Following precedence.
|
z = ((x++)-1) |
Following precedence.
|
(z=((x++)-1)) |
|
(z=(1-1)), and x=2 |
The ++ to the right of its operand is a post increment.
This means that x is incremented after its value is used
in the expression.
|
(z=0) |
|
0 |
|
Operators 3.4
Initially x=2, y=1, z=0 |
|
z += - x ++ + ++ y |
|
z += - (x++) + (++y) |
Unary operators associate from right to left, thus
++ binds before unary -. (Actually, the expression
would not be legal if it were arranged so that the
- bound first since ++ and -- expet a reference to
a variable (an lvalue) as their operand. x is
an lvalue, but -x is not.)
|
z += (-(x++)) + (++y) |
|
z += ((-(x++))+(++y)) |
|
(z+=((-(x++))+(++y))) |
|
(z+=((-2)+2)), and x=3, y=2 |
Evaluating from inside out.
|
(z+=0) |
|
(z=0+0) |
|
(z=0) |
|
0 |
|
Operators 3.5
Initially x=3, z=0 |
|
z = x / ++ x |
|
z = x /(++x) |
|
z =(x/(++x)) |
|
(z=(x/(++x))) |
|
|
You may be tempted at this point to begin evaluating this expression
as before, from the inside out. First the value of x would be retrieved
and incremented to be divided into the value of x. One question that
might be asked is what value is retrieved from x for the numerator,
3 or 4? That is, is the value for the numberator retrieved before or
after the increment is stored? The C language does not specify when
such a side effect* actually occurs; that is left to the compiler
writer. The message is to avoid writing expressions that depend upon
knowing when a side effect will occur.
|
A side effect is any change to the state of a program that occurs as a
byproduct of executing a statement. By far the most common side effects
in C relate to storing intermediate values in variables, such as with
the increment operator as above or with an embedded assignment operator.