Опубликован: 04.12.2009 | Доступ: свободный | Студентов: 8233 / 585 | Оценка: 4.30 / 3.87 | Длительность: 27:27:00
Лекция 5:

Управляющие конструкции

< Лекция 4 || Лекция 5: 123 || Лекция 6 >
Аннотация: Составной оператор. Условный оператор if. Оператор выбора switch. Операторы инкремента ++ и декремента --. Оператор цикла for. Оператор цикла while - цикл с предусловием. Оператор цикла do...while - цикл с постусловием. Операторы прерывания continue, break, return, System.exit.
Ключевые слова: Java, составной оператор, автор, меню, пункт, if, else, операторы, форматирование, исключение, последовательность операторов, запись, произвольное, компилятор, логические ошибки, стиль оформления, reformat, команда, фигурные скобки, присваивание, функция, значение, диагностика, типизация, синтаксис, диапазон, вычисленное значение, блок операторов, программа, выражение, инкремент, цикла, инициализация, условие продолжения цикла, тело цикла, переменная, вычисление, площадь, интегрирование, длина, интеграл, алгоритм, интервал, выход, операции, мантисса, погрешности вычислений, счетчик, устойчивость, бит, метод Симпсона, умножение, время выполнения, неравенство, равенство, целое число, двоичное представление, погрешность, итерация, код завершения, вложенные циклы, идентификатор, вывод, оператор выбора, декремент, цикл с предусловием, цикл с постусловием

5.1. Составной оператор

Согласно синтаксису языка Java во многих конструкциях может стоять только один оператор, но часто встречается ситуация, когда надо использовать последовательность из нескольких операторов.

Составной оператор — блок кода между фигурными скобками {}:

Имеется два общепринятых способа форматирования текста с использованием фигурных скобок.

В первом из них скобки пишут друг под другом, а текст, находящийся между ними, сдвигают на 1-2 символа вправо (изредка – больше). Пример:

оператор
  {
    последовательность простых или составных операторов
  }

Во втором, более распространенном, открывающую фигурную скобку пишут на той же строке, где должен начинаться составной оператор, без переноса его на следующую строку. А закрывающую скобку пишут под первым словом. Пример:

оператор{
  последовательность простых или составных операторов
}

Именно такой способ установлен по умолчанию в среде NetBeans, и именно он используется в приводимых в данной книге фрагментах программного кода. Тем не менее, автор предпочитает первый способ форматирования программного кода, так как он более читаемый. Для установки такого способа форматирования исходного кода следует перейти в меню Tools/Options, выбрать Editor/Indentation, после чего в появившейся диалоговой форме отметить галочкой пункт Add New Line Before Brace.

После фигурных скобок по правилам Java, как и в /C++, ставить символ ";" не надо.

5.2. Условный оператор if

У условного оператора if имеется две формы: if и if- else.

По-английски if означает "если", else - "в противном случае". Таким образом, эти операторы могут быть переведены как "если…то…" и "если…то…в противном случае…".

Первая форма:

if(условие)
  оператор1;

Если условие равно true, выполняется оператор1. Если же условие==false, в операторе не выполняется никаких действий.

Вторая форма:

if(условие)
  оператор1;
else
  оператор2;

В этом варианте оператора if если условие==false, то выполняется оператор2.

Обратите особое внимание на форматирование текста. Не располагайте все части оператора if на одной строке – это характерно для новичков!

Пример:

if(a<b)
  a=a+1;
else if(a==b)
      a=a+1;
    else{
      a=a+1;
      b=b+1;
    };

Из этого правила имеется исключение: если подряд идет большое количество операторов if, умещающихся в одну строку, для повышения читаемости программ бывает целесообразно не переносить другие части операторов на отдельные строки.

Надо отметить, что в операторе if в области выполнения, которая следует после условия, а также в области else, должен стоять только один оператор, а не последовательность операторов. Поэтому запись оператора в виде

if(условие)
  оператор1;
  оператор2;
else
  оператор3;

недопустима. В таких случаях применяют составной оператор, ограниченный фигурными скобками. Между ними, как мы знаем, может стоять произвольное число операторов:

