Некоммерческая организация «Ассоциация московских вузов»
Государственное образовательное учреждение
высшего профессионального образования
Московский государственный индустриальный университет
ГОУ ВПО МГИУ
Научно-образовательный материал
«Программирование на языке Java»
Состав научно-образовательного коллектива:
, к. т.н., профессор
, ведущий инженер
Москва 2010 г.
Программирование на языке Java
Java — язык ООП. В информатике и программировании изменения происходят постоянно и с большой скоростью. Одним из самых значительных изменений за последние двадцать лет стало появление общемировой сети Интернет и языка программирования Java. Важнейшими свойствами этого языка, называемого даже революционным, являются следующие:
• Java является современным объектно-ориентированным языком;
• Java предоставляет программисту богатый набор классов различных объектов;
• Java позволяет создавать аплеты, являющиеся небольшими, надежными, динамичными и не зависящими от платформы сетевыми приложениями, которые встраиваются в веб-страницы сети Интернет.
Выбор этого языка в качестве базового для нашего курса обусловлен прежде всего наличием у него таких качеств, как простота и мощь, безопасность, объектная ориентированность, надежность, интерактивность, архитектурная независимость, возможность интерпретации, высокая производительность и легкость в изучении. Часть из них нам понадобится с первых же шагов, другие — несколько позже.
Объектно-ориентированное программирование настолько интегрировано в Java, что написание даже простейших программ требует знания основных принципов ООП. Хотя в первой части курса мы и не собираемся акцентировать внимание на них, общее представление об основах объектно-ориентированного подхода необходимо иметь уже сейчас.
Объектно-ориентированное программирование представляет собой технологию программирования, в основе которой лежит способность человека обобщать, классифицировать и генерировать абстракции. Концепция ООП базируется на таких понятиях как объекты и классы. В повседневной жизни объекты встречаются на каждом шагу: компьютеры, телефоны, машины, дома, чашки и многое другое. В программировании это могут быть символы, числа, строки, а также объекты, придуманные и реализованные автором программы.
Важно то, что объекты — это не только некоторые значения (данные). В них также имеются методы, связывающие данные и управляющие ими.
Объекты представляют собой объединение структур данных, содержащих информацию, и методов и функций для управления этими данными.
Произвольный объектно-ориентированный язык программирования характеризуют три основных свойства:
• инкапсуляция, т. е. совмещение данных с функциями (методами), предназначенными для манипулирования этими данными, в одном объекте, сопровождающееся сокрытием его внутренней структуры от внешнего мира; в языке Java это достигается путем введения механизма классов;
• наследование, т. е. создание новых, производных классов, на базе уже имеющихся, которые наследуют данные и методы от ранее определенных базовых классов; при этом возможно переопределение или добавление новых данных и методов; в результате создается так называемая иерархия классов;
• полиморфизм, т. е. наличие у разных классов методов с одним и тем же именем, в результате чего каждый из классов имеет возможность по-своему выполнять связанные с этим методом действия.
Более полную информацию, связанную с объектно-ориентированным программированием, можно почерпнуть из уже упоминавшейся книги и замечательной, хотя и сложной для новичка. В нагнем же курсе мы вернемся к этому вопросу в третьей главе.
Основные свойства программ и первые примеры. Перед тем, как перейти непосредственно к примерам программ, обсудим вопрос о том, какими качествами должна обладать хорошая программа.
Оказывается, что таких свойств достаточно много: корректность, эффективность, удобство эксплуатации, надежность, удобство сопровождения, понятность и еще целый ряд других. Тремя самыми главными из них являются корректность или правильность, эффективность и понятность и модифицируемость.
Так как программа на языке Java является просто записью алгоритма решения определенной задачи, прежде всего она должна быть правильной, то есть реализующей корректный алгоритм решения исходной задачи. Оказывается, что не так просто не только научиться писать правильные программы, но даже и просто сформулировать, что это такое. Только в §6, после предварительного изучения основ теории предикатов, мы сможем дать точное определение понятию правильная программа.
Свойства понятности и модифицируемости программ связаны самым тесным образом: очень трудно изменить программу, которую не понимаешь. В реальной жизни программиста задачи на модификацию уже написанных кем-то ранее программ встречаются едва ли не чаще, чем задачи на разработку программ с нуля. Решение задач на модификацию является также и весьма эффективным способом изучения как языка, так и методов программирования.
Научиться писать понятные и легко модифицируемые программы существенно легче, чем правильные и эффективные. Для этого достаточно только соблюдать несколько простых общих правил, которые мы сформулируем в применении к языку Java:
• используйте в программе осмысленные имена для всех переменных, отличных от счетчиков и других подобных величин;
• всем константам, отличным от нуля и единицы, присваивайте имена;
• соблюдайте принятый в языке стиль написания имен (имена классов должны начинаться с прописной буквы, переменных и методов — со строчной, констант — состоять полностью из прописных букв);
• применяйте разумное форматирование текста программы;
• там, где это необходимо, используйте комментарии.
Программа на языке Java пишется в обычном текстовом файле, содержащем в себе определения одного или нескольких классов. Имя файла обязано совпадать с именем основного класса, определенного в нем, и иметь расширение Java. Компилятор, запускаемый обычно с помощью команды javac Filename. Java, при отсутствии ошибок компиляции порождает один или несколько выходных файлов с именами, совпадающими с именами содержащихся в исходном файле классов, и расширением class. Для запуска откомпилированной программы после этого необходимо выполнить команду Java Filename.
В соответствии с давно установившейся традицией рассмотрим в качестве первой задачи следующую.
ЗАДАЧА. Напишите программу, выводящую на экран строку текста Здравствуй, мир!.
Текст программы.
public class Hello {
public static void main(String[] args) {
System. out. printIn("Здравствуй, мир!"); } }
Приведенный выше текст обязательно должен содержаться в файле с именем Hello .Java (обратите внимание на то, что первая буква в имени является прописной, а остальные — строчными).
Как и большинство других языков, Java допускает произвольное форматирование текста программы. Это означает, что любую программу в принципе можно записать в одну длинную строку или, наоборот, максимально растянуть по вертикали, размещая на каждой строке только по одной лексеме — минимальной неделимой единице языка. Приведенная выше программа состоит из следующей цепочки лексем: ключевые слова public, class, идентификатор Hello, разделитель {, ключевые слова public, static и void, идентификатор main, разделитель (, идентификатор String, разделители [ и ], идентификатор args, разделители ) и {, идентификатор System, разделитель., идентификатор out, разделитель., идентификатор println, разделитель (, строковый литерал "Здравствуй, мир!", разделители ), ;, и дважды }. Данная программа не содержит лексем только еще одного типа, существующего в языке — констант, примером которой является, скажем, число 5.
Человек, однако, не машина, и ему далеко не безразлично, как отформатирован текст программы. Неудачное форматирование существенно усложняет правильное восприятие текста и порождает потенциальные ошибки. Не обсуждая сейчас вопрос о том, какой именно стиль форматирования программ на языке Java является наиболее правильным, мы призываем читателя следовать тем образцам, которые он найдет в книге — они предлагают заведомо не самый плохой вариант.
Запомните, что в языке Java существует около шести десятков зарезервированных ключевых слов, которые имеют вполне определенное значение и не могут быть использованы для иных целей, кроме тех, для которых они предназначены.
Последовательное выполнение двух команд javac Hello. Java и Java Hello должно привести к тому, что на экране появится результат работы программы — строка Здравствуй, мир!
Мы не будем приводить подробный разбор того, каков смысл отдельных частей рассмотренной программы, — этот комментарий можно найти в любой книге по языку Java. Вместо этого мы обсудим решение следующей задачи, в которой будут использованы методы уже анонсированного выше класса Xterm.
ЗАДАЧА. Напишите программу, печатающую на экране красивое поздравление с новым учебным годом.
Текст программы.
public class NewYear { // magic!
public static void main(String[] args) { Xterm. clear(); Xterm. setPosition(25,8); Xterm. print("С новым годом ", Xterm. Red); Xterm. print("(учебным)", Xterm. Blue); Xterm. print("!*', Xterm. Red); Xterm. setPosition(0,16); /*
Конец программы */ } }
В этой программе используются два вида комментариев из трех, существующих в языке Java. Текст, расположенный после символов // вплоть до конца строки, и произвольное количество строк текста между символами /* и */, компилятором просто игнорируются. Знакомство с третьим видом комментариев, предназначенным для автоматического документирования программ, отложим до третьей главы книги. Второй из комментариев, включенных в приведенную выше программу, является типичным примером комментария, ухудшающего код. Не включайте в свои программы бесполезные комментарии!
Некоторые фрагменты этой (и многих последующих) программы обсуждаться до начала третьей главы не будут. Только тогда, после полноценного знакомства с основными концепциями объектно-ориентированного программирования на языке Java, можно будет разобраться с тем, что же означает строка public static void main(String[] args). Пока мы будем просто считать, что так надо!
Содержательная же часть приведенной программы (тело функции main, т. е. текст, расположенный между внутренними фигурными скобками) сейчас будет подробно разобрана. Рекомендуется откомпилировать и запустить эту программу для того, чтобы увидеть результат ее работы, — это поможет лучше понять ее. При этом следует иметь в виду, что кроме файла NewYear. java в данном случае необходим еще и файл Xterm. Java (его содержимое приведено для справки в последней секции данного параграфа на странице 34).
Объект, с которым ведется работа в программе, — Xterm. Подробно он рассматривается чуть ниже (см. стр. 26), а пока отметим только то, что он определяет терминал, обеспечивающий ввод чисел и вывод строк текста. Объект Xterm содержит в себе некоторую информацию или, как говорят находится в некотором состоянии. Состояние характеризуется тем текстом, который отображается в окне терминала, и положением курсора, отвечающего за позицию, в которой появится очередной выводимый символ.
На самом деле в классе Xterm нет компонент, содержащих указанную информацию (она хранится совсем в другом объекте), однако подобное упрощение реальной ситуации является весьма удобным.
Множество всех состояний, в которых может находиться объект, называется пространством состояний. По отношению к объекту могут быть выполнены некоторые, заранее определенные действия — методы (methods), а процесс выполнения этих действий называют вызовом метода. В результате этих действий состояние объекта может измениться.
В языке Java для вызова метода необходимо сначала указать объект, к которому применяется тот или иной метод, а затем после точки записать имя метода. Именно этот синтаксис, в котором главная роль отводится объекту, над которым производится действие, послужил основой для названия парадигмы — «объектно-ориентированная».
Некоторые из методов требуют для своего выполнения указания дополнительных объектов. Такие дополнительные объекты называют параметрами или аргументами и перечисляют их через запятую в круглых скобках после имени метода. В случае метода без параметров скобки тем не менее обязательны. Завершается любой оператор в языке Java точкой с запятой.
Рассматриваемая программа содержит вызов трех различных методов класса Xterm: clear, setPosition и print. Первый из них очищает окно терминала и не имеет параметров, второй перемещает курсор в позицию, задаваемую параметрами метода, а третий позволяет вывести строку текста. При этом первый параметр метода print определяет выводимую строку, а второй задает цвет символов.
Все встретившиеся в данной программе методы не возвращают значений, однако это вовсе не является обязательным. Метод может возвращать в качестве результата своей работы объект произвольного типа с помощью оператора return.
Типы, переменные и операторы. Типы данных в языке Java подразделяются на простые (primitive) и ссылочные (reference). К простым относятся величины логического типа boolean, символьного char, целых
типов byte, short, int и long, и типов для представления действительных чисел float и double. Ссылочные типы позволяют работать с объектами и массивами.
Множество всех объектов с одинаковым пространством состояний и одинаковым набором методов называется классом (class). Почти все, с чем приходится иметь дело в языке Java, — это объекты различных классов.
Логический тип предназначен для хранения величин, имеющих значения False (Ложь) или True (Истина), а символьный тип позволяет хранить многочисленные символы различных алфавитов всех народов мира. Особенностям представления числовых типов и работе с ними посвящен следующий параграф.
Для работы с объектами, массивами и сущностями простых типов используются переменные (variables). Присваивание переменной какого-то значения, содержащегося в некоторой другой переменной, результата вызова метода или вычисленного выражения, осуществляется с помощью оператора присваивания =.
В языке Java все переменные должны быть описаны, т. е. для каждой переменной в программе до ее первого использования должно присутствовать ее определение. Общий вид определения переменных таков:
тип идентификатор [= значение] [, идентификатор [= значение ]...];
Описание переменной определяет ее тип и имя (идентификатор). Имя представляет из себя последовательность из букв, цифр, символов подчеркивания и доллара, причем первый символ не может быть цифрой, а прописные и строчные буквы различаются.
Квадратные скобки в приведенной записи означают фрагменты, которые могут быть опущены. В частности, переменная может быть объявлена без присваивания ей начального значения (инициализации). В языке Java все такие переменные автоматически инициализируются нулем.
Java — строго типизированный язык. Это, в частности, означает, что переменной одного типа, вообще говоря, нельзя присвоить значение другого типа — несовпадение типов приведет к сообщению об ошибке на этапе компиляции. Для каждого типа строго определены наборы допустимых значений и разрешенных операций. Например, для типов int и double операция сложения определена, а для типа boolean — нет.
Из приведенного правила есть исключения. В языке Java производится автоматическое преобразование, например, целых чисел в действительные. В приведенном ниже примере обе переменные будут проиници-ализированы единицей, причем для переменной g при этом произойдет преобразование целого числа один в действительное (что именно это значит, описано в следующем параграфе):
double f = 1.0, g = 1;
Обратное преобразование (из действительного числа в целое) в языке Java автоматически произойти не может, так как это может повлечь за собой искажение исходного значения. В тех ситуациях, когда действительно необходимо выполнить подобную операцию (найти целую часть числа), необходимо воспользоваться оператором преобразования типа:
double f = 1.1;
int n = (int) f, m = (int) (f + 0.8);
Для преобразования типа переменной или какого-то выражения необходимо перед ним указать в круглых скобках новый тип. В приведенном выше примере обе целочисленные переменные (ш и п) окажутся равными единице.
Кроме уже встретившихся операторов вызова метода, присваивания и преобразования типа в языка Java определен целый ряд других. Операторы бывают унарными (с одним аргументом), бинарными (с двумя) и тернарными (с тремя). Большинство операторов языка Java являются бинарными: к ним относятся, например, операции сложения и умножения чисел. Унарные операторы подразделяются на префиксные и постфиксные, а тернарный оператор в языке всего один.
Существует и другая классификация операторов: они делятся на арифметические, битовые, операторы отношения и логические. Арифметические и битовые операторы разбираются в §4 после знакомства с представлением чисел в ЭВМ, а логические операторы и операторы отношения — в конце текущего параграфа.
Использование класса Xterm. Методы clear и setPosition этого класса были полностью описаны ранее, а вот об уже встречавшемся методе print было рассказано далеко не все. Начнем с того, что в классе Xterm имеется целых три метода с именем print: с одним, двумя и тремя аргументами. Первый аргумент — выводимая строка, второй (в случае его наличия) определяет цвет символов, а третий (если он есть) — цвет фона. Второй и третий аргументы являются просто целыми числами, которым для удобства использования присвоены символические имена:
public static final int Black = 0:
public static final int Red = 1
public static final int Green = 2
public static final int Yellow = 3
public static final int Blue = 4
public static final int Magenta = 5
public static final int Cyan = 6
public static final int White = 7
Класс Xterm дает возможность выводить только строки, но язык Java
позволяет легко преобразовывать данные всех простых типов в строковое
представление. Самым простым способом является использование опера
тора + с первым операндом, являющемся строкой. Оператор + является
полиморфным и выполняется различным образом для чисел и строк:
2+2 //4
"i = " + "с" | // "i = с" |
"i = " + 2 | // "i = 2" |
их = " + (3./2.) | // "х = 1. |
,|Н + (3./2.) // "1.5"
2 + "i = " // Ошибка!
Используя этот оператор и метод print класса Xterm, можно выводить значения переменных любого из простых типов. Полезно знать, что "" обозначает пустую строку, а печать "\п" приводит к тому, что курсор терминала перемещается в начало следующей строки.
Для того чтобы не добавлять постоянно к выводимой строке "\п", можно пользоваться методами print In, действие которых в остальном совершенно аналогично работе методов print.
Оставшиеся неразобранными методы класса Xterm предназначены для ввода целых и действительных чисел. Они позволяют работать в величинами типов int, long, float и double. Их имена вполне естественны: input Int, input Long, inputFloat и inputDouble соответственно. Все эти методы возвращают в качестве результата введенное число, если только в процессе ввода не произошла какая-либо ошибка. При этом предполагается, что за один раз может быть введено только одно число, и ввод завершается нажатием на клавишу Enter
Аналогично работает и метод input Chars, позволяющий осуществить ввод строки символьной информации, размещая ее в массиве символов.
Исключительная ситуация возникает, например, в случае ошибочного или целенаправленного ввода буквенных или управляющих символов, а также при вводе пустой строки. Про работу с исключительными ситуациями будет рассказано позже (стр. 75), а пока необходимо запомнить, что в том случае, когда программа использует ввод чисел, строку
public static void main(String[] args) следует заменить на
public static void main(String[] args) throws Exception
Все четыре метода ввода чисел и метод ввода строки символов, определенные в классе Xterm, являются перегруженными (overload). Перегрузка методов — это своеобразное проявление полиморфизма, когда два или более различных методов имеют одно и то же имя и различаются только
количеством или типами аргументов. Методы ввода класса Xterm позволяют указывать в качестве аргумента строку, которая будет выведена в качестве подсказки. Это весьма удобно, так как позволяет при выполнении программы явно увидеть, когда именно следует вводить ту или иную информацию.
Использование класса Xterm для организации операций ввода/вывода будет проиллюстрировано при решении следующей задачи.
ЗАДАЧА. Напишите программу, вводящую два целых числа а и Ъ, печатающую их, затем обменивающую значения этих переменных (так, чтобы новое значение а стало равно старому значению Ь, и наоборот) и вновь их печатающую.
Текст программы.
public class Change {
public static void main(String[] args) throws Exception { int a = Xterm. inputInt("Введите первое число -> "); int b = Xterm. inputInt("Введите второе число -> "); Xterm. printIn("До обмена: a = " + a + "; b = " + b);
int с = a; a = b; b = c;
Xterm. printIn("Поеле обмена: a = " + a + "; b = " + b);
}
}
Эта программа использует третью переменную с для того, чтобы сохранить в ней начальное значение переменной а, которое иначе оказалось бы утерянным при выполнении оператора присваивания а = b;. Попробуйте придумать какой-либо способ обменять значения двух переменных без введения третьей.
Логические и условные операторы. Все программы, которые мы писали до сих пор, были линейными, т. е. все действия в них выполнялись последовательно именно в том порядке, в котором в них располагались операторы. Иногда, однако, требуется опускать или многократно повторять некоторые из них. Делать это позволяют управляющие конструкции языка Java, к которым принадлежат условные операторы, операторы циклов и операторы обработки исключений. С первыми из них мы познакомимся в этом параграфе, а циклы и исключения отложим до § 5.
Простейшими конструкциями, предназначенными для изменения порядка выполнения операторов, являются условные операторы if, if-else
и switch. Применение первых двух из них требует использования логических выражений и логических операторов, к рассмотрению которых мы сейчас и перейдем.
Подробному изложению основ теории предикатов (именно так называют по-научному логические выражения) посвящен следующий параграф, а сейчас ограничимся некоторой минимальной информацией. Любые объекты одного и того же типа можно сравнивать на равенство и неравенство — первый из операторов обозначается в языке Java символами ==, а второй — с помощью символов! =. Стандартные математические обозначения для них — это = ж ф соответственно.
Следует помнить, что при использовании этих операторов для величин ссылочных типов, проверяется факт равенства (или неравенства) ссылок, а не содержимого объектов. Сравнение на равенство двух экземпляров совершенно одинаковых объектов, в частности, даст результат F.
Объекты числовых типов можно сравнивать между собой также и с помощью таких операторов, как < (меньше), <= (меньше или равно), > (больше) и >= (больше или равно), математическими обозначениями для которых являются <, ^, > и ^.
Из простейших логических выражений, к которым относятся логические переменные и результаты сравнений, можно конструировать более сложные, используя следующие логические операторы: унарный оператор отрицания !, бинарные операторы логического И (And) &, логического Или (Or) |, исключающего Или (si Хог) ", равенства ==, неравенства !=, условного И (short circuit And) && и условного Или (short circuit Or) I I, а также тернарный оператор условия ?:.
В математической теории исчисления предикатов отрицание принято обозначать символом -< (или просто!), операторам логического Или и И соответствуют дизъюнкция V и конъюнкция Л, а равенство (эквивалентность) обозначают символами - Ф4>, = или просто =.
Отрицание логического выражения, имеющего значение F (Ложь), есть Т (Истина), и наоборот. Дизъюнкция истинна, если истинен хотя бы один из ее аргументов, а конъюнкция — только при истинности обоих. Исключающее Или истинно тогда и только тогда, когда истинен ровно один из аргументов, а назначение и истинность остальных логических операторов будут описаны чуть позже.
Управляющая конструкция if-else в зависимости от значения логического выражения позволяет выполнять различные части программного кода. В общей форме этот оператор записывается следующим образом: if (логическое_выражение) блок!; [ else блок2; ]
Если условие, задаваемое заключенным в круглые скобки логическим выражением истинно, то будет выполняться блок1, иначе — блок2. Часть else может и отсутствовать.
Управляющие конструкции if и if-else могут быть вложенными, и с помощью блока (block) (заключения нескольких операторов в фигурные скобки) позволяют помещать в каждую из двух своих ветвей произвольное число операторов. Это позволяет разделить поток управления программы на произвольное число частей.
Эту же задачу часто удобнее решать с помощью оператора switch, общий вид которого таков:
switch (выражение) { case значение!.:
блок 1;
break; case значение2:
блок 2;
break;
case значениеЫ: блокЫ; break; default: блок N+1; }
Выражение, которое должно иметь целочисленный тип, сравнивается со всеми значениями (тоже целочисленными), указанными после ключевых слов case. Если оно оказывается совпадающим с одним из них, то управление передается соответствующему блоку операторов, а если совпадения не обнаруживается, то управление передается блоку default (если таковой существует, ибо он не является обязательным). После выполнения того блока, на который было передано управление, оператор break вызывает завершение выполнения оператора switch. При отсутствии оператора break управление просто будет передано следующему блоку за только что выполненным.
Рассмотрим использование описанных операторов на примере решения следующих несложных задач.
ЗАДАЧА. Напишите программу, вводящую три целых числа, и печатающую максимальное из них.
Текст программы.
public class MaxVal3 {
public static void main(String[] args) throws Exception { int a = Xterm. inputInt("Введите первое число -> "); int b = Xterm. inputInt("Введите второе число -> "); int с = Xterm. inputInt("Введите третье число -> "); int max;
if (a > b) max = a; else max = b; if (c > max) max = c;
Xterm. printIn("Максимальное число из введенных = "+max);
}
}
В этой программе переменной max сначала присваивается максимальное значение из двух чисел — а и Ь, а затем, если третье число с больше этой величины, переменной max присваивается его значение.
Использование вложенных управляющих конструкций иллюстрирует программа, решающая следующую задачу.
ЗАДАЧА. Напишите программу, вводящую три целых числа, и печатающую количество максимальных среди введенных чисел.
Для экономии места приведем только содержательную часть решения этой задачи.
Фрагмент программы (NumMaxVal3vl. java). int nMax;
if (а == b) {
if (а == с) nMax = 3;
else {
if (а > с) nMax = 2; else nMax = 1; } } else {
if (а > b) {
if (а == с) nMax = 2; else nMax = 1; } else {
if (b == с) nMax = 2; else nMax = 1; } }
Xterm. printIn("Количество максимальных чисел = " + nMax);
Приведенная программа является достаточно громоздкой. Гораздо понятнее следующее решение той же задачи.
Фрагмент программы (NumMaxVal3v2. java).
if (а > b) max = a;
else max = b;
if (c > max) max = c;
if (a == max) nMax += 1 if (b == max) nMax += 1 if (c == max) nMax += 1
Xterm. printIn("Количество максимальных чисел = "
Здесь мы сначала определяем максимальное по величине число, а затем просто считаем количество равных этому значению величин. Следующая задача является более простой, но она позволит нам проиллюстрировать работу с логическими операторами.
ЗАДАЧА. Напишите программу, вводящую три целых числа, и печатающую Yes в том случае, если среди введенных чисел есть одинаковые, и No — иначе.
Текст программы.
public class Equal3vl {
public static void main(String[] args) throws Exception { int a = Xterm. inputInt("Введите первое число -> "); int b = Xterm. inputInt("Введите второе число -> "); int с = Xterm. inputInt("Введите третье число -> ");
if ( (a == b) || (a == c) || (b == c) )
Xterm. printIn("Yes"); else
Xterm. printIn("No"); } }
Обратите внимание, что в данной программе использованы операторы условного Или | |, а не логического Или \. Это вполне типично — операторы логического Или | и логического Л & на практике не используют — вместо них применяют условные операторы | | и &&.
Как это следует из определений, если первый операнд дизъюнкции истинен, то независимо от значения второго операнда результатом будет истина. Аналогично в случае конъюнкции при ложном первом операнде значение второго операнда на результат не влияет — он всегда будет
ложным. При выполнении условных операторов | | и && исполняющая система Java не производит оценку второго операнда логического выражения, если результат ясен из значения первого операнда. Иногда это просто ускоряет вычисления, а иногда позволяет добиться и большего, как, например, в следующем программном фрагменте. if (а==0 || Ъ/а > 0) х = у;
При а = 0 второй операнд оператора I I вычисляться не будет и деления на ноль не произойдет, как это было бы в случае использования логического оператора Или \.
Можно изменить проверяемое условие среди чисел есть равные в рассмотренной выше программе на его отрицание среди чисел нет равных и переписать программу, заменяя оператор Или на И.
Фрагмент программы (Equal3v2. j ava).
if ( (а!= b) ftft (а!= с) && (Ъ!= с) )
Xterm. printIn("No"); else
Xterm. printIn("Yes");
При решении рассматриваемой задачи можно обойтись без условных операторов, если вспомнить, что произведение чисел равно нулю тогда и только тогда, когда одно из них нулевое. Это позволяет написать следующую программу.
Фрагмент программы (Equal3v3. j ava).
if ((а-Ъ)*(Ъ-с)*(с-а) != 0)
Xterm. printIn("No"); else
Xterm. printIn("Yes");
И, наконец, заметим, что программа запишется короче, если заменить в ней оператор if-else на тернарный оператор условия?:, общая форма записи которого имеет следующий вид: выражение1 ? выражение2 : выражениеЗ
Если результат вычисления первого выражения истинен, то выполняется выражение2 (второй операнд), а иначе — выражениеЗ (третий операнд) . При использовании этой конструкции два последних ее выражения должны иметь один и тот же тип, в данном случае — строковый.
Фрагмент программы (Equal3v4. j ava).
Xterm. printIn( (a-b)*(b-c)*(c-a) != 0 ? "No" : "Yes" );
Задачи для самостоятельного решения.
ЗАДАЧА. Напишите программу, вводящую два целых числа а и Ъ, печатающую их, затем обменивающую значения этих переменных (так, чтобы новое значение а стало равно старому значению Ь, и наоборот) и вновь их печатающую, которая не использовала бы иных переменных, кроме а и Ъ.
ЗАДАЧА. Напишите программу, вводящую три целых числа, и печатающую второе по величине, если оно существует, и No — иначе.
ЗАДАЧА. Напишите программу, вводящую действительное число, которая рассматривает это число, как координаты точки на прямой, и печатает расстояние от этой точки до отрезка [0,1].
ЗАДАЧА. Напишите программу, вводящую три целых числа, и печатающую с использованием всех возможностей класса Xterm как сами числа, так и их среднее арифметическое.
ЗАДАЧА. Напишите программу, вводящую действительные коэффициенты а, Ь и с квадратного уравнения ах2-\-Ьх-\-с = 0 с положительным дискриминантом, находящую оба корня этого уравнения.
7. Реализация класса Xterm. Эта секция содержит для справки про
граммную реализацию класса Xterm, который мы будем активно исполь
зовать всю первую половину нашего курса.
import j ava. io.*;
// Класс, обеспечивающий вывод строк текста с возможностью // позиционирования и использования цветов, а также ввод чисел // целых типов int и long и вещественных float и double. public class Xterm {
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 |


