Variables and expressions

Contents

 

 

introduction

 

Data types

 

Strings

 

Arithmetic operators

 

Mathematical functions

 

Multiple assignments

 

Practice exercises

introduction

We want to launch our first program

/* Multi-line comment: 
The "Hello World" example. 
*/
public class HelloWorld
{   
    public static void main (String args[])
    {   
        System.out.println("Hello World"); // Comment
    }
}

expand. First, the individual lines will be explained.

public class HelloWorld
{...
}

Introduces the definition of a class . A Java program consists of a number of classes. The class containing `main` must be public . The Java file must have the same name as the public class declared within it, in this case, ` HelloWorld.java` .

public static void main (String args[])
{...
}

Definition of a subroutine named `main` . This subroutine is automatically started by the Java interpreter because of its name and the specific arguments it has. It must also be public and static . The `main` subroutine in this example does not return a result (` void` ) and does not use its parameters ( `args[]` strings ).

Subroutines will be explained in detail later. For now, we'll stick with main .

System.out.println("Hello World");

Calling the subroutine `println` in the `System.out` object . This subroutine can print the string "Hello World", passed as a parameter , to the command line.

The line is an example of a statement. Every statement ends with a semicolon ( ;) .

... // Comment

A line comment. Ignored by the compiler.

/* ... */

Multi-line comment. The compiler ignores everything between /* and */

For now, we can read the lines

public class Test
{   
    public static void main (String args[])
    {   
        ...
    }
}

Consider this as a framework. The three dots ... are replaced by the relevant program parts. In the example above, text was simply output here.

We now want to modify this program. To do this, we copy the file HelloWorld.java to Test.java .

copy HelloWorld.java Test.java

(or cp for Unix) and modify the contents of Test.java . To do this, we open this file in our favorite editor and enter the following text.

public class Test
{   
    public static void main (String args[])
    {   
        int n;
        n = 3*4;
        System.out.println(n);
    }
}

This calculates the product of the numbers 3 and 4, which is 12, stores the result in a variable, and outputs the value of the variable. Note that the class name has also changed and now matches the name of the file Test.java . To test the example, type the following in DOS:

javac Test.java
Java test

The output should

12

This example includes the following new language elements.

int n;

Declaration of a variable named n . The variable is stored on the stack and is only available locally within the subroutine `main` . It is no longer available after the subroutine finishes. Since our program also finishes at that point, this is irrelevant.

The variable is of type int (integer, i.e., whole number). It can take values ​​from -2,147,483,648 to 2,147,483,647 .

The general form of variable declaration is:

data type variable name;

In this case, the data type is int and the variable name is n .

n = 3*4;

This is an assignment. The value resulting from the calculation of the expression 3*4 is assigned to n . This expression is of type int , since it is an operation on two int constants.

Naturally, the type of an expression is determined by the type of its operands. In this case, both constants, 3 and 4, are of type int , and therefore so is the result 3*4. This general rule always holds true.

Rule: The type of operands determines the type of result.

Data types

The following elementary data types exist . The table lists the Java name of each data type, examples of constants of that data type, and the possible values ​​that variables of that data type can take.

Data type

constants

Value set

short

 

-2^15 ... 2^15-1

int

3, -3, 0, 0x3FF (hexadecimal), 0377 (octal)

-2^31 ... 2^31-1

long

3l, -30000000000l

-2^63 ... 2^63-1

float

 

approximately a 6-digit mantissa and a two-digit exponent.

double

3.1415, 1e20, 1e-10, -1E10

Approximately 16-digit decimal mantissa and 3-digit exponent.

byte

 

0 ... 2^8-1=255. Normal storage unit.

char

'A', 'a', ' ', '\t', '\n', '\xFE', '\u0121'

Simple single characters, special characters with \ , Unicode characters.

boolean

true, false

True or false.

The type of constants, such as 3 and 4 , is determined by their notation. For numbers without a decimal point, it is ` int` ; for numbers with a decimal point , it is `double` , e.g., 3.4 , -1.55 , or 1.5e10 . Long constants have an appended `l` .

An expression remains of type int as long as it does not contain any double values.

