Home Previous Next

CSC110AB::Lecture Note::Week 03
Assignments | Handouts | Resources | Email Thurman {Twitter::@compufoo Facebook::CSzero}
GDT::Bits:: Time  |  Weather  |  Populations  |  Special Dates

Overview Assignment(s): Code ArithOps.java | Divider.java | MaxMinValues.java | EscapeSequences.java
If.java {If2.java} | Age.java | Age1.java

Defining Variables

A variable is a location in the computer's memory where a value can be stored for use by a program.

Variables have the following characteristics:

Variables must be defined before or at the time they are first used. A variable is defined by giving it a type and a name.

Variable names must begin with either an underscore _, dollar sign $, or a letter. The rest of the variable name, if any, can be any combination of letters and numbers. Letters can be either uppercase or lowercase and they include dollar sign ($) and underscore (_). By convention, Java variables have meaningful names, often made up of several words combined. The first word is lowercase, but all following words have an initial uppercase letter.

There is no difference between defining and declaring a variable; therefore, the two terms can be used inter-changeably.

There are three categories of variables: class, instance and local. These categories are detailed later in the course.

Notes on style:

{TopOfPage} {Oracle.com::API Specification | Tutorial} {GDT::Java Resources} {Eclipse IDE} {Udacity} {udemy} {CodingGround (online IDE)


Primitive Data Types

The size of the Java primitive types are fixed across all JVMs. As a consequence, the language does not have (nor does it need) a sizeof() operator.

boolean 1-bit (true or false)
byte 8-bits
char 16-bits (unsigned -- unicode)
short 16-bits
int 32-bits
long 64-bits
float 32-bits (single-precision)
double 64-bits (double-precision)

The minimum and maximum values that can be stored in a variable is dependent on its type. These min/max values can be found from the "wrapper" classes that exist for each type.

All types are signed (except char, which is unsigned). Java does not have the signed and unsigned keywords.

Assigning a variable of a larger type to a variable of a smaller type requires the use of type cast.

   short s;
   int i;
   ...
   s = (short)i;   //the typecast is required; otherwise, syntax error

When you define long and short variables, the keyword int cannot be used.

   long int li;   //syntax error
   short int si;  //syntax error

The following items help make Java programs portable.

Some more differences between Java and C/C++.

{TopOfPage} {Oracle.com::API Specification | Tutorial} {GDT::Java Resources} {Eclipse IDE} {Udacity} {udemy} {CodingGround (online IDE)


Constants

An integral (whole number) value by default is treated as an int.

An integral value suffixed with an ell (either lowercase or uppercase) is treated as type long.

A floating-point (real number) value by default is type double.

A floating-point value suffixed with an eff (either lowercase or uppercase) is treated as type float.

A floating-point value suffixed with a dee (either lowercase or uppercase) is treated as type double.

An integral value prefixed with a zero indicates octal representation being used (e.g 034 is octal for the decimal value 28). An integral with 0x or 0X prefix implies hexadecimal notation used.

Floating-point values can be expressed using exponential notation. For example.

   3.14e0    3.14 times 100
   1e+3      1.0 times 103
   2.99e-5   2.99 times 10-5 

A character enclosed in single quotes is type char.

A sequence of zero more more characters enclosed in double quotes is a string literal and results in an object of type String.

   i = 200;     //200 is an  int
   l = 200L;    //200 is type long
   f = 200.0f;  //200 is a float
   d = 200.0;   //200 is a double
   c = 'A';     //'A' is type char
   s = "200";   //2000 is a String

The type of a constant is important when they are used in mixed-mode expressions (EXPRs). In a nutshell, Java does the following.

{TopOfPage} {Oracle.com::API Specification | Tutorial} {GDT::Java Resources} {Eclipse IDE} {Udacity} {udemy} {CodingGround (online IDE)


Define Terms: Expression, Operand, Operator

An expression is a combination of operands and operators that yields (expresses) a single value. Let EXPR be short for expression.

An operand is a constant or variable that is manipulated in the EXPR. Let OP stand for operand. Each OP of an EXPR is also an EXPR, since it represents a single value.

An operator specifies how the operand or operands of an EXPR are manipulated. Let OPER represent operator.

When an EXPR is evaluated, the resulting value depends on the relative precedence of OPERs in the EXPR and on "sequence points" and "side effects," if any. The precedence of OPERs determines how OPs are grouped for evaluation (i.e. how operands bind with operators). Side effects are changes caused by the evaluation of an EXPR.

OPs include constants, identifiers, function calls and so on.

The result every EXPR has a type. For example, an EXPR may evaluate to an int.

OPERs take either one OP (unary), two OPs (binary) or three OPs (ternary).

{TopOfPage} {Oracle.com::API Specification | Tutorial} {GDT::Java Resources} {Eclipse IDE} {Udacity} {udemy} {CodingGround (online IDE)


Operators

An operator specifies how the operand or operands of an expression are manipulated.

Java has many of the same operators as does C and C++ with similar precedence and associvity.

Operators are usually represented using symbols (+ - * / %).

Operators and operands form the atomic unit of an expression.

Operators take either one operand (unary), two operands (binary) or three operands (ternary).

When multiple operators are used in an expression, then precedence and associativity is used to bind (or group) operands with operators.

Java evaluates expressions unconditionally left-to-right. [This is not true in C or C++.]

Arithmetic Operators

All of the arithmetic operators are binary operators (i.e. they take two operands).

   +   addition
   -   subtraction
   /   division
   *   multiply
   %   modulus (remainder)

The arithmetic operators work with integral and floating-point values except for the modulus (%) operator which works only on integral operands.

If both operands are integral data types, then the result is integral and an integer division occurs (i.e. any reminder is dropped (truncated) from the result). Examples.

    3 / 2  equals  1
    7 / 3  equals  2
   11 / 3  equals  3

An integer division by 0 causes an Exception. Example: The expression 2002 / 0 causes a program to abnormally terminate. Floating-point division by 0 results in the value infinity without an Exception.

If one operand is integral and other is a floating-point, then a floating-point division is executed. The result is the type of the floating-point operand.

If both operands are floating-point, then the type of the result is the type of the "largest" operand. Example.

   float f = 1.9;
   double d = 1.9;

   f / d   results in a  double
   d / f   results in a  double

The + addition operator can be applied to String objects. If only one operand is a String, then the other is converted to a String. The addition operator when applied to String objects performs a concatentation of the value of the left-hand operand with the value of the right-hand operand. The concatenation results in the creation of a third (new) String object that stores the result of the concatentation. [This is Java's only overloaded operator. Java does not support operator overloading.]

Relational Operators

Relational operators are binary operators that are used to compare the value of two expressions.

   ==  equality
   !=  not equal
   >   greater than
   >=  greater than or equal to
   <   less than
   <=  less than or equal to

Relational operators evaluate to boolean values (i.e. true or false).

   int a = 10;
   int b = 15;

   a == b        evaluates to false
   a != b        evaluates to true
   a > b         evaluates to false
   a < b         evaluates to true

If the operands are not the same type, then the value of the type smallest type is promoted to the larger type before the comparison is executed.

Logical Operators

The binary logical operators are use to test if two expressions, when combined, are either true or false. The unary logical operator is used to reverse the outcome of an expression that evaluates to a boolean values.

   &&  and
   ||  or
   !   not (unary)

The operands of logical operators must evaluate to type boolean values.

Java uses short-circuit evaluation (i.e. an EXPR is evaluated only until the truth or falsehood of the entire EXPR can be unambigously determined).

Bit-wise Operators
   ^  exclusive or
   &  and
   |  or
   >> right shift (sign extension)
   << left shift
   ~  one's complement

   Java also has a  >>>  right shift operator (0 extension).
Miscellaneous Operators
   ++  increment (both prefix and postfix)
   --  decrement (both prefix and postfix)
   ?:  conditional
   +   unary plus
   -   unary minus
   ()  typecast
   compound assignment  (e.g. +=, -=, /=, %=, *=, &=, |=, ^=, 
                              <<=, >>=, >>>=)
Java does not the following operators:
   sizeof()
   sequence (i.e. comma)

   Note:  the sequence operator is supported when used with the
          for()  repetition control statement.
The following Java operators will be covered later:
   new
   instanceof
   ()  /* method call */
   []  /* array */
   .   /* dot */
Operator precedence and associativity:

[]   .    ()(method call) left-to-right
!   ~   ++   --   +(unary)   -(unary)  ()(cast)   new right-to-left
*   /   % left-to-right
+   - left-to-right
<<   >>   >>> left-to-right
<   <=   >   >=   instanceof left-to-right
==   != left-to-right
& left-to-right
^ left-to-right
| left-to-right
&& left-to-right
|| left-to-right
?: left-to-right
= compound assignment operators right-to-left

In Java, the order in which EXPRs are evaluated is always a strict left-to-right. Recall, in C and C++, the order of EXPR evaluation is implementation-dependent. Having the order of EXPR evaluation be well-defined helps make Java portable. Here is an example:

   Given the following EXPR:  f() + g()

   In Java, you are guaranteed that  f()  will be called before  g().
   In C, on some systems  f()  may be called first, but on others it
   might be called after  g()  has been invoked.

{TopOfPage} {Oracle.com::API Specification | Tutorial} {GDT::Java Resources} {Eclipse IDE} {Udacity} {udemy} {CodingGround (online IDE)


The if Statement and else Clause

The if is a selection control statement. It is a keyword of the language. It has the following syntax.

   if (EXPR) 
      statement';
   statement'';

   If  EXPR  evaluates to  true  then  statement'  is executed 
   followed by  statement''; otherwise,  statement'  is skipped 
   and the flow control of the program jumps to  statement''.

   if (netWorth > 1000000)
      System.out.println("you are rich (at least money wise)"); 
   netWorth = netWorth * 2;   //let us double your net worth

The EXPR of an if statement must evaluate to a boolean value.

   int i;

   //! if (i = 7)   // not legal; EXPR evaluates to an  int
      System.out.println("lucky number");

Typically, there is no semicolon after the if. If there is, then the body of the if is simply a NULL statement. In many cases, this is a defect with your program (i.e. it is done by accident, not design).

   if (netWorth < 0)
      ;  //do nothing...

If more than one statement needs to be executed when an if EXPR is true, then a compound statement . should be used. A compound statement is a collection of zero or more statements enclosed in braces {}.

Compound statements are terminated by the closing brace } -- not a semicolon.

   if (EXPR) {
      statement';
      statement'';
   }                //note that there is no semicolon
   statement''';

   If EXPR evaluates to true, then both statement' and statement''
   are executed followed by statement'''; otherwise, statement' and
   statement'' are skipped and the flow control of the program jumps
   to statement'''.

   isSuperStar = false;
   bonus = 0;

   ...

   if (battingAvg > 300) {
      isSuperStar = true;
      bonus = 10000;
   }
   number = 55;

Every if statement can have a corresponding else clause which is executed whenever the if is false.

   if (EXPR)
      statement';
   else
      statement'';
   statement''';

   If EXPR is  true, then statement' is executed, the else clause is
   skipped, and the flow control of the program jumps to statement''';
   otherwise, statement' is skipped, statement'' is executed and
   the flow control of the program jumps to statement'''.

   if (netWorth > 1000000)
      System.out.println("you are rich (with respect to money)");
   else
      System.out.println("you are rich in other ways");

An else clause cannot be used without a corresponding if statement. Example.

   int i = 10;

   ...

   else   //not allowed -- there is no if statement
      System.out.println("this is not legal");

The body of an if construct can be any type of statement. Examples.

   if (EXPR) EXPR;      //the body is an expression statement
   if (EXPR) System.exit(0);  //body is call to System.exit()
   if (EXPR) ;          //body is a null statement
   if (EXPR) { }        //body is an empty compound statement
   if (EXPR) if (EXPR)  //body is another if statement

An if statement containing another if is referred to as a nested if. There is no limit to the amount of nesting that can occur. Examples.

   if (EXPR)
      if (EXPR')
         statement';
   statement'';

   If EXPR is true, then EXPR' is evaluated; otherwise,
   flow control jumps to statement''.  If EXPR' is evaluated
   and it evaluates to true, then statement' is executed;
   otherwise, flow control jumps to statement''.

   if (age >= 100)
      if (gender == 'M')
         System.out.println("old man look at my life");

   if (age >= 100)
      if (gender == 'M')
         if (iq > 120)
            System.out.println("smart old man look at my life");
   System.out.println();

When using if statements, it is a good programming practice to use indentation to aid readability. The body of an if statement should be indented three or four spaces.

In all cases, each if can have a corresponding else clause.

   if (EXPR)
      if (EXPR')
         statement';
      else
         statement'';
   statement''';

   The top-most  if  does not have an  else  clause, whereas the
   inner-most  if  does.  If EXPR evaluates to  false, then
   flow control jumps to statement'''; otherwise, EXPR' is
   evaluated.  If it evaluates to true, then statement' is
   executed; otherwise, statement' is skipped and statement'' is
   evaluated.  Regardless of which statement is executed,
   flow control jumps to statement'''.

Caution is required to make sure that else clauses match up to the correct if construct. The following code snippet has a defect.

   if (age > 100)
      if (gender == 'M')
         System.out.println("you are an old man");
      else
         System.out.println("you are a young person");

   If age is greater than 100, then  if (gender == 'M')  will
   be executed.  If the gender is 'M', then the correct statement
   will print, but if the gender is not 'M', then the 
   "you are a young person" message will print.

   To correct this problem, a compound statement is needed to
   "tie" the  else  clause with the outer-most  if  statement.

   if (age > 100) {
      if (gender == 'M')
         System.out.println("you are an old man");
   } else
      System.out.println("you are a young person");
   
   Now if age > 100, then the body of the  if  is executed;
   otherwise, flow control jumps to the  else  clause.

The placement of {}'s when using compound statements is a style issue that is usually resolved by the formulation of coding standards. Primary rule: be consistent.

{TopOfPage} {Oracle.com::API Specification | Tutorial} {GDT::Java Resources} {Eclipse IDE} {Udacity} {udemy} {CodingGround (online IDE)


Truth Tables and De Morgan's Laws

The following is a "truth table" for the logical operators AND, OR and NOT.

  -------------------------------------------------------------------
  Logical operators:         AND   OR                            NOT 
  -------------------------------------------------------------------
  expr1       expr2          &&    ||                expr       !expr
  -------------------------------------------------------------------
  zero        zero           0     0                 zero         1
  nonzero     zero           0     1                 nonzero      0
  zero        nonzero        0     1 
  nonzero     nonzero        1     1 
  -------------------------------------------------------------------

In most popular programming environments, evaluation of a logical expression stops as soon as the truth is known. This is called short circuit evaluation. For example, given the following logical expression.

   expr1 || expr2

The C and Java languages guarantee that expr1 is evaluated first. If expr1 evaluates to TRUE, then the entire logical expression is TRUE and expr2 is not evaluated. (TRUE logically OR'd with anything is TRUE.)

The || and && logical operators are sequence points of the language. For example, given the following logical expression.

   f() && g()

Function f() is evaluated before function g(); however, the same is not necessarily true given the following arithmetic expression.

   f() + g()

Some implementations will evaluate the function f() first, while others will evaluate function g() first.

Logical operators (and the fact that they are sequence points and are subject to short circuit evaluation) are a critical tool when it comes to transaction processing.

   step1 && step2 && step3 && commit

   don't do step2 if step1 fails
   don't do step3 if step2 fails
   commit the transaction if step3 is successful
De Morgan's Laws

De Morgan's Laws are used to simplify logical expressions.

   !(expr1 || expr2)    is equivalent to     !expr1 && !expr2
   !(expr1 && expr2)    is equivalent to     !expr1 || !expr2

   examples... 

      useCYMK = !(red || green || blue)
      ...apply De Morgan's Law...
      useCYMK = !red && !blue && !green

      isdefective = !(clear && zeroerrors && posted)
      ...apply De Morgan's Law...
      isdefective = !clear || !zeroerrors || !posted

{TopOfPage} {Oracle.com::API Specification | Tutorial} {GDT::Java Resources} {Eclipse IDE} {Udacity} {udemy} {CodingGround (online IDE)


Home Previous Next