Некоммерческая организация «Ассоциация московских вузов»

Государственное образовательное учреждение

высшего профессионального образования

Московский государственный индустриальный университет

ГОУ ВПО МГИУ

Научно-образовательный материал

«Программирование на языке 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