Attention! The expression 1/3 results in 0 , since it is calculated as an integer.

If you want to obtain 0.333... as the result, you can write 1.0/3 . In this case, the first operative part is a double, and therefore so is the result. Of course, 1.0/3.0 also works , or as we will see below, (double)1/3 .

Now we can calculate a more complicated expression.

public class Test
{   
    public static void main (String args[])
    {   
        double x = 1.5, y;
        y = 1+x+x*x/2+x*x*x/6+x*x*x*x/24;
        System.out.println("y = " + y);
    }
}

It is therefore possible to declare multiple variables on a single line and assign values ​​to them simultaneously. If a variable is not assigned a value, it cannot be used. The compiler will flag this as an error.

Furthermore, the variable x is used here as an operand in expressions. So far, we have only used constants in expressions.

It's also interesting to see how 1 + x + ... is calculated. 1 is a constant of type int , but x is a variable of type double . Here, the result is determined by the higher-order type of the operands, in this case, double . Naturally, the sum of multiple addends is calculated from left to right. Java follows the order of operations (multiplication and division before addition and subtraction ) and also takes parentheses into account . The exponentiation must be calculated using Math.pow(x,y) .

Note the addition of a string and a double variable in the output. Here, the double value is first converted to a string, and then the two strings are concatenated. We will explain this in more detail below .

The program produces the following output

y = 4.3984375

What happens when an expression of a lower type is stored in a variable of a higher type? In this case, the conversion is automatic. Conversely, the reverse will result in a compiler error message.

Rule: Automatic conversions are only allowed if the target can accept the value in any case .

int n = 3;
long l = n; // automatic conversion

Conversely, a type cast is necessary.

long l = 20000;
int n = (int)l; // type cast from long to int

This allows data types to be converted into one another as desired. The programmer is responsible for any errors.

public class Test
{   
    public static void main (String args[])
    {   
        long c = 1000000000000l; // the l is necessary! 
        System.out.println(c); // prints the correct value 
        System.out.println((int)c); // prints -727379968
    }
}

No runtime error is generated in the event of an overflow . However, division by zero or similar errors generate an arithmetic exception . We will postpone discussing exceptions and their handling for now.

ArithmeticOperators

For the arithmetic data types (all except boolean ), the usual operators + , - , * , /, and % (modulo) are defined. The result is always of the same type. Therefore

int n=3;
System.out.println(n/4); // prints 0

The order of operations is strictly defined, but corresponds to the usual convention ("multiplication and division before addition and subtraction", and consideration of parentheses).

System.out.println((3.0+7.0)/(4.0*5.0+80.0)); // prints 0.1 
System.out.println((3.0+7)/(4*5+8)); // prints 0.1 
System.out.println((double)(3+7)/(4*5+8)); // also prints 0.1 
System.out.println((3+7)/(4*5+80)); // but prints 0 !!!

Comparisons of numbers yield true or false of type boolean . The comparisons are < , <= (less than or equal to), > , >= , == (equal to), != (not equal to). Example:

double x=3;
System.out.println(1/x >= 0.3); // prints true

Boolean expressions are combined with && (and) and || (or). They are reversed with ! (not).

We will need such Boolean expressions later, especially for controlling the flow of programs, for example for conditional jumps and instructions.

Furthermore, there are several special bitwise operators for numbers, namely | (or), & (and) , ^ (either/or), and ~ (bitwise complement, NOT). In addition, there are operators that shift bitwise right and left, namely >> (shift right, where negative numbers remain negative), << , and >>> (shift right with padding of zeros). For example, n<<2 corresponds to multiplying n by 4. These operators are only relevant when dealing with numbers in the binary system.

There are also the operators ++ and -- , which can be used before and after the integer. These operators increment or decrement an integer value by 1. ++n does this before the use of n, and n++ after. These operators can also be used as statements. Example:

int i=1;
i++;
System.out.println(i); // prints 2.

It is debatable whether it wouldn't be better to write i=i+1 , which is clearer and therefore less error-prone. However, i++ was translated by earlier compilers into code that executed faster, so this notation has become established.

