Note: this short lesson is just a quick supplement to the textbook reading to prepare you for assignment 2. Most future lessons will be much more detailed.
Let's work on a new problem now. Let's say we want a computer program to calculate paychecks for our employees. We want it to ask how many hours the employee worked and then we want it to calculate the amount of the paycheck and print out this amount. We will assume for now that all of our employees make $12 an hour. Here's an example of what will happen when we run our program (the text in bold face is typed by the person running the program. We call this person the user):
Enter hours worked: 23
The amount of the paycheck is $276
In order to do this we need a Java statement that says "wait for the user to type in a value and put the value that the user types into a variable." We'll call our variable "hoursWorked". It takes four steps to accomplish this:
These four steps are illustrated in the complete program below.
import java.util.Scanner;
public class Paycheck {
public static void main(String[] args) {
int hoursWorked;
int paycheckAmount;
int payrate;
Scanner input = new Scanner(System.in);
System.out.print("Enter hours worked: ");
hoursWorked = input.nextInt();
paycheckAmount = hoursWorked * 12;
System.out.println("The amount of the paycheck is "
+ paycheckAmount + " dollars.");
input.close();
}
}
Using a Variable for the Pay Rate:
Here's an example of a program that extends the concepts of this section a bit further. To make our paycheck program more flexible let's allow the user to enter the pay rate instead of forcing it to always be $12. That means we'll need another variable to store the pay rate. Instead of multiplying the hours worked by $12, we'll multiply the hours worked by the pay rate. Here's what it looks like.
import java.util.Scanner;
public class Paycheck {
public static void main(String[] args) {
int hoursWorked;
int paycheckAmount;
int payrate;
Scanner input = new Scanner(System.in);
System.out.print("Enter hours worked: ");
hoursWorked = input.nextInt();
System.out.print("Enter rate of pay: ");
payrate = input.nextInt();
paycheckAmount = hoursWorked * payrate;
System.out.println("The amount of the paycheck is "
+ paycheckAmount + " dollars.");
}
}
Enter hours worked: 23
Enter rate of pay: 10
The amount of the paycheck is 230 dollars.
What happens if we include a sequence of statements like this in our program?
int hours;
hours = 23 / 4;
The answer is that in Java when you divide two integers, the answer is an integer. You simply chop off (truncate is the technical term) any fraction or decimal part of the number. So 23 / 4 is 5.
Java provides the modulus operator so that we can get the remainder in integer division. To understand how this works, let's go back to third grade math for a minute (at least it was the third grade at my school). Remember when we first learned how to divide? We were taught to do the problem something like this:
5 r 3
4 | 23
20
3
We could read this as "23 divided by 4 is equal to 5 with a remainder of 3." This is how Java does division when we are working with just integers. The "is equal to 5" means that 23 / 4 equals 5. The "with a remainder of 3" means that 23 % 4 equals 3.
Although it might be hard to imagine at this point, the modulus operator actually turns out to be quite useful. For example, you can use the modulus operator to see if one number is divisible by another. To see if 24 is divisible by x, you would evaluate 24 % x. If the answer is 0, then 24 is divisible by x (in other words, when you divide 24 by x the remainder is 0).
Here is another example. Let's say we wanted to write a program to figure out how to make change for 83 cents using quarters, dimes, nickels and pennies. Our first step would be to figure out how many quarters to use. A correct assignment statement to accomplish this would be
numQuarters = 83 / 25;
83 / 25 is 3, so this gives us the correct number of quarters. Next we need to figure out how many dimes. Before we can do that we need to figure out how much money is left after we have taken care of the quarters. This is where modulus comes in.
amountLeft = 83 % 25;
83 % 25 is 8, so this gives us the correct amount of money left. The rest of this example is left as an exercise.
Up to this point we have discussed only integer values and variables. Of course, not every problem we encounter will deal exclusively with integers. In the rest of this lesson we will discuss several other types of variables that we can use. Throughout the discussion it is important to understand the distinction between variables and values. (Our text uses the phrase "literal constant" or "literal value" or just "literal" where I use the word "value".) For each data type, you must know how to distinguish between a variable and a value of that type, and under what circumstances each is used.
We have seen the use of variables of type int to store integer values. For example, the statement
hours = 47;
assigns the integer value 47 to the integer variable hours. In the same way we will now use variables of type double to store double values. A double value is defined as a number that has a decimal point in it. (Note: in some textbooks the type "float" is used instead of "double". You should use "double", not "float". When you see "float" used in the text just think "double". For our purposes they are synonymous.) In mathematical terms we might think of these as real numbers, but the Java definition of "double value" is not quite the same as the mathematical definition of "real number." For example, in Java 5 is an integer value, but 5.0 is a double value because it includes a decimal point. This is despite the fact that in algebra 5.0 would be considered an integer.
The declaration used to define a double variable looks like this:
double salary;
After using this declaration statement, we could then say something like
salary = 1213.81;
Here's another example:
double gallons;
double quarts;
quarts = 7;
gallons = quarts / 4;
If we had declared gallons and quarts to be integers, gallons would have been assigned the value 1. However, since we have declared gallons and quarts to be doubles, this statement assigns to gallons the value 1.75.
Because of the way that computers store doubles, you can never assume that a double value is being stored with exact precision. For this reason, you should never use the equals operator (==) to compare doubles. (We haven't technically covered the equals operator yet, so you'll need to just remember this fact for future use.)
You should always use type int whenever possible. Use double only when the situation requires the use of non-integer values.
At times you will need to convert an int into a double. For example, in order to do some sort of calculation that requires decimal points in the answer. If the int that needs to be converted is a literal, this is easy: you can just add a ".0" to the literal. For example, if the int is 47, to force Java to treat it as a double instead of as an int you can just use 47.0. You should expect to have to use this technique in assignment 2.
If the int that needs to be converted is an int variable, say count, then to convert it you would replace "count" with "(double) count". You may not need to use this right away, but you'll need it later in the course.
All 5 of the arithmetic operators we have discussed require both of their operands to be of the same type. This means, for example, that Java cannot add an int and a double. However, Java is able to convert back and forth between the two types, so the two types can be mixed in expressions and assignment statements. The assignment statement above, for example, has a double (quarts) and an int (4) in the expression. The results, however, are not always what we would expect. Unlike the situation in algebra, in Java we cannot perform mathematical operations with operands of two different types. We must have rules for how to convert one type to another so that the types of the operands match.
Rule #1 (expressions): The first rule is that if an expression has one int operand and one double operand, the int operand is temporarily changed to a double, so the result of the expression will be of type double. For example let's look at the expression
(2 + 3.5)/5
First we do 2 + 3.5. Since 2 is an int value and 3.5 is a double value, 2 becomes 2.0 (a double value), and the result is 5.5.
Now we have 5.5 / 5. Since 5.5 is a double value and 5 is an int value, the 5 gets changed to 5.0 (a double value) and the result is 1.1.
Rule #2 (assignments): Things get a bit more complicated in assignment statements. The rule is that Java tries to change the value of the expression on the right side of the assignment operator so that it matches the type of the variable of the left side of the assignment operator. If the variable on the left is a double and the variable on the right is an int, Java can do this automatically. If the variable on the left is an int and the variable on the right is a double, you'll get a syntax error unless you explicitly convert the double to an int by preceding the double with (int).
Example 1: int i;
double x;
double y;
x = 11;
y = 4;
i = x / y;
This would cause a syntax error, because in the last statement we need to convert a double (x / y) to an int (i), which Java will not do automatically. So we would do this instead:
int i;
double x;
double y;
x = 11;
y = 4;
i = (int) (x / y);
Another option would be this:
int i;
double x;
double y;
x = 11;
y = 4;
i = (int) x / (int) y;
Example 2:
int i;
int j;
double x;
i = 11;
j = 4;
x = i / j;
Because i and j are both integers, i/j is equal to 2. When Java goes to assign this value to x, it realizes that x is a double variable, and so before doing the assignment, it converts 2 to a double. So x gets the value 2.0.
Both of these examples illustrate that Java doesn't always do things the way we expect it to. Unless we are careful, we might not expect i to get the value 2 in example 1, because in math we learn to give an exact answer (2.75) or to round off to the nearest integer (3). In example 2, we might expect x to get the value 2.75. After all, x is a double variable so it could handle the value 2.75. If we are careful, though, we notice that i and j are both integers, so i/j is equal to 2. When mixing doubles and ints in expressions and assignment statements, we must be very careful to follow Java's rules exactly.
Sometimes it is desirable to store a character in a variable. In the same way that we use int variables to store integer values and double variables to store double values, we use char variables to store character values.
Characters are things like letters ('a', 'Z'), digits ('1','9','0'), and other symbols that might appear on a screen ('$','+','^'). There are also some characters that are invisible, but we won't concern ourselves with them just yet.
A declaration statement to declare a character variable looks like this:
char ch;
Then we could say something like this:
ch = '?';
We must be very careful to distinguish between char values and variables. With integers this is easy: hours is obviously a variable, not an integer value. 47 is obviously an integer value, not a variable. The same is true for double values and variables. With characters things get more difficult. We distinguish between variables and character values by placing single quotes around character values. This is why the question mark in the example above has single quotes around it. This means that if we see the letter x in a program (no quotation marks), it is a variable, not a character value. But if we see 'x' in a program it is a character value, not a variable.
A common mistake made by novice computer programmers is omitting the quotation marks when using a character value. When this happens, Java will think that we are trying to use a variable that has not been declared.
Two other important points about character values and variables:
Be careful as you work through the next three examples. Note that despite their many similarities there are important differences. You might even want to start by making sure that you see the differences in the code given for the three examples.
Example 1
What would be the output of the following program segment?
char m;
char x;
m = 'x';
x = 'm';
System.out.println('x');
The answer is that the letter "x" would appear on the output screen. Why? Let's trace through this code. First two variables are declared. We picture that situation like this:
___ ___
| | | |
m | ? | x | ? |
|___| |___|
The question marks in the boxes indicate that the values stored in the variables m and x are unknown. This is always the case immediately after we declare a variable. The value could be anything, we just don't know.
Next we have an assignment statement placing the character value 'x' into the variable m. Our picture now looks like this:
___ ___
| | | |
m |'x'| x | ? |
|___| |___|
The next statement is x = 'm'; Our picture now looks like this:
___ ___
| | | |
m |'x'| x |'m'|
|___| |___|
It turns out that all of this is irrelevant, because when we hit the output statement, the character value 'x' is printed on the screen without regard to what is stored in the variables.
Example 2
What would be the output of the following program segment?
char m;
char x;
m = 'x';
x = 'm';
System.out.println(x);
The answer is that the letter "m" would appear on the output screen. Why? Let's trace through this code. First two variables are declared. We picture that situation like this:
___ ___
| | | |
m | ? | x | ? |
|___| |___|
Next we have an assignment statement placing the character value 'x' into the variable m. Our picture now looks like this:
___ ___
| | | |
m |'x'| x | ? |
|___| |___|
The next statement is x = 'm'; Our picture now looks like this:
___ ___
| | | |
m |'x'| x |'m'|
|___| |___|
When we hit the output statement, we look up the value stored in the variable "x". This is where example 2 differs from example 1. In example 1, the x in the cout statement had single quotes around it, making it a value that was simply printed. In example 2 the "x" does not have single quotes around it, so it is the variable x. The character value 'm' is stored in the variable x, and that is what gets printed on the screen.
Example 3 What would be the output of the following program segment? char m;
char x;
m = 'x';
x = m;
System.out.println(x);
The answer is that the letter "x" would appear on the output screen. Why? Let's trace through this code. First two variables are declared. We picture that situation like this:
___ ___
| | | |
m | ? | x | ? |
|___| |___|
The question marks in the boxes indicate that the values stored in the variables m and x are unknown. This is always the case immediately after we declare a variable. The value could be anything, we just don't know.
Next we have an assignment statement placing the character value 'x' into the variable m. Our picture now looks like this:
___ ___
| | | |
m |'x'| x | ? |
|___| |___|
The next statement is x = m; Notice that the thing on the right of the assignment operator is not a character value this time. It is a variable. We can tell this because if it was a character value it would be surrounded by single quotes. Execution of this assignment statement involves looking up the value stored in the variable m and placing that value in the variable x. As we can see from the previous picture, the value stored in the variable m is the character value 'x'. So we place that character into the variable x. our picture now looks like this:
___ ___
| | | |
m |'x'| x |'x'|
|___| |___|
So when we hit the output statment, the character value 'x' is stored in the variable x, and that is what gets printed on the screen.