Characters and Strings. A: Escape Sequences
Characters and Strings. A: Escape Sequences
Characters and Strings. A: Escape Sequences
ing point numbers, and truefalse values, along with sample programs that
illustrate their use.
Characters and Strings. A char is an alphanumeric character or symbol,
16
like the ones that you type. There are 2 different possible character values,
but we usually restrict attention to the ones that represent letters, numbers,
symbols, and white-space characters like tab and newline. To specify a character as a char literal, we enclose it in single quotes: 'a' represents the
letter a. For tab, newline, single quote and double quote, we use the special
escape sequences \t, \n, \', and \", respectively. The characters are encoded
as 16-bit integers using an encoding scheme known as Unicode, and there are
escape sequences for specifying any special character (see Appendix X). We
usually do not perform any operations on characters other than assigning
values to variables and using the comparison functions defined later in this
section, so we move immediately on to other data types.
A String is a sequence of characters. A literal String is a sequence
of characters within double quotes, like "Hello, World". The String data
type is not a primitive type, but Jave sometimes treats it like one. For example,
one of the most common operations that we perform on Strings is built in
to the Java language. That operation is known as concatenation: given two
strings, chain them together to make a new string. The symbol for concatenating strings in Java is + (the same symbol that we use for adding numbers).
For example, the following Java code fragment is like the one that we considered at the beginning of this section, but it uses Strings instead of ints:
String a, b, c;
a = "1234";
b = "99";
c = a + b;
As before, the first statement declares three variables to be of type String and
the next three assign values to them. In this case, the end result that c has the
value "123499".
We use the concatenation operation frequently to put together
results of computation in output. For example we could make Program 2.1.2
much simpler by replacing its three statements by this single statement:
25
%
%
1
1
1
1
javac Ruler
java Ruler
2 1
2 1 3 1 2 1
2 1 3 1 2 1 4 1 2 1 3 1 2 1
The concatenation operation (along with the ability to declare String variables and to use them in expressions and assignment statements) is sufficiently powerful to allow us to attack some nontrivial computing tasks, as
illustrated in Program 2.1.1 and Exercise 2.1.18.
How do we print out the values of other types of data? To print out
anything, we need to convert it from its internal representation to a String.
Similarly, when we put a value on the command line, we type a string of characters: if we want to process the data that the string represents, we must convert the string to the appropriate internal reservation for that type of data.
26
If a and b are int variables with the values 1234 and 99, respectively, then this
statement prints out the string 1234 + 99 = 1243. This usage takes advantage of the Java convention that if one of the operands of + is a String, then
the other is automatically converted to a String so that the + is interpreted as
concatenation. We will discuss the specific rules for such conversions in more
detail at the end of this section, after we have discussed properties of each of
the types.
Integers. An int is an integer (whole number) between 2147483648 and
2147483647 . These bounds derive from the fact that integers are represented
32
in binary with with 32 binary digits: there are 2 possible values. (The term
binary digit is omnipresent in computer science, so the abbreviation bit is
always used: a bit is either 0 or 1.) The range of possible int values is asymmetric because 0 is included with the positive values. We will consider number representations in detail in Chapter 5 (see also Appendix X); in the
present context it suffices to know that an int is one of the finite set of values
in the range just given. We use ints frequently not just because they occur
27
= + p);
= + q);
= + r);
+ + r);
% javac IntOps
% java IntOps 1234 99
1234 * 99 = 122166
1234 / 99 = 12
1234 % 99 = 46
1234 = 12*99 + 46
frequently in the real world, but also they naturally arise when expressing
algorithms.
Standard arithmetic operators for addition/subtraction ( + and -),
multiplication (*), division (/), and remainder (%) for the int data type are
built in to Java. These operators take two int arguments and produce an int
result, with one significant exception: division or reminder by 0 is not
allowed. These operations are defined just as in grade school: Given two ints
a and b, the value of a / b is the number of times b goes into a and the value
of a % b is the remainder that you get when you divide a by b. The int result
that we get from these operations is just what we expect from the gradeschool definition, with one significant exception: if the result is too large to fit
into the 32-bit representation described above, then it will be truncated to the
28
least significant 32 bits. We have to take care that such a result is not misinterpreted by our code.
Integer literals are just strings of decimal integers, as in the code fragment above. To use integer parameters on the command line, we need to use
the built-in Java method Integer.parseInt, which converts string values to
integer values. When we type a number as a command-line parameter, it is a
string of characters, so we have to include a statements that calls with Integer.parseInt to convert it to an integer at execution time; if we type the
same string of characters within the program, the compiler interprets it as a
literal integer and does the conversion at compile time. Program 2.1.2 illustrates these basic operations for manipulating integers.
Three other built-in types are different representations of integers.
The long, short, and byte types are the same as int except that they use 64,
16, and 8 bits respectively, so the range of allowed values is accordingly different. Programmers use long when working with huge integers and the others
to save space. Appendix X gives a table with the maximum and minimum values for each type.
Real numbers. The double type is for representing floating-point numbers, for use in scientific and commercial applications. The internal representation is like scientific notation, so that we can compute with numbers in a
huge range. Floating-point numbers are not the same as real numbers, primarily because there are an infinite number of real numbers, and we can only
represent finitely many numbers in any digital computer representation.
Floating-point numbers do approximate real numbers sufficiently well that
we can use them in all sorts of applications, but we often need to cope with
the fact that we cannot always do exact computations.
We can use a string of digits with a decimal point to type floatingpoint numbers. For example, 3.14159 represents a six-digit approximation
to ! . Alternatively, we can use a notation like scientific notation: the literal
23
6.022E23 represents the number 6.022 10 . As with integers, you can use
these conventions to write floating-point literals in your programs or to provide floating-point numbers as string parameters on the command line.
The arithmetic operators +, -, *, and / are defined for double. The
result of a calculation can be 0 (if the number is too small to be represented)
29
% javac Quadratic
% java Quadratic -3.0 2.0
2.0
1.0
% java Quadratic -1.0 -1.0
1.618033988749895
-0.6180339887498949
% java Quadratic 1.0 1.0
NaN
NaN
or one of the special values Infinity (if the number is too large to be represented) or NaN (if the result of the calculation is undefined). Beyond the builtin operators, the Java Math library defines the square root, trigonometric
functions, logarithm/exponential functions and other common functions for
floating-point numbers (see Appendix X).
There are myriad details to consider with regard to precision and
when calculations involve 0, infinity or NaN (see Appendix X and the Q&A
and exercises at the end of this section) but you can use these operations in a
natural way for all sorts of familiar calculations. With this library, you can
begin to write Java programs instead of using a calculator for all kinds of calculations. For example, Program 2.1.3 shows the use of doubles in computing roots of a quadratic equation using the quadratic formula. Several of the
exercises at the end of this section further illustrate this point.
30
&&
a && b is true
a && b is false
or
||
a || b is true
a || b is false
not
!a
!a
is true if a is false
is false if a is true
Although these definitions are intuitive and easy to understand, it is worthwhile to fully specify each possibility for each operation, as in the following
tables. Such tables are known as truth tables.
a
!a
a && b
a || b
true
false
false
false
false
false
false
true
false
true
false
true
true
false
false
true
true
true
true
true
The not function (on the left) has only one operand: its value for each of the
two possible values of the operand is specified in the second column. The and
31
% javac LeapYear
% java LeapYear 2004
true
% java LeapYear 1900
false
% java LeapYear 2000
true
and or functions each have two operands: there are four different possibilities
for operand input values, and the values of the functions for each possibility
are specified in the right two columns.
We can use these operators with parentheses to develop arbitrarily
complex expressions, each of which specifies a well-defined boolean function.
Often, the same function appears in different guises. For example, the
expressions (a && b) and !(!a || !b) are equivalent.
The study of manipulating expressions of this kind is known as Boolean logic and is the subject of Section 5.1. This field of mathematics is fundamental to computing. For example, Boolean logic plays an essential role in
the design and operation of computer hardware itself, as we will see in Chapter 5. It also helps us understand fundamental limitations on what we can
compute, as we will see in Chapter 8.
32
a op b
true
false
2 == 2
2 == 3
3 != 2
2 != 2
==
equal
a is equal to b
!=
not equal
!(a == b)
<
less than
a is less than b
2 < 13
2 < 2
<=
(a < b) || (a == b)
2 <= 2
3 <= 2
>
greater than
!(a <= b)
13 > 2
2 > 13
>=
!(a < b)
3 >= 2
2 >= 3
Since operations are defined only with respect to data types, each of these
symbols stands for many operations, one for each data type. It is required
that both operands be of the same type, and the result is always boolean.
Even without going into the details of number representation that we consider in Section X, it is clear, on reflection, that the operations for the various
types are really quite different: for example, it is one thing to compare two
ints to check that 2 == 2 is true but quite another to compare two doubles
to check whether 2.1 == .0021E3 is true or false.
33
34
% javac RandomInt
% java RandomInt 1000
548
% java RandomInt 1000
141
% java RandomInt 1000000
135032
the result to double, because that is what Math.sqrt expects. Java does this
kind of type conversion automatically because your intent is clear and it can
do so with no loss of information. On the other hand, if the conversion might
involve loss of information, for example if you try to assign a double to an
int, you will get an error message from the compiler.
Explicit cast. Java has some built-in type conversion methods for primitive
types that you can use when you are aware that you might lose information,
but you have to make your intention to do so explicit using a device called a
cast. You cast a variable or an expression from one primitive type to another
simply by prepending the desired type name within parentheses: for example,
the expression (int) 3.14159 is a cast from double to int that is of type
int with value 3. Java has built-in conversion methods defined for casts
among primitive numeric types that implement reasonable and convenient
approaches to throwing away information (for a full list, see Appendix X).