Furthermore, combinations of operators and = exist. Example

int i = 1;
i += 2;
System.out.println(i); // prints 3.

The question here is whether i=i+2 is not clearer, and yet executed just as quickly.

Strings

Strings are not actually elementary data types but behave like classes. However, since they are crucial for non-mathematical examples, we will discuss them here. We will examine strings in more detail later .

We have already used string constants . Such constants are enclosed in quotation marks . Example

String s="This is a test string.";

The most important arithmetic operation with strings is addition (+). This addition appends two strings to each other. You can also add elementary data types to strings. These values ​​are then first converted into a string representation. This allows you to annotate numerical outputs.

double pi = Math.PI;
System.out.println("Pi squared is " + (pi*pi));

First, pi*pi is calculated, then this value is converted into a string, and finally...

Pi squared is 9.869604401089358

Java outputs all relevant digits , thus revealing computational inaccuracies that are rounded down when outputting with other languages, even though they exist internally. If you want to format to a specific number of digits, you must use Java's formatting routines in `String.format` , which we will discuss later.

Here is another example that outputs the letter which has the code 67.

public class Test
{   
    public static void main (String args[])
    {   
        int n = 67;
        System.out.println(
            "The letter number " + n + " is " +(char)n);
    }
}

The value 'n' is treated once as an int value and once as a char value, and accordingly converted into a string differently. The result is...

The letter number 67 is C

Hexadecimal numbers can be entered as 0xff , which stands for 255.

Mathematical functions

The mathematical functions are defined statically in the Math class . Therefore, they are called as in the following example:

System.out.println(Math.exp(1)); // Prints the value of e

Before we explain classes in more detail, this should simply be understood as a way of writing down mathematical functions.

The usual functions abs , sin , cos , exp , log , asin , acos , and sqrt are defined. In addition, there are two-variable functions such as pow (calculates x^y ), atan2 (calculates the angle between x and y), max , and min . All these functions must be called with the prefix Math .

In addition, there are the functions `floor` and `ceil` , which round down and up, respectively, to the nearest integer. The `round` function rounds to the nearest integer but returns a `long` value.

Finally, the function `random` generates a random number between 0 and 1.

Multiple assignments

It is also possible to perform multiple assignments simultaneously.

int n,m;
n = m = 3;

This is because an assignment like m=3 actually has a result (namely 3 ), which is then used by n= . Normally, this result is discarded. It's possible to use the result in other cases, but this usually leads to poorly readable code.

For example, it is not immediately clear how

double a;
double y = Math.sin(a = Math.PI/4));

It actually works. In contrast, it reads...

double a=Math.PI/4;
double y=Math.sin(a);

significantly lighter.

 Important details

Exercisetasks

  1. Write a program that outputs the circumference of a circle with radius 2.0 . Also output the radius of the circle. The output should look like this:
    The circumference of a circle with radius 2.0 is 12.566370614359172
  2. What is the result of the expression 1000000*1000000 ? Why does this result occur?
  3. What is the result of 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 - 1.0 ? Why isn't it exactly 0.0 ?
  4. Calculate (1+1/n)^n for increasing values ​​of n . How large must n be chosen so that this expression is less than 0.01 away from e ?
  5. Output the character numbered 124 .
  6. Give an expression that is true if and only if x lies in the interval [1,2].
  7. Try to see what happens when you try to calculate the square root of -1 .

Solutions (please try them yourself first!).

Problems without solutions

  1. You can perform calculations with the `char` data type . It is then treated like an `int` by converting its code into a number. Calculate the 10th letter after 'A' . How many letters are between 'A' and 'Z' ? Where are the lowercase letters, uppercase letters, and numbers located?
  2. Test the move operators >> , >>>, and << . What do these operators do and why?
  3. What happens during a type cast from double to int ? Does the computer round or truncate the number? How does it round? How does it handle negative numbers?
  4. Test what happens when `n++` appears twice in an expression, or when `n++` appears followed by `n` again. What is the difference between this and `++n` ?
  5. What happens when a long number is converted to an int ? Is the higher-order part always truncated? Do negative numbers remain negative?

Back to the Java course