Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Тема 1.13 Автоупакока и автораспаковка.
Начиная с JDK 5 в Java существуют два новых средства: автоупаковка (autoboxing) и автораспаковка (autounboxing). Данная возможность позволяет не использовать методы типа типValue() для преобразования примитивного типа в объект. Так, автоупаковка происходит каждый раз, когда элементарный тип должен быть преобразован в примитивный тип, автораспаковка – наоборот. Автораспаковка/автораспаковка может быть осуществлена, когда аргумент передается в метод или значение из метода возвращается, или в выражениях. Листинг 1.17 public class Main { public static void main(String[] args) { IntegerobjI; inti = 100; // пример ручной упаковки и распаковки objI = Integer.valueOf(i); System.out.println(" 1: " + objI.intValue()); // пример автоматической упаковки/распаковки objI = 2000; i = objI; System.out.println(" 2: objI=" + objI + " i=" + i); // автоматическая упаковка/распаковка в методы doubled; d = getDouble(2.345); System.out.println(" 3: d=" + d); // автоматическая упаковка/распаковка в выражении objI++; i = objI / 2 + 10; System.out.println(" 4: objI=" + objI + " i=" + i); // упаковка/распаковка булевского типа Booleanbool; bool = true; if (bool) { System.out.println(" true" ); } else { System.out.println(" false" ); } // упаковка/ распаковка символьного типа Characterch; ch = 'd'; char c = ch; System.out.println(c); }
public static double getDouble(Double d) { returnd; } }
Тема 1.14 Операторы Рисунок 1.36 – Операторы управления Как известно, любой алгоритм, можно разработать, используя линейные вычисления, разветвления и циклы. Записать его можно в разных формах: в виде блок-схемы, на псевдокоде или на обычном языке. Всякий язык программирования должен иметь средства записи алгоритмов. Они называются операторами (statements) языка. Операторы управления языка Java показаны на рис 1.36. Минимальный набор операторов должен содержать оператор для записи линейных вычислений, условный оператор для записи разветвлений и оператор цикла. Обычно состав операторов языка программирования шире: для удобства записи алгоритмов в язык включаются несколько операторов цикла, оператор варианта, операторы перехода, операторы описания объектов. В языке Java нет оператора goto. Все операторы языка Java можно разделить на: · операторы описания переменных и других объектов; · операторы-выражения; · операторы присваивания; · условные операторы if; · операторыциклов while, do-while, for; · операторы варианта switch; · операторы перехода break, continue и return; · блок {}; · пустые операторы – просто точка с запятой. Всякий оператор завершается точкой с запятой. Можно поставить точку с запятой в конце любого выражения, и оно станет оператором. Но смысл это имеет только для операций присваивания, инкремента и декремента и вызовов методов. В остальных случаях это бесполезно, потому что вычисленное значение выражения потеряется. Точка с запятой в Java не разделяет операторы, а является частью оператора. Линейное выполнение алгоритма обеспечивается последовательной записью операторов. Переход со строки на строку в исходном тексте не имеет никакого значения для компилятора, он осуществляется только для наглядности и читаемости текста. Блок Блок может содержать в себе нуль или несколько операторов с целью их использования как одного оператора в тех местах, где по правилам языка можно записать только один оператор. Например, {х=5; у=6; }. Можно записать и пустой блок –{}. Блоки операторов часто используются для ограничения области действия переменных и просто для улучшения читаемости текста программы. Условный операторif Условный оператор в Java записывается так: if (логВыр) оператор1; else оператор2; и действует следующим образом. Сначала вычисляется логическое выражение логВыр. Если результат true, то выполняется оператор1 и на этом выполнение условного оператора завершается, оператор2 не выполняется, далее будет выполняться следующий за if оператор. Если результат false, то действует оператор2, при этом оператор1 вообще не выполняется. Условный оператор может быть сокращенным: if (логВыр) оператор; и в случае false не выполняется ничего. Синтаксис языка не позволяет записывать несколько операторов ни в ветви if, ни в ветви else. При необходимости составляется блок операторов в фигурных скобках. Рекомендуется всегда использовать фигурные скобки и размещать оператор на нескольких строках с отступами, как показано в следующем примере: if (а < х) { х = а + b; } else { х = а – b; } Это облегчает добавление операторов в каждую ветвь при изменении алгоритма. Очень часто одним из операторов является снова условный оператор, например: if (n == 0) { sign = 0; } else if (n < 0) { sign = -1; } else { sign = 1; } При этом может возникнуть такая ситуация: int ind = 5, х = 100; if (ind > = 10) if (ind< = 20) x = 0; elsex = 1; Сохранит переменная х значение 100 или станет равной 0? Здесь необходимо волевое решение, и общее для большинства языков, в том числе и Java, правило таково: ветвь else относится к ближайшему слева условию if, не имеющему своей ветви else. Поэтому в нашем примере переменная х останется равной 100. Изменить этот порядок можно с помощью блока: if (ind > 10) { if (ind < 20) x = 0; }else x = 1; Вообще не стоит увлекаться сложными вложенными условными операторами, т.к. проверки условий занимают много времени. По возможности лучше использовать логические операции, например, в данном примере лучше написать следующее: if (ind > = 10 & & ind < = 20) { х = 0; } else { х = 1; }
Задания: Определить, какое значение будет в переменной dd 1). int dd, k1 = 3, k2 = 5, k3 = 7; if (k1 > 1) { if (k2! = 3) { dd = 4; } else { dd = 3; } } else { dd = 2; 2). int dd, k1 = 3, k2 = 5, k3 = 7; if (k1> 10) dd=1; else if (k1 % 3 == 1) dd=2; else if (k2 % 5 == 1) dd=3; else if (k3 % 3 == 2) dd=4; else dd=5; 3). int dd, k1 = 3, k2 = 5, k3 = 7; if (k1> 10) dd=1; else if (true) dd=2; else if (k2 % 5 == 1) dd=3; else if (k3 % 3 == 2) dd=4; else dd=5; 4). int dd, k1 = 6, k2 = 10, k3 = 21; if (k1> k2) dd=1; else if (k1> k3) dd=2; else if (k1+k2> k3) dd=3; else dd=4;
5). int dd=0; int k=44; if (k % 2 == 0) dd=dd+1; if (k % 3 == 1) dd=dd+2; if (k % 5 == 4) dd=dd+5; if (k % 6 == 4) dd=dd+9; 6). int dd=0; int k1=6; int k2=10; int k3=21; if (k1> k2 || k3> k2) dd=dd+1; if (k1 < k3& & k2! =10) dd=dd+2; else dd=dd+3; if (k1 % 5 == 4) dd=dd+5; if (k2% 6! = 4) dd=dd+9;
If-elseи? Оператор? называется тернарным оператором, поскольку он обрабатывает три операнда. Этот оператор записывается в следующем форме: выражение_1? выражение_2: выражение_3; где первое выражение должно быть логическим, т.е. возвращать тип boolean а второе и третье выражения, разделяемые двоеточием, могут быть любого за исключением void. Необходимо только, чтобы тип второго и третьего выражения совпадал. Значение выражения? определяется следующим образом. Сначала вычисляется первое выражение. Если оно возвращает значение true, то вычисляется второе выражение и значение, возвращаемое им, становится значением всего выражения? Если значение первого выражения – false, то вычисляется третье выражение, которое становится значением всего выражения?. Рассмотрим пример, в котором вычисляется абсолютное значение val и присваивается переменной absval: absval = val < 0? -val: val; // Получение абсолютного значения val. где переменной absval присваивается значение val, если переменная val больше или равна нулю. Если значение val отрицательное, то переменной absval присваивается значение val со знаком " минус" (что в результате даст положительную величину). Код, решающий ту же самую задачу, но использующий структуру if-else, будет выглядеть следующим образом: if(val < 0) absval = -val; else absval = val; Рассмотрим еще один пример использования оператора?. В листинге 1.18 выполняется деление двух чисел, но не допускается деление на нуль. Листинг 1.18 // Использование оператора? для предотвращения деления на нуль public class NoZeroDiv { public static void main(String args[]) { int result; for (int i = -5; i < 6; i++) { result = i! = 0? 100 / i: 0; if (i! = 0) { System.out.println(" 100 / " + i + " is " + result); } else { System.out.println(" i = " + result); } } } } Обратите внимание на следующую строку кода: result = i! = 0? 100 / i: 0; где переменной result присваивается результат деления 100 на i. Однако деление выполняется только в том случае, если значение переменной i не равно нулю. В противном случае переменной result присваивается нулевое значение. Выражение, возвращаемое оператором?, не обязательно присваивать переменной. Вы можете применить его, например, в качестве параметра при вызове метода. Если же все три выражения имеют тип boolean, то само выражение? может быть использовано в качестве условия для цикла или оператора if. Ниже приведена предыдущая программа, код которой несколько видоизменен(листинг 1.19). Она генерирует те же данные, которые были представлены ранее. Листинг 1.19 // Использование оператора? для предотвращения деления на нуль public class NoZeroDiv { public static void main(String args[]) { for (int i = -5; i < 6; i++) { if (i! = 0? true: false) { System.out.println(" 100 / " + i + " is " + 100 / i); } } } } Обратите внимание на выражение if. Если значение переменной i равно нулю, то выражение? возвращает значение false, что предотвращает деление на нуль, и результат не отображается. В противном случае осуществляется обычное деление.
Оператор циклаwhile Основной оператор цикла – оператор while – выглядит так: while (логВыр) оператор;
Вначале вычисляется логическое выражение логВыр; если его значение true, то выполняется оператор, образующий цикл. Затем снова вычисляется логическое выражение и действует оператор, и так до тех пор, пока не получится значение false. Если логВыр изначально равняется false, то оператор не будет выполнен ни разу. Предварительная проверка обеспечивает безопасность выполнения цикла, позволяет избежать переполнения, деления на нуль и других неприятностей. Поэтому оператор while является основным, а в некоторых языках и единственным оператором цикла. int i = 1, sum = 0; while (i < 5 & & sum < 4) { sum += i; i++; } System.out.println(sum); Можно организовать бесконечный цикл: while (true) оператор; Конечно, из такого цикла следует предусмотреть какой-то выход, например, используя оператор break. В противном случае программа зациклится, в результате чего придется принудительно прекращать ее выполнение. В листинге 1.20 показаны примеры использования бесконечного цикла. Листинг 1.20 publicclassMain { public static void main(String args[]) { int i = 0; while (true) { System.out.println(" i=" + i); i++; if (i == 10) { break; } } } } или так: public class Main { public static void main(String args[]) { int i = 0; boolean d = true; while (d) { System.out.println(" i=" + i); i++; if (i == 10) { d = false; } } } } Если в цикл необходимо включить несколько операторов, то следует использовать блок операторов {}.
Задания: 1) С помощью цикла whileи оператора if определяйте четность чисел и выводите их (числа от 1 до 10). 1-нечетное 2-четное И т.д. 2) Напишите цикл while выводящий числа последовательности 1, 4, 7, 10… до тех пор, пока их произведение не превысит 300 или сумма 200. Выведите количество этих чисел. 3) Организуйте бесконечный цикл вычисляющий факториал числа введенного с клавиатуры. Выход из цикла с помощью break.
Оператор цикла do-while Второй оператор цикла – оператор do-while – имеет вид do оператор while (логВыр); Здесь сначала выполняется оператор, а потом происходит вычисление логического выражения логвыр. Цикл выполняется, пока логвыр остается равным true. Существенное различие между этими двумя операторами цикла заключается в том, что в цикле do-while оператор обязательно выполнится хотя бы один раз. В листинге 1.21 показан вывод чисел кратных 3 в диапазоне от -10 до 10. Листинг 1.21 public class Main { public static void main(String args[]) { int i = -10; do { if (i % 3 == 0) { System.out.println(" i=" + i); } i++; } while (i < = 10); } } Задание: С помощью цикла do-whileсоздайте программу, выводящую на экран первые 10 элементов последовательности 2 4 8 16 32 64 128 ….
Оператор цикла for Третий оператор цикла – оператор for – выглядит так: for ( списокВыр; логВыр; списокВыр2) оператор; Перед выполнением цикла вычисляется список выражений списокВыр1. Это нуль или несколько выражений, перечисленных через запятую. Они вычисляются слева направо, и в следующем выражении уже можно использовать результат предыдущего выражения. Как правило, здесь задаются начальные значения переменным цикла. Затем вычисляется логическое выражение логВыр. Если оно истинно, true, то выполняется оператор, потом вычисляются слева направо выражения из списка выражений списокВыр2. Далее снова проверяется логВыр. Если оно истинно, то выполняется оператор и списокВыр2 и т. д. Как только логВыр станет равным false, выполнение цикла заканчивается. Вместо списокВыр1 может стоять одно определение переменных обязательно с начальным значением. Такие переменные известны только в пределах этого цикла.
for (inti = 0, j=10; i< j; i++, j--){ System.out.println(" i=" +i+", j=" +j); } Любая часть оператора for может отсутствовать: цикл может быть пустым, выражения в заголовке тоже, при этом точки с запятой сохраняются. Можно задать бесконечный цикл: for (;; ) оператор; В этом случае в теле цикла следует предусмотреть какой-нибудь выход. int i=0; for (;; ){ if (i==5) break; i++; System.out.println(i); } Хотя в операторе for заложены большие возможности, используется он, главным образом, для перечислений, когда их число известно, например, фрагмент кода int s=0, N=7; for (int k = 1; k < = N; k++) s += k * k; вычисляет сумму квадратов первых N чисел. В листинге 1.22 показан пример вывода чисел в диапазоне от -10 до 10 с шагом 2. Листинг 1.22 public class Main { public static void main(String args[]) { for (int i = -10; i < = 10; i += 2) { System.out.println(" i=" + i); } } } Задание: 1).С помощью цикла for подсчитайте сумму всех четных чисел в диапазоне от -20 до 20. 2). Выведите все простые числа до 100.
Оператор continue и метки Оператор continue используется только в операторах цикла. Он имеет две формы. Первая форма состоит только из слова continue и осуществляет немедленный переход к следующей итерации цикла. В листинге 1.23 оператор continue позволяет обойти деление на нуль: Листинг 1.23 public class Main { public static void main(String args[]) { for (int i = 0, j = 4, s = 0; i < 5; i++, j--) { if (i == j) { System.out.println(" del na 0 " ); continue; } s = 100 / (i - j); System.out.println(" s = " + s); } } } Листинг 1.24 содержит метку: continue метка; Листинг 1.24 public class Main { public static void main(String args[]) { label: for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { if (i == 5) { continue label; } } System.out.println(i); } } } Метка записывается, как все идентификаторы, из букв Java, цифр и знака подчеркивания, но не требует никакого описания. Метка ставится перед оператором или открывающей фигурной скобкой и отделяется от них двоеточием. Так получается помеченный оператор или помеченный блок. Метка не требует описания и не может начинаться с цифры. Вторая форма используется только в случае нескольких вложенных циклов для немедленного перехода к очередной итерации одного из объемлющих циклов, а именно, помеченного цикла.
Оператор break Оператор break используется в операторах цикла и операторе варианта для немедленного выхода из этих конструкций. Операторbreak меткаприменяется внутри помеченных операторов цикла, оператора варианта или помеченного блока для немедленного выхода за эти операторы. Следующая схема поясняет эту конструкцию: Ml: { // Внешний блок М2: { // Вложенный блок – второй уровень М3: { // Третий уровень вложенности... if (что-то случилось) break M2; // Если true, то здесь ничего не выполняется } // Здесь тоже ничего не выполняется } // Сюда передается управление }
Поначалу сбивает с толку то обстоятельство, что метка ставится перед блоком или оператором, а управление передается за этот блок или оператор. Поэтому не стоит увлекаться оператором break с меткой. В листинге 1.25 показано использование вложенных друг в друга меток. Листинг 1.25 public class Main { public static void main(String args[]) { int i = 3, j = 4; M1: { // Внешний блок int s = i + j; M2: { // Вложенный блок – второй уровень s = i; M3: { // Третий уровень вложенности... if (i < j) { break M2; } // Если true, то здесь ничего не выполняется System.out.println(" level 3 s = " + s); } // Здесь тоже ничего не выполняется System.out.println(" level 2 s = " + s); } // Сюда передается управление System.out.println(" level 1 s = " + s); } } }
1.14.9 Оператор вариантаswitch Оператор варианта switch организует разветвление по нескольким направлениям. Каждая ветвь отмечается константой или константным выражением какого-либо целого типа (кроме long) и выбирается, если значение определенного выражения совпадет с этой константой. Вся конструкция выглядит так. switch (целВыр) { case констВыр1: оператор1; case констВыр2: оператор2; ..... case констВырN: операторN; default: операторDef; }; Стоящее в скобках выражение целВыр может быть типа byte, short, int, char, но не long. Начиная с jdk 1.7 и String! Целые числа или целочисленные выражения, составленные из констант, констВыр тоже не должны иметь тип long. Оператор варианта выполняется так. Все константные выражения вычисляются заранее, на этапе компиляции, и должны иметь отличные друг от друга значения. Сначала вычисляется целочисленное выражение целВыр. Если оно совпадает с одной из констант, то выполняется оператор, отмеченный этой константой. Затем выполняются все следующие операторы, включая и операторDef, и работа оператора варианта заканчивается. Если же ни одна константа не равна значению выражения, то выполняется операторDefи все следующие за ним операторы. Поэтому ветвь default должна записываться последней. Ветвь default может отсутствовать, тогда в этой ситуации оператор варианта вообще ничего не делает. Таким образом, константы в вариантах case играют роль только меток, точек входа в оператор варианта, а далее выполняются все оставшиеся операторы в порядке их записи. После выполнения одного варианта оператор switch продолжает выполнять все оставшиеся варианты. Чаще всего необходимо " пройти" только одну ветвь операторов. В таком случае используется оператор break, сразу же прекращающий выполнение оператора switch. Если необходимо выполнить один и тот же оператор в разных ветвях case, то следует поставить несколько меток case подряд, как показано в листинге 1.26. Листинг 1.26 public class Main { public static void main(String args[]) { for (int dayOfWeek = 1; dayOfWeek < = 8; dayOfWeek++) { switch (dayOfWeek) { case 1: case 2: case 3: case 4: case 5: System.out.println(" Week-day" ); break; case 6: case 7: System.out.println(" Week-end" ); break; default: System.out.println(" Unknown day" ); } } } }
Задание Написать программу, которая по номеру месяца будет определять пору года. Номер месяца вводится с клавиатуры. Предусмотреть проверку на некорректный ввод. Популярное:
|
Последнее изменение этой страницы: 2016-05-30; Просмотров: 680; Нарушение авторского права страницы