Главная страница

Java. Полное руководство. 8-е издание. С. Н. Тригуб Перевод с английского и редакция


Скачать 25.04 Mb.
НазваниеС. Н. Тригуб Перевод с английского и редакция
АнкорJava. Полное руководство. 8-е издание.pdf
Дата28.02.2017
Размер25.04 Mb.
Формат файлаpdf
Имя файлаJava. Полное руководство. 8-е издание.pdf
ТипДокументы
#3236
страница9 из 90
1   ...   5   6   7   8   9   10   11   12   ...   90
ГЛАВА
"ГГ
i Управляющие
операторы
В языках программирования управляющие операторы используются для реализации переходов и ветвлений в потоке выполнения команд программы в соответствии с ее состоянием. Управляющие операторы программы Java можно разделить наследующие категории операторы выбора, операторы цикла и операторы перехода. Операторы выбора позволяют программе выбирать различные ветви выполнения команд в соответствии с результатом выражения или состоянием переменной. Операторы цикла позволяют программе повторять выполнение одного или нескольких операторов (те. они образуют циклы. Операторы перехода обеспечивают возможность нелинейного выполнения программы. В этой главе мы рассмотрим все управляющие операторы В языке Java поддерживаются два оператора выбора i f и s w itc h . Эти операторы позволяют управлять порядком выполнения команд программы в соответствии с условиями, которые известны только вовремя выполнения. Читатели будут приятно удивлены возможностями и гибкостью этих двух операторов.
В этой главе мы подробно рассмотрим оператор i f , изначально представленный в главе 2. Это — оператор условного выбора ветви программы Java. Его можно использовать для направления выполнения программы по двум различным ветвям. Общая форма этого оператора выглядит следующим образом (условие) оператор оператор Здесь каждый оператор это одиночный оператор или составной оператор, заключенный в фигурные скобки (те. блок. Условие это любое выражение, возвращающее значение типа b o o le a n . Выражение ё 1 э е не обязательно.
О ператор i f работает следующим образом если условие истинно, программа выполняет оператор В противном случае она выполняет оператор (если он существует. Нив одной из ситуаций программа не будет выполнять оба оператора. Например, рассмотрим следующий фрагмент кода а, Ь / . .
if(a < b) а = 0;
else b = Операторы выбора
Оператор i f

1 1 8 Часть I. Язык В данном случае, если значение переменной а меньше значения переменной Ь, значение переменной а устанавливается равным нулю. В противном случае значение переменной b устанавливается равным нулю. Нив одной из ситуаций значения обеих переменных аи не могут получить нулевые значения.
Чаще всего в управляющих выражениях оператора
if будут использоваться операции сравнения. Но это необязательно. Для управления оператором i f можно применять и одиночную переменную типа boolean, как показано в следующем фрагменте кода dataAvailable;
/ / . .
if (Помните, что только один оператор может следовать непосредственно за ключевым словом if или else. Если нужно включить больше операторов, придется создать код, подобный приведенному в следующем фрагменте bytesAvailable;
/ / . .
if (bytesAvailable > 0 ) {
ProcessData();
bytesAvailable -= n;
} В этом примере оба оператора, помещенные внутри блока, будут выполняться, если значение переменной bytesAvailable больше нуля.
Н екоторые программисты предпочитают использовать в операторе i f фигурные скобки даже при наличии только одного оператора в каждом выражении. Это упрощает добавление операторов в дальнейшем и избавляет от беспокойства по поводу наличия фигурных скобок. Фактически пропуск определения блока в тех случаях, когда он необходим, — достаточно распространенная ошибка. Например, рассмотрим следующий фрагмент кода bytesAvailable;

/ / . .
if (bytesAvailable > 0 ) {
ProcessData();
bytesAvailable -= n;
} else
waitForMoreData();
bytesAvailable = Если судить по уровню отступа в коде, предполагалось, что оператор bytesAvailable=n; должен выполняться внутри выражения else. Однако, как вы помните, в программе Java отступы значения не имеют, и компилятор никак не может узнать намерения программиста. Компиляция этого кода будет выполняться без вывода каких-либо предупреждающих сообщений, но при выполнении программа будет вести себя не так, как было задумано. В следующем фрагменте ошибка предыдущего примера исправлена bytesAvailable;
/ / . .
if (bytesAvailable > 0 ) {
ProcessData();
bytesAvailable -= n;
Глава 5. Управляющие операторы 1 9
} Вложенные операторы i Вложенный оператор i f — это оператор i f , являющийся целью другого оператора i f или e l s e . В программах вложенные операторы i f встречаются очень часто. При использовании вложенных операторов i f важно помнить, что оператор e l s e всегда связан с ближайшим оператором i f , расположенным водном с ним блоке и еще несвязанным с другим оператором e l s e .
if(i == Юс этот оператор if
else a = с
// связан с этим оператором else
}
else a = d;
// а этот с оператором if(i == Как видно из комментариев, последний оператор e l s e связан нес оператором i f (j <2 0 ), поскольку тот не находится водном с ним блоке (несмотря на то, что он является ближайшим оператором i f , который еще не связан с оператором e l s e ) . Последний оператор e l s e связан с оператором i f ( i= = 1 0 ) . Внутренний оператор e l s e связан с оператором i f (k> 1 0 0 ), поскольку тот является ближайшим внутри этого же блока.
Конструкция i f - e l s e - i Распространенной конструкцией программирования, построенной на основе последовательности вложенных операторов i f , является конструкция i f - e l s e - i f . Она выглядит следующим образом f условие bib)bibоператорbi
else i f условие оператору слови е )
оператор;
else
оператор;
Операторы i f выполняются последовательно, сверху вниз. Как только одно из условий, управляющих оператором i f , становится равным t r u e , программа выполняет оператор, связанный сданным оператором i f , и пропускает остальную часть конструкции i f - e l s e - i f . Если ни одно из условий не выполняется неравно, программа выполнит заключительный оператор e l s e . Этот последний оператор служит условием, используемым по умолчанию. Иными словами, если проверка всех остальных условий дает отрицательный результат, программа выполняет последний оператор e l s e . Если заключительный оператор e l s e неуказан, а результат проверки всех остальных условий равен f a l s e , программа не будет выполнять никаких действий.
Ниже приведен пример программы, в которой конструкция i f - e l s e - i f служит для определения времени года, к которому относится конкретный месяц Демонстрация применения операторов if-else-if.

class IfElse {
public static void main(String args[]) {

1 2 Часть I. Язык Java
int month = 4; // Апрель
String season;
if(month == 12 I
I
month == 1 I
I
month == 2)
season = "зиме
else if(month == 3 I
I
month == 4 |
I
month == 5)
season = "весне
else if(month == 6 I
I
month == 7 I
I
month == 8)
season = "лету
else if(month == 9 II month = = 1 0 II month == 11)
season = "осени = "вымышленным месяцам";
System.out.println("Апрель относится к " + season + "Программа создает следующий вывод.
Апрель относится к весне
Прежде чем продолжить чтение главы, вы можете поэкспериментировать с этой программой. Убедитесь, что независимо от значения, присвоенного переменной month, внутри конструкции if-else-if будет выполняться только один оператор присваивания.
Оператор s w it c Оператор оператор ветвления в Java. Он предлагает простой способ направления потока выполнения команд по различным ветвям кода в зависимости от значения управляющего выражения. Зачастую он оказывается эффективнее применения длинных последовательностей операторов if-else-if. Общая форма оператора switch имеет следующий вид.
switch (выражение {
case значение I последовательность операторов
break;
case значение 1 последовательность операторов
break;
case
значениеЫ:
// последовательность операторов
break;
default:
// последовательность операторов, выполняемая по умолчанию
}
Для всех версий Java до JDK 7 выражение должно иметь тип type, short, int, char или тип перечисления. (Перечисления описаны в главе 12.) Начиная с JDK 7 выражение может иметь также тип
String. Каждое значение, определенное в операторах case, должно быть уникальным константным выражением (таким, как литеральное значение. Дублирование значений case не допускается. Тип каждого значения должен быть совместим с типом выражения.
Оператор switch работает следующим образом. Значение выражения сравнивается с каждым значением в операторах case. При обнаружении совпадения программа выполняет последовательность кода, следующую заданным оператором case. Если значения ни одной из констант не совпадают со значением вы
Глава 5. Управляющие операторы
1 2 1
ражения, программа выполняет оператор d e f a u l t . Однако этот оператор необязателен. При отсутствии совпадений со значениями c a s e и отсутствии оператора d e f a u l t программа не выполняет никаких дальнейших действий.
О ператор b r e a k внутри последовательности s w i t c h служит для прерывания последовательности операторов. Как только программа доходит до оператора b r e a k , она продолжает выполнение с первой строки кода, следующей за всем оператором s w itc h . Этот оператор оказывает действие выхода из оператора s w itc h Ниже представлен простой пример использования оператора s w itc h .
// Простой пример применения оператора switch,
class SampleSwitch {
public static void main(String a r g s []) {
for(int i=0; i<6; i++)
switch(i) {
case 0:
System.out.println("i равно нулю равно
единице."
break;
case 2:
System.out.println("i равно двум равно трем больше Эта программа создает следующий вывод равно нулю
i равно единице равно двум
i равно трем больше 3.
i больше Как видите, на каждой итерации цикла программа выполняет операторы, связанные с константой c a s e , которая соответствует значению переменной i. Все остальные операторы пропускаются. После того как значение переменной i становится больше 3, оно перестает соответствовать какому-либо значению c a s e , поэтому программа выполняет оператор d e f a u l t Оператор необязателен. Если его опустить, программа продолжит выполнение со следующего оператора c a s e . В некоторых случаях желательно использовать несколько операторов c a s e без разделяющих их операторов b r e a k . Например, рассмотрим следующую программу / В последовательности switch операторы break необязательны
class MissingBreak {
public static void main(String a r g s []) {
for(int i=0; i<12; i++)
switch(i) {
case 0:
case 1:
case 2:

1 2 2 Часть I. Язык Java
case 3:
case 4:
System.out.println("i меньше 5");
break;
case 5:
case 6:
case 7:
case 8:
case 9:
System.out.println("i меньше 10");
break;
default:
System.out.println("i равно или больше Эта программа создает следующий вывод меньше 5
i меньше 5
i меньше 5
i меньше 5
i меньше 5
i меньше 10
i меньше 10
i меньше 10
i меньше 10
i меньше 10
i равно или больше 10
i равно или больше Как видите, программа выполняет каждый оператор c a s e , пока не достигнет оператора b r e a k (или конца оператора s w itc h ) Хотя приведенный пример был создан специально в качестве иллюстрации, пропуск операторов b r e a k находит множество применений в реальных программах. В качестве более реалистичного примера рассмотрим измененную версию приведенной ранее программы со временами года. В этой версии мы использовали оператор s w i tc h , что позволило создать более эффективную реализацию Усовершенствованная версия программы с временами года
class Switch {
public static void main(String a r g s []) {
int month = 4;
String season;
switch (month) {
case 12:
case 1:
case 2:
season = "зиме
break;
case 3:
case 4:
case 5:
season = "весне
break;
case 6:
case 7:
case 8:
season = "лету
break;
case 9:
Глава 5. Управляющие операторы
1 2 3
case 10:
case 11:
season = "осени
break;
default:
season = "вымышленным месяцам";
}
System.out.println("Апрель относится к" + season +Как упоминалось, начиная с JDK 7 вы можете использовать строку для контроля оператора switch.
// Использование строки для контроля оператора switch,
class StringSwitch {
public static void main(String a r g s []) {
String str = "два
switch(str) {
case "один":
System.out.println("один");
break;
case "два":
System.out.println("два");
break;
case "три":
System.out.println("три"); нет соответствия Как вы и ожидали, вывод будет следующим.
два
Строка, содержащаяся в переменной str которой в данном случае является "два, сравнивается с константами оператора case. Когда находится соответствие (во втором операторе case), выполняется связанная с ним последовательность кода.
Возм ож ность использовать строки во п ераторе switch упрощает много ситуаций. Например, использование оператора со строками является существенным усовершенствованием по сравнению с использованием эквивалентной последовательности операторов. Однако выбор среди строк дороже выбора среди целых чисел. Поэтому лучше применять строки только в тех случаях, когда контролирующие данные уже находятся в строковой форме. Другими словами, не используйте строки в операторе без необходим ости.
В лож енны е операторы s w i t c Оператор можно использовать в последовательности операторов внешнего оператора switch. Такой оператор называют вложенным оператором switch. Поскольку оператор switch определяет собственный блок, каких- либо конфликтов между константами case внутреннего и внешнего операторов switch не происходит. Например, следующий фрагмент полностью допустим

1 2 4 Часть I. Язык Java
switch(count)
{
case 1:
switch(target)
{// вложенный оператор switch
case 0:
System.out.println("target равна 0");
break;
case 1: // конфликты с внешним оператором switch отсутствуют
System.o u t .println("target равна 1");
break;
}
break;
case 2: // В данном случае оператор easel
: внутреннего оператора switch не^конфлик- тует с оператором easel: внешнего оператора switch. Программа Сравнивает значение переменной count только со списком ветвей case внешнего уровня. Если значение count равно 1, программа сравнивает значение переменной tar­
get с внутренним списком ветвей В результате можно выделить следующие три важных свойства оператора Оператор switch отличается от оператора if тем, что он может выполнять проверку только равенства, в то время как оператор if может вычислять результат булевого выражения любого типа. То есть оператор switch ищет только соответствие между значением выражения и одной из констант Никакие две константы case водном и том же операторе switch не могут иметь одинаковые значения. Конечно, внутренний оператор switch и содержащий его внешний оператор switch могут иметь одинаковые константы Как правило, оператор switch эффективнее набора вложенных операторов Последнее свойство представляет особый интерес, поскольку позволяет понять работу компилятора. Компилируя оператор, компилятор будет проверять каждую константу case и создавать таблицу переходов, которую будет использовать для выбора ветви программы в зависимости от значения выражения. Поэтому в тех случаях, когда требуется осуществлять выбор в большой группе значений, оператор будет выполняться значительно быстрее последовательности операторов if-else. Это обусловлено тем, что компилятору известно, что все константы case имеют один и тот же тип, и их нужно просто проверять на равенство значению выражения. Компилятор не располагает подобными сведениями о длинном списке выражений оператора Операторы цикла

Операторами
4
HioiaJava являются for, while и do-while. Эти операторы образуют конструкции, обычно называемые циклами. Как, наверняка, известно читателям, циклы многократно выполняют один и тот же набор инструкций до тех пор, пока не будет удовлетворено условие завершения цикла. Как вы вскоре убедитесь, Java предлагает средства создания циклов, способные удовлетворить любые потребности программирования
Глава 5. Управляющие операторы
1 2 Цикл w h i l Оператор цикла while
— наиболее часто используемый оператор цикла Java. Он повторяет оператор или блок операторов до тех пор, пока значение его управляющего выражения истинно. Он имеет следующую общую форму условие) {
// тело цикла
}
Здесь условие любое булево выражение. Тело цикла будет выполняться до тех пор, пока условное выражение истинно. Когда условие становится ложным, управление передается строке кода, непосредственно следующей за циклом. Фигурные скобки могут быть опущены, только если в цикле повторяется лишь один оператор.
В качестве примера рассмотрим цикле, который выполняет обратный отсчет начиная с 10; вывод — ровно 10 строк тактов Демонстрация использования цикла while,

class While {
public static void main(String a r g s []) {
int n = 10;
while(n > 0 ) такт " + n ) ; После запуска эта программа выводит десять “тактов”.
такт 10 такт 9
такт 8 такт 7 такт 6 такт 5 такт 4 такт 3 такт 2 такт Поскольку цикл while вычисляет свое условное выражение вначале цикла, тело цикла не будет выполнено ни разу, если в самом начале условие оказывается ложным. Например, в следующем фрагменте кода метод println
() никогда не будет вызвана (а > Ь)
1   ...   5   6   7   8   9   10   11   12   ...   90


написать администратору сайта