## Section 2.5

Details of Expressions

THIS SECTION TAKES A CLOSER LOOK at expressions. Recall that an expression is a piece of program code that represents or computes a value. An expression can be a literal, a variable, a function call, or several of these things combined with operators such as

+and>. The value of an expression can be assigned to a variable, used as the output value in an output routine, or combined with other values into a more complicated expression. (The value can even, in some cases, be ignored, if that's what you want to do; this is more common than you might think.) Expressions are an essential part of programming. So far, these notes have dealt only informally with expressions. This section tells you the more-or-less complete story.The basic building blocks of expressions are literals (such as

674,3.14,true, and'X'), variables, and function calls. Recall that a function is a subroutine that returns a value. You've already seen some examples of functions: the input routines from theTextIOclass and the mathematical functions from theMathclass.Literals, variables, and function calls are simple expressions. More complex expressions can be built up by using operators to combine simpler expressions. Operators include

+for adding two numbers,>for comparing two values, and so on. When several operators appear in an expression, there is a question of precedence, which determines how the operators are grouped for evaluation. For example, in the expression "A + B * C",B*Cis computed first and then the result is added toA. We say that multiplication (*) has higher precedence than addition (+). If the default precedence is not what you want, you can use parentheses to explicitly specify the grouping you want. For example, you could use "(A + B) * C" if you want to addAtoBfirst and then multiply the result byC.The rest of this section gives details of operators in Java. The number of operators in Java is quite large, and I will not cover them all here. Most of the important ones are here; a few will be covered in later chapters as they become relevant.

## Arithmetic Operators

Arithmetic operators include addition, subtraction, multiplication, and division. They are indicated by

