Главная страница
Навигация по странице:

  • Индивидуальные задания

  • Контрольные вопросы

  • Рекомендуемая литература

  • Лабораторная работа 1 2 лабораторная работа 2 31 лабораторная работа 3 44 лабораторная работа 4 74


    Скачать 1.76 Mb.
    НазваниеЛабораторная работа 1 2 лабораторная работа 2 31 лабораторная работа 3 44 лабораторная работа 4 74
    Дата12.03.2021
    Размер1.76 Mb.
    Формат файлаdoc
    Имя файлаOOP_Lab_Rus.doc
    ТипЛабораторная работа
    #184105
    страница3 из 31
    1   2   3   4   5   6   7   8   9   ...   31

    ЛАБОРАТОРНАЯ РАБОТА 2



    Тема: Преобразование и приведение типов. Компиляция программ на языке Java. Чтение консольного ввода. Математические операции.

    Цель: Приобрести практические навыки разработки программных средств на языке java с использованием ввода данных и математических операций.

    Теоретические сведения

    Рассматриваемые вопросы:

    2.1 Преобразование и приведение типов

    2.2 Приведение несовместимых типов

    2.3 Автоматическое расширение типа в выражениях

    2.4 Компиляция программы

    2.5 Чтение консольного ввода

    2.6 Чтение символов

    2.7 Математические операции
    2.1 Преобразование и приведение типов

    При написании программы бывают ситуации, когда присваиваются значения одного типа переменной другого типа. Если два типа совместимы, то Java выполнит преобразование автоматически. Напри­мер, всегда возможно назначить int-значение long-переменной. Однако не все типы совместимы и, таким образом, не все преобразования типов не­явно позволены. Например, не определено никакого преобразования из double в byte. К счастью, все еще возможно осуществить преобразование между несовместимыми типами. Чтобы это сделать, следует использовать специальную операцию приведения типов(cast), которая выполняет явное преобразование между несовместимыми типами.

    Автоматическое преобразование типов в Java

    Когда один тип данных назначается переменной другого типа, будет иметь место автоматическое преобразование типов, если выполняются два следую­щих условия:

    - два типа совместимы;

    - целевой тип больше чем исходный.

    Когда эти два условия выполняются, имеет место расширяющее преобразова­ние (widening conversion). Например, тип int всегда достаточно большой, чтобы содержать все допустимые byte-значения, так что никакой явный оператор приведения не требуется.

    Для расширяющих преобразований числовые типы, включая целый и с пла­вающей точкой, являются совместимыми друг с другом. Однако числовые типы не совместимы с char или boolean. Типы char и boolean не совмес­тимы также и друг с другом. Java выполняет автоматическое преобразование типов при сохранении литеральной целочисленной константы в перемен­ных типа byte, short или long.
    2.2 Приведение несовместимых типов

    Хотя автоматическое преобразование типов полезно, оно не удовлетворяет всем потребностям. Например, как быть, если нужно назначить int-значение byte-переменной? Это преобразование не будет выполнено авто­матически, потому что тип byte меньше, чем int. Данный вид преобразова­ния иногда называется сужающим преобразованием(narrowing conversion), т. к. вы явно делаете значение более узким, чтобы оно вписалось в целе­вой тип.

    Чтобы создавать преобразование между двумя несовместимыми типами, нужно использовать приведение типов. Приведение(cast) — это и есть явное преобразование типов. Оно имеет общий формат:

    (target-type) value

    Здесь target-typeопределяет желаемый тип, к которому следует преобразо­вать указанное value. Например, следующий фрагмент приводит int к byte. Если целое значение больше, чем диапазон byte-типа (256), то оно будет редуцировано по модулю этого диапазона (до остатка от целочисленного деления этого значения на 256).

    int а; byte b; // ...

    b = (byte) a;

    Другой тип преобразований — усечение(trancation), произойдет, когда зна­чение с плавающей точкой назначается целому типу. Целые числа не имеют дробных частей. Таким, образом, когда значение с плаваю­щей точкой назначается целому типу, дробная часть теряется. Например, если значение 1.23 назначается целой переменной, результирующее значе­ние будет просто 1, а 0.23 будет усечено. Конечно, если числовое значение слишком велико, чтобы вписаться в целевой целый тип, то оно будет реду­цировано по модулю диапазона целевого типа.

    Следующая программа демонстрирует некоторые преобразования типов, ко­торые требуют приведений:

    // Демонстрирует приведения типов

    class Conversion {

    public static void main(String args[]) {

    byte b;

    int i = 257;

    double d = 323.142;

    System.out.println("Приведение int к byte"); b = (byte) i;

    System.out.println("i и b " + i + " " + b);

    System.out.println("Приведение double Kint."); i = (int) d;

    System.out.println("d и i " + d + " " + i);

    System.out.println("Приведение double к byte."); b = (byte) d;

    System.out.println("d and b " + d + " " + b);

    }

    }

    Эта программа генерирует следующий вывод:

    Приведение int к byte i и b 257 1

    Приведение double к int d и i 323.142 323

    Приведение double к byte d и b 323.142 67

    Посмотрим на каждое преобразование. Когда значение 257 приводится к byte-переменной, результат — остаток от деления 257 на 256 (диапазон типа byte) в этом случае равен 1. Когда d преобразуется к int, его дробный ком­понент теряется. Когда d преобразуется к byte, его дробный компонент те­ряется, и значение редуцируется по модулю 256, что в этом случае дает 67.

    2.3 Автоматическое расширение типа в выражениях

    В дополнение к операции назначения (присваивания) в выражениях есть и другое место, где могут происходить некоторые преобразования типов — в выражениях.Чтобы увидеть, как и почему это происходит, приведем сле­дующие соображения. В выражении точность, требуемая от промежуточного значения, будет иногда превышать диапазон любого операнда. Например, рассмотрим следующие выражения:

    byte а = 40; byte b = 50; byte с = 100; int d = а * b / с;

    Результат промежуточного выражения а*b превышает диапазон любого из его byte-операндов. Чтобы управлять проблемой этого рода, Java при оценке выражения автоматически расширяет (повышает) тип каждого byte или short операнда до int. Это означает, что подвыражение а*b вычисляется с использованием целых чисел — не байтов. Таким образом, результат 2000 промежуточного выражения 50*40 является законным даже при том, что оба операнда (а и b) определены с типом byte.

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

    byte b = 50;

    b = b * 2; // Ошибка! Невозможно назначить int-значение byte-переменной!

    Во второй строке кода происходит попытка сохранить совершенно правиль­ное byte-значение (50*2) в byte-переменной b. Однако, из-за того что опе­ранды были автоматически расширены до типа int (во время оценки выра­жения), результат также был расширен до int. Таким образом, результат выражения имеет теперь тип int, который не может быть назначен byte-переменной без использования приведения.

    В таком случае следует использовать яв­ное приведение типа:

    byte b = 50;

    b = (byte)(b*2) ;

    что выдает правильное значение 100.
    2.4 Компиляция программы

    ­ Чтобы скомпилировать проrpамму, нужно запустить компилятор (javac), указав имя исходноro файла в командной строке, например:

    C:\>javac Example.java

    Компилятор javac создаст файл Example.class, содержащий байт­кодовую версию программы. Байт­код Java ­ это промежуточное представление программы, содержащее инструкции, которые будет выполнять виртуальная машина java. Следовательно, результат работы компилятора javac не является непосредственно исполняемым кодом.

    Чтобы действительно выполнить программу, необходимо воспользоваться програм­мой запуска приложений java, которая носит имя java. При этом ей потребуется пере­дать имя класса Example в качестве аpгументa командной строки, как показано в следую­щем примере:

    C:\>java Example

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

    Именно поэтому исходным файлам jаvа целесообразно присваивать имена, совпадающие с именами классов, которые они содержат ­ имя исходного файла будет совпадать с име­нем файла с расширением .class. При запуске java описанным способом в командной строке в действительности указывают имя класса, который нужно выполнить. Программа будет автоматически искать файл с указанным именем и расширением .class. Если про­гpaммa найдет файл, она выполнит код, содержащийся в указанном классе.
    2.5 Чтение консольного ввода

    ­В java1.0 единственным способом выполнения консольного ввода было использова­ние байтового потока, и существует большой объем cтapoгo кода, в котором применяется этот подход. Сегодня применение байтового потока для чтения консольного ввода по­ прежнему технически возможно, но поступать так не рекомендуется. Предпочтительный метод чтения консольного ввода ­ это использовать символ-ориентированный поток, что значительно упрощает возможности интернационализации и поддержки разрабатывае­мых программ.

    В java консольный ввод выполняется чтением System.in. Чтобы получить символь­ный поток, присоединенный к консоли, вы должны поместить System.in в оболочку объекта BufferedReader. BufferedReader поддерживает буферизованный входной по­ток. Наиболее часто используемый eгo конструктор выглядит так:

    BufferedReader(Reader iпputReader)

    Здесь inputReader ­ это поток, который связывается с создаваемым экземпляром BufferedReader.Reader ­ абстрактный класс. Одним из его конкретных наследников является InputStreamReader, который преобразует байты в символы. Для получения объекта InputStreamReader, который присоединен к System.in, служит следующий конструктор:

    ­InputStreamReader(InputStream iпputStream)

    Поскольку System.in ссылается на объект типа InputStream, он должен быть ис­пользован как параметр iпputStream. Собрав все вместе, получим следующую строку кода, которая создает BufferedReader, соединенный с клавиатурой:

    BufferedReader br = new BufferedReader(newInputStreamReader(System.in));

    После выполнения этого оператора br представляет собой основанный на символах поток, подключенный к консоли через System.in.

    ­

    2.6 Чтение символов

    ­Для чтения символа из BufferedReader применяется read(). Ниже показана версия read(), которая будет использоваться:

    int read() throws IOException

    Каждый раз, когда вызывается метод read(), он читает символ из входного потока и возвращает eгo как целое значение. При достижении конца потока возвращается ­l. Как видите, метод может возбудить исключение IOException.

    В следующей программе демонстрируется применение read(), читая символы с консоли до тех пор, пока не пользователь не введет "q". Обратите внимание, что любые исключения ввода/­вывода, которые могут быть сгенерированы, просто передаются в main ( ). Такой подход распространен при чтении с консоли, но при желании вы можете обработать ошибки такого рода самостоятельно.

    // Использование BufferedReader для чтения символов с консоли.

    import java.io.*;

    class BRRead {

    public static void main(String args[]) throws IOException

    {

    ­ char с;

    BufferedReader br ­= new BufferedReader(newInputStreamReader(System.in));

    Sustеm.оut.рrintln("Вводите символы, 'q' ­ для выхода.");

    // читать символы

    do {

    с ­ (char) br.read();

    System.out.println(c);

    while(c !­ 'q');

    ­}

    }

    Ниже показан пример запуска этой прогpаммы:

    ­Вводите символы, 'q' ­ для выхода.

    12сq

    1

    2

    с

    ­q

    ­
    2.7 Математические операции

    Класс Маth содержит все функции с плавающей точкой, которые используются в гeo­метрии и тригонометрии, а также некоторые методы общего назначения. В Маth опре­делены две константы double: Е (равную приблизительно 2,72) и РI (равную примерно 3,14).

    Методы, перечисленные в табл. 1, принимают параметр типа double, выражаю­щий угол в радианах и возвращающий результат соответствующей трансцендентной функции.

    Табл.1

    Метод

    Описание

    static double sin (double arg)

    Возвращает синус угла arg, переданного в радианах

    static double cos (double arg)

    Возвращает косинус угла arg, переданного в радианах

    static double tan (double arg)

    Возвращает тангенс угла arg, переданного в радианах

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

    Табл. 2

    Метод

    Описание

    static double asin (double arg)

    Возвращает угол, синус которого равен arg.

    static double acos (double arg)

    Возвращает угол, косинус которого равен arg.

    static double atan (double arg)

    Возвращает угол, тангенс которого равен arg.

    static double atan2 (double x,double у)

    Возвращает угол, тангенс которого равен х/у.


    В классе Math определен набор экспоненциальных методов, которые описаны в табл. 3.

    Табл. 3.

    Метод

    Описание

    static double cbrt (double arg)

    Возвращает кубический корень из arg.

    static double exp (double arg)

    Возвращает экспоненту arg.

    static double expml (double arg)

    Возвращает экспоненту arg-1.

    static double log (double arg)

    Возвращает натуральный алгоритм arg.

    static double loglO (double arg)

    Возвращает логарифм по основанию 10 от arg.

    static double loglp (double arg)

    Возвращает натуральный алгоритм arg+l.

    static double pow (double y, double x)

    Возвращает у в степени х

    static double scalb(double arg, int factor)

    Возвращает arg х 2factor

    static float scalb(float arg, int factor)

    Возвращает arg х 2factor

    static double sqrt (double arg)

    Возвращает квадратный корень из arg.


    В классе Math определены некоторые методы, которые предназначены для выпол­нения различного рода операций округления. Они перечислены в табл. 4. Обратите внимание на два метода ulp () в конце таблицы. В данном контексте "ulp" означает "units in the last place" (единицы на последнем месте). Это указывает число единиц между зна­чением и ближайшим большим значением. Это можно использовать для получения точ­ности результата.

    Табл. 4

    Метод

    Описание

    static int abs (int arg)

    Возвращает абсолютное значение arg.

    static double сеil (double arg)

    Возвращает наименьшее целое число, которое больше arg.

    static double floor(double arg)

    Возвращает наибольшее целое число, которое меньше или равно arg.

    static int тах (int х, int у)

    Возвращает большее из двух чисел х и у.

    static int rnin (int х, int у)

    Возвращает меньшее из двух чисел х и у.

    static double rint (double arg)

    Возвращает ближайшее целое к arg.

    static int round (float arg)

    Возвращает arg, округленное вверх до ближайшего int.

    static float ulp (float arg)

    Возвращает ulp для arg.


    В дополнение к методам, приведенным в таблицах выше, в Math определено еще не­сколько методов, которые перечислены в табл. 5.

    Табл. 5

    Метод

    Описание

    static int getExponent (float arg)

    Возвращает экспоненту по основанию 2, ис­пользуемую для двоичного представления arg.

    static double IEEEremainder(double dividend, double divisor)

    Возвращает остаток от деления divident/

    divisor.

    static double toDegrees(double angle)

    Преобразует радианы в градусы. Переданный в angle уrол должен быть указан в радианах.

    Возвращается результат в градусах.

    static double toRadians(double angle)

    Преобразует градусы в радианы.



    В следующей программе демонстрируется использование toRadians() и toDegrees().

    // Демонстрация применения toDegrees() и toRadians().

    class Angles {

    public static void main(String args[]) {

    double theta = 120.0;

    System.out.println(theta + " градусов равно " +Math.toRadians(theta) + " радиан.");

    theta = 1.312;

    System.out.println(theta + " радиан равно " +Math.toDegrees(theta) + " градусов.");

    Вывод этой программы показан ниже:

    120.0' градусов равно 2.0943951023931953 радиан.

    1.312 радиан равно 75.17206272116401 радиан.
    Индивидуальные задания

    Написать программу на java для вычисления выражения, используя консольный ввод/вывод:

    1. y= ;

    2. y= ;

    3. y= ;

    4. y= ;

    5. y= ;

    6. y= ;

    7. y= ;

    8. y= ;

    9. y= ;

    10. y= ;

    11. y= ;

    12. y= ;

    13. y= ;

    14. y= ;

    15. y= ;

    16. y= ;

    17. y= ;

    18. y= ;

    19. y= ;

    20. y= .

    Контрольные вопросы

    1. При каких условиях выполняется автоматическое преобразование типов?

    2. Для чего нужно приведение типов?

    3. Приведите пример программы автоматического расширения типов с пояснением.

    4. Почему исходным файлам jаvа целесообразно присваивать имена, совпадающие с именами классов?

    5. Приведите пример программы чтения символов с консоли.

    6. Какие экспоненциальные методы определены в классе Math?

    7. Какие методы определены в классе Math для округления?

    8. Какие методы определены в классе Math для перевода из градусов в радианы и из радиан в градусы? Приведите пример.

    Рекомендуемая литература

    Основная литература

    1. Шилдт Г., Ноутон П. Java 2. Наиболее полное руководство, 2001.

    2. Павловская Т.А., Щупак Ю.А. C++. Объектно-ориентированное программирование. Практикум. СПб. Питер, 2006.

    3. Г.Шилдт. Полный справочник по Java SE6 2007.

    4. Б.Эккель. Философия Java (4е издание), 2009.

    5. К. Арнольд, Д. Гослинг. Язык программирования Java. Питер Пресс, Санкт-Петербург, 1997.

    Дополнительная литература

    1. М. Эферган Java: справочник .- QUE Corporation, 1997, Издательство "Питер Ком", 1998

    2. Д. Вебер Технология Java в подлиннике .- QUE Corporation, 1996, "BHV-Санкт-Петербург",1997.

    3. Н. Бартлетт, А. Лесли, С. Симкин Программирование на Java. Путеводитель .- The Coriolis Group,Inc.,1996, Издательство НИПФ "ДиаСофт Лтд.",1996

    4. К. Джамса Библиотека программиста Java .- Jamsa Press, 1996, ООО "Попурри", 1996

    5. К. Арнольд, Д. Гослинг Язык программирования Java .- Addison-Wesley Longman,U.S.A.,1996, Издательство "Питер-Пресс", 1997.


    1   2   3   4   5   6   7   8   9   ...   31


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