if(условие){
  оператор1;
  оператор2;
}
else
  оператор3;

Если же мы напишем

if(условие)
  оператор1;
else
  оператор2;
  оператор3;

- никакой диагностики ошибки компилятор не выдаст! Оператор3 в этом случае никакого отношения к условию else иметь не будет – подобное форматирование текста будет подталкивать к логической ошибке. При следующем форматировании текста программы, эквивалентному предыдущему при компиляции, уже более очевидно, что оператор3 не относится к части else:

if(условие)
  оператор1;
else
  оператор2;
оператор3;

Для того, чтобы оператор3 относился к части else, следует использовать составной оператор:

if(условие)
  оператор1;
else{
  оператор2;
  оператор3;
};

В случае последовательности операторов типа:

if(условие1)if(условие2)оператор1 else оператор2;

имеющийся else относится к последнему if, поэтому лучше отформатировать текст так:

if(условие1)
  if(условие2)
    оператор1;
  else
    оператор2;

Таким образом, если писать соответствующие if и else друг под другом, логика работы программы становится очевидной.

Пример неправильного стиля оформления:

if(условие1)
  if(условие2)
    оператор1;
else
  оператор2;

Этот стиль подталкивает к логической ошибке при чтении программы. Человек, читающий такую программу (как и тот, кто ее писал), будет полагать, что оператор2 выполняется, если условие1==false, так как кажется, что он относится к первому if, а не ко второму. Надо отметить, что сама возможность такой ошибки связана с непродуманностью синтаксиса языка Java. Для правильной работы требуется переписать этот фрагмент в виде

if(условие1){
  if(условие2)
    оператор1;
};
else оператор2;

Чтобы избегать такого рода проблем, используйте опцию Reformat code ("переформатировать код") из всплывающего меню, вызываемого в исходном коде щелчком правой кнопки мыши.

Типичной является ситуация с забытым объединением последовательности операторов в составной с помощью фигурных скобок. Например, пишут

if(условие)
  оператор1;
  оператор2;

вместо

if(условие)
  {оператор1;
   оператор2;
   };