+,-,*, and/. These operations can be used on values of any numeric type:byte,short,int,long,float, ordouble. When the computer actually calculates one of these operations, the two values that it combines must be of the same type. If your program tells the computer to combine two values of different types, the computer will convert one of the values from one type to another. For example, to compute 37.4 + 10, the computer will convert the integer 10 to a real number 10.0 and will then compute 37.4 + 10.0. (The computer's internal representations for 10 and 10.0 are very different, even though people think of them as representing the same number.) Ordinarily, you don't have to worry about type conversion, because the computer does it automatically.When two numerical values are combined (after doing type conversion on one of them, if necessary), the answer will be of the same type. If you multiply two

ints, you get anint; if you multiply twodoubles, you get adouble. This is what you would expect, but you have to be very careful when you use the division operator/. When you divide two integers, the answer will always be an integer; if the quotient has a fractional part, it is discarded. For example, the value of7/2is3, not3.5. IfNis an integer variable, thenN/100is an integer, and1/Nis equal to zero for anyNgreater than one! This fact is a common source of programming errors. You can force the computer to compute a real number as the answer by making one of the operands real: For example, when the computer evaluates1.0/N, it first convertsNto a real number in order to match the type of1.0, so you get a real number as the answer.Java also has an operator for computing the remainder when one integer is divided by another. This operator is indicated by

%. IfAandBare integers, thenA % Brepresents the remainder whenAis divided byB. For example,7 % 2is1, while34577 % 100is77, and50 % 8is2. A common use of%is to test whether a given integer is even or odd.Nis even ifN % 2is zero, and it is odd ifN % 2is1. More generally, you can check whether an integerNis evenly divisible by an integerMby checking whetherN % Mis zero.Finally, you might need the unary minus operator, which takes the negative of a number. For example,

-Xhas the same value as(-1)*X. For completeness, Java also has a unary plus operator, as in+X, even though it doesn't really do anything.

## Increment and Decrement

You'll find that adding

1to a variable is an extremely common operation in programming. Subtracting1from a variable is also pretty common. You might perform the operation of adding1to a variable with assignment statements such as:counter = counter + 1; goalsScored = goalsScored + 1;The effect of the assignment statement

x = x + 1is to take the old value of the variablex, compute the result of adding1to that value, and store the answer as the new value ofx. The same operation can be accomplished by writingx++(or, if you prefer,++x). This actually changes the value ofx, so that it has the same effect as writing "x = x + 1". The two statements above could be writtencounter++; goalsScored++;Similarly, you could write

x--(or--x) to subtract1fromx. That is,x--performs the same computation asx = x - 1. Adding1to a variable is called incrementing that variable, and subtracting1is called decrementing. The operators++and--are called the increment operator and the decrement operator, respectively. These operators can be used on variables belonging to any of the numerical types and also on variables of typechar.Usually, the operators

++or--, are used in statements like "x++;" or "x--;". These statements are commands to change the value ofx. However, it is also legal to usex++,++x,x--, or--xas expressions, or as parts of larger expressions. That is, you can write things like:y = x++; y = ++x; TextIO.putln(--x); z = (++x) * (y--);The statement "

y = x++;" has the effects of adding1to the value ofxand, in addition, assigning some value toy. The value assigned toyis the value of the expressionx++, which is defined to be theoldvalue ofx, before the1is added. Thus, if the value ofxis6, the statement "y = x++;" will change the value ofxto7and will change the value ofyto6. On the other hand, the value of++xis defined to be thenewvalue ofx, after the1is added. So ifxis6, then the statement "y = ++x;" changes the values of bothxandyto7. The decrement operator,--, works in a similar way.This can be confusing. My advice is: Don't be confused. Use

++and--only in stand-alone statements, not in expressions. I will follow this advice in all the examples in these notes.

## Relational Operators

Java has boolean variables and boolean-valued expressions that can be used to express conditions that can be either

trueorfalse. One way to form a boolean-valued expression is to compare two values using a relational operator. Relational operators are used to test whether two values are equal, whether one value is greater than another, and so forth. The relation operators in Java are:==,!=,<,>,<=, and>=. The meanings of these operators are:A == B Is A "equal to" B? A != B Is A "not equal to" B? A < B Is A "less than" B? A > B Is A "greater than" B? A <= B Is A "less than or equal to" B? A >= B Is A "greater than or equal to" B?These operators can be used to compare values of any of the numeric types. They can also be used to compare values of type

char. For characters,<and>are defined according the numeric Unicode values of the characters. (This might not always be what you want. It is not the same as alphabetical order because all the upper case letters come before all the lower case letters.)When using boolean expressions, you should remember that as far as the computer is concerned, there is nothing special about boolean values. In the next chapter, you will see how to use them in loop and branch statements. But you can also assign boolean-valued expressions to boolean variables, just as you can assign numeric values to numeric variables.

By the way, the operators == and != can be used to compare boolean values. This is occasionally useful. For example, can you figure out what this does:

boolean sameSign; sameSign = ((x > 0) == (y > 0));One thing that you

cannotdo with the relational operators<,>,<=, and<=is to use them to compare values of typeString. You can legally use==and!=to compareStrings, but because of peculiarities in the way objects behave, they might not give the results you want. (The==operator checks whether two objects are stored in the same memory location, rather than whether they contain the same value. Occasionally, for some objects, you do want to make such a check -- but rarely for strings. I'll get back to this in a later chapter.) Instead, you should use the subroutinesequals(),equalsIgnoreCase(), andcompareTo(), which were described in Section 3, to compare twoStrings.

## Boolean Operators

In English, complicated conditions can be formed using the words "and", "or", and "not." For example, "If there is a test

andyou didnotstudy for it...". "And", "or", and "not" are boolean operators, and they exist in Java as well as in English.In Java, the boolean operator "and" is represented by

&&. The&&operator is used to combine two boolean values. The result is also a boolean value. The result istrueifbothof the combined values aretrue, and the result isfalseifeitherof the combined values isfalse. For example, "(x == 0) && (y == 0)" istrueif and only if bothxis equal to 0 andyis equal to 0.The boolean operator "or" is represented by

||. (That's supposed to be two of the vertical line characters,|.) "A || B" istrueif eitherAistrueorBistrue, or if both are true. "A || B" isfalseonly if bothAandBare false.The operators

&&and||are said to be short-circuited versions of the boolean operators. This means that the second operand of&&or||is not necessarily evaluated. Consider the test

(x != 0) && (y/x > 1)Suppose that the value of

xis in fact zero. In that case, the divisionx/yis illegal, since division by zero is not allowed. However, the computer will never perform the division, since when the computer evaluates(x != 0), it finds that the result isfalse, and so it knows that ((x != 0) &&anything) has to be false. Therefore, it doesn't bother to evaluate the second operand,(x/y > 1). The evaluation has been short-circuited and the division by zero is avoided. Without the short-circuiting, there would have been a division-by-zero error. (This may seem like a technicality, and it is. But at times, it will make your programming life a little easier. To be even more technical: There are actually non-short-circuited versions of&&and||, which are written as&and|. Don't use them unless you have a particular reason to do so.)The boolean operator "not" is a unary operator. In Java, it is indicated by

!and is written in front of its single operand. For example, iftestis a boolean variable, then

test = ! test;will reverse the value of test, changing it from

truetofalse, or fromfalsetotrue.

## Conditional Operator

Any good programming language has some nifty little features that aren't really necessary but that let you feel cool when you use them. Java has the conditional operator. It's a ternary operator -- that is, it has three operands -- and it comes in two pieces, ? and :, that have to be used together. It takes the form

boolean-expression?expression-1:expression-2The computer tests the value of

boolean-expression. If the value istrue, it evaluatesexpression-1; otherwise, it evaluatesexpression-2. For example:

next = (N % 2 == 0) ? (N/2) : (3*N+1);will assign the value

N/2tonextifNis even (that is, ifN % 2 == 0istrue), and it will assign the value(3*N+1)tonextifNis odd.

## Assignment Operators

You are already familiar with the assignment statement, which uses the symbol "=" to assign the value of an expression to a variable. In fact, = is really an operator in the sense that an assignment can itself be used as an expression or as part of a more complex expression. The value of an assignment such as

A=Bis the same as the value that is assigned toA. So, if you want to assign the value ofBtoAand test at the same time whether that value is zero, you could say:

if ( (A=B) == 0 )Usually, I would say,

don't do things like that!In general, the type of the expression on the right-hand side of an assignment statement must be the same as the type of the variable on the left-hand side. However, in some cases, the computer will automatically convert the value computed by the expression to match the type of the variable. Consider the list of numeric types:

byte,short,int,long,float,double. A value of a type that occurs earlier in this list can be converted automatically to a value that occurs later. For example:int A; double X; short B; A = 17; X = A; // OK; A is converted to a double B = A; // illegal; no automatic conversion // from int to shortThe idea is that conversion should only be done automatically when it can be done without changing the semantics of the value. Any

intcan be converted to adoublewith the same numeric value. However, there areintvalues that lie outside the legal range ofshorts. There is simply no way to represent theint100000 as ashort, for example, since the largest value of typeshortis 32767.In some cases, you might want to force a conversion that wouldn't be done automatically. For this, you could use what is called a type cast. A type cast is indicated by putting a type name, in parentheses, in front of the value you want to convert. For example,

int A; short B; A = 17; B = (short)A; // OK; A is explicitly type cast // to a value of type shortYou can do type casts from any numeric type to any other numeric type. However, you should note that you might change the numeric value of a number by type-casting it. For example,

(short)100000is 34464. (The 34464 is obtained by taking the 4-byteint100000 and throwing away two of those bytes to obtain ashort-- you've lost the real information that was in those two bytes.)

As another example of type casts, consider the problem of getting a random integer between 1 and 6. The function

Math.random()gives a real number between 0.0 and 0.9999..., and so6*Math.random()is between 0.0 and 5.999.... The type-cast operator,(int), can be used to covert this to an integer:(int)(6*Math.random()). A real number is cast to an integer by discarding the fractional part. Thus,(int)(6*Math.random())is one of the integers 0, 1, 2, 3, 4, and 5. To get a number between 1 and 6, we can add 1: "(int)(6*Math.random()) + 1".You can also type-cast between the type

charand the numeric types. The numeric value of acharis its Unicode code number. For example,(char)97is'a', and(int)'+'is43.Java has several variations on the assignment operator, which exist to save typing. For example, "

A += B" is defined to be the same as "A = A + B". Every operator in Java that applies to two operands gives rise to a similar assignment operator. For example:x -= y; // same as: x = x - y; x *= y; // same as: x = x * y; x /= y; // same as: x = x / y; x %= y; // same as: x = x % y; (for integers x and y) q &&= p; // same as: q = q && p; (for booleans q and p)The combined assignment operator

+=even works with strings. You will recall from Section 3 that when the+operator is used with a string as the first operand, it represents concatenation. Sincestr += xis equivalent tostr = str + x, when+=is used with a string on the left-hand side, it appends the value on the right-hand side onto the string. For example, ifstrhas the value "tire", then the statementstr += 'd';changes the value ofstrto "tired".

## Precedence Rules

If you use several operators in one expression, and if you don't use parentheses to explicitly indicate the order of evaluation, then you have to worry about the precedence rules that determine the order of evaluation. (Advice: don't confuse yourself or the reader of your program; use parentheses liberally.)

Here is a listing of the operators discussed in this section, listed in order from highest precedence (evaluated first) to lowest precedence (evaluated last):

Unary operators: ++, --, !, unary - and +, type-cast Multiplication and division: *, /, % Addition and subtraction: +, - Relational operators: <, >, <=, >= Equality and inequality: ==, != Boolean and: && Boolean or: || Conditional operator: ?: Assignment operators: =, +=, -=, *=, /=, %=Operators on the same line have the same precedence. When they occur together, unary operators and assignment operators are evaluated right-to-left, and the remaining operators are evaluated left-to-right. For example,

A*B/Cmeans(A*B)/C, whileA=B=CmeansA=(B=C). (Can you see how the expressionA=B=Cmight be useful, given that the value ofB=Cas an expression is the same as the value that is assigned toB?)

End of Chapter 2

[ Next Chapter | Previous Section | Chapter Index | Main Index ]