Причем такую ошибку время от времени допускают даже опытные программисты. Reformat code не помогает – обычно эта команда вызывается после того, как программист далеко ушел от проблемного места, и перенос оператора под начало " if " не замечает. Для того, чтобы гарантированно избежать такой ошибки, следует ВСЕГДА ставить фигурные скобки в тех местах операторов Java, где по синтаксису может стоять только один оператор. Конечно, было бы лучше, чтобы разработчики Java предусмотрели такую конструкцию как часть синтаксиса языка. Возможно, в среде NetBeans в дальнейшем будет сделана возможность в опциях редактора делать установку, позволяющую автоматически создавать эти скобки. Точно так же, как автоматически создается закрывающая круглая скобка в операторе if после того как вы набираете if( .

Следует отметить разные правила использования точки с запятой при наличии части else в случае использования фигурных скобок и без них:

if(i==0)
    i++;
else
    i--;

Во втором случае после скобок (перед else ) точка с запятой не ставится:

if(i==0){
     i++;
}
else{
     i--;
};

Неприятной проблемой, унаследованной в Java от языка C, является возможность использования оператора присваивания "=" вместо оператора сравнения "==". Например, если мы используем булевские переменные b1 и b2, и вместо

if(b1==b2)
  i=1;
else
  i=2;

напишем

if(b1=b2)
  i=1;
else
  i=2;

никакой диагностики ошибки выдано не будет. Дело в том, что по правилам C и Java любое присваивание рассматривается как функция, возвращающая в качестве результата присваиваемое значение. Поэтому присваивание b1=b2 возвратит значение, хранящееся в переменной b2. В результате оператор будет работать, но совсем не так, как ожидалось. Более того, будет испорчено значение, хранящееся в переменной b1. Проблемы с ошибочным написанием "=" вместо "==" в Java гораздо менее типичны, чем в C/C++, поскольку они возникают только при сравнении булевской переменной с булевским значением. Если же оператор "=" ставится вместо "==" при сравнении числовой переменной, происходит диагностика ошибки, так как такое присваивание должно возвращать число, а не булевское значение. Жесткая типизация Java обеспечивает повышение надежности программ.

5.3. Оператор выбора switch

Является аналогом if для нескольких условий выбора. Синтаксис оператора следующий:

switch(выражение){
  case значение1: операторы1;
  ……………………………
  case значениеN: операторы N;
  default: операторы;
}

Правда, крайне неудобно, что нельзя ни указывать диапазон значений, ни перечислять через запятую значения, которым соответствуют одинаковые операторы.

Тип выражения должен быть каким-нибудь из целых типов. В частности, недопустимы вещественные типы.

Работает оператор следующим образом: сначала вычисляется выражение. Затем вычисленное значение сравнивается со значениями вариантов, которые должны быть определены еще на этапе компиляции программы. Если найден вариант, которому удовлетворяет значение выражения, выполняется соответствующий этому варианту последовательность операторов, после чего НЕ ПРОИСХОДИТ выхода из оператора case, что было бы естественно. - Для такого выхода надо поставить оператор break.Эта неприятная особенность Java унаследована от языка C.

Часть с default является необязательной и выполняется, если ни один вариант не найден.

Пример:

switch(i/j){
    case 1:
        i=0;
        break;
    case 2:
        i=2;
        break;
    case 10:
        i=3;
        j=j/10;
        break;
    default:
        i=4;
};

У оператора switch имеется две особенности:

  • Можно писать произвольное число операторов для каждого варианта case, что весьма удобно, но полностью выпадает из логики операторов языка Java.
  • Выход из выполнения последовательности операторов осуществляется с помощью оператора break. Если он отсутствует, происходит "проваливание" в блок операторов, соответствующих следующему варианту за тем, с которым совпало значение выражения. При этом никакой проверки соответствия очередному значению не производится. И так продолжается до тех пор, пока не встретится оператор break или не кончатся все операторы в вариантах выбора. Такие правила проверки порождают типичную ошибку, называемую "забытый break ".

5.4. Условное выражение …?... : …

Эта не очень удачная по синтаксису функция унаследована из языка C. Ее синтаксис таков:

условие?значение1:значение2

В случае, когда условие имеет значение true, функция возвращает значение1, в противном случае возвращается значение2.

Например, мы хотим присвоить переменной j значение, равное i+1 при i<5, и i+2 в других случаях. Это можно сделать таким образом:

j=i<5?i+1:i+2

Иногда при вычислении громоздких выражений этот оператор приходится использовать: без него программа оказывается еще менее прозрачной, чем с ним. Приоритет разделителей "?" и ":" очень низкий – ниже только приоритет оператора присваивания (в любых его формах). Поэтому можно писать выражения без использования скобок. Но лучше все-таки использовать скобки:

j=(i<5)?(i+1):(i+2)

5.5. Операторы инкремента ++ и декремента --

Оператор "++" называется инкрементным ("увеличивающим"), а "--" декрементным ("уменьшающим"). У этих операторов имеются две формы, постфиксная (наиболее распространенная, когда оператор ставится после операнда) и префиксная (используется очень редко, в ней оператор ставится перед операндом).

Для любой числовой величины x выражение x++ или ++x означает увеличение x на 1, а выражение x-- или --x означает уменьшение x на 1.

Различие двух форм связано с тем, когда происходит изменение величины – после вычисления выражения, в котором используется оператор, для постфиксной формы, или до этого вычисления – для префиксной.

Например, присваивания j=i++ и j=++i дадут разные результаты. Если первоначально i=0, то первое присваивание даст 0, так как i увеличится на 1 после выполнения присваивания. А второе даст 1, так как сначала выполнится инкремент, и только потом будет вычисляться выражение и выполняться присваивание. При этом в обоих случаях после выполнения присваивания i станет равно 1.

< Лекция 4 || Лекция 5: 123 || Лекция 6 >
Максим Старостин
Максим Старостин

Код с перемещением фигур не стирает старую фигуру, а просто рисует новую в новом месте. Точку, круг.

Наталья Алмаева
Наталья Алмаева
Россия
Александр Санчиров
Александр Санчиров
Россия, Москва