T.M. SoftStudio

feci quod potui, faciant meliora potentes

Купить полную версию курса "Введение в вычисления с Java" (русскоязычная версия, лекции, тесты, лабораторные работы)

Введение в вычисления с Java. Основы программирования

Неделя 2

Лекция 9

Выражения

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

Существует два типа выражений – арифметические выражения и логические выражения.

Примером арифметического выражения может служить вычисление окончательной оценки как взвешенной суммы оценок, как мы видели в программе courseGrade.

Примером логического выражения может служить действие проверки студента на получение оценки.

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

Арифметическое выражение это последовательность операндов, включающих переменные и константы или литералы, соединенные арифметическими операторами, такими как +, -, * & / .

Мы уже обсуждали переменные и константы.

Первым примером здесь будет использование литералов.

Арифметическое выражение 2+3 соединяет два литерала 2 и 3, используя оператор сложения.

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

с*9/5+32

с (Цельсий) это переменная, 9, 5 и 32 – литералы, и литералы соединены тремя операторами *, / и +.

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

Вы узнаете, что я имею в виду, когда мы будем говорить о делении целых чисел.

Так что вы видите, что литерал – это константное значение, которое появляется непосредственно в Java программе.

Существует два типа численных литералов в Java – целочисленные литералы и литералы с плавающей запятой.

Здесь некоторые примеры литералов.

Заметьте, что для переменной aFloat значение установлено 10.0f с суффиксом f после 10.0 – это потому, что литерал с плавающей запятой 10.0 представлен как double 64 bit, в то время как float имеет размер 32 bit.

Присвоение double в float ведет потенциально к потере информации, и Java компилятор будет жаловаться, если суффикс f отсутствует.

Я поговорю о преобразовании типов позже.

Также присвоение 1000 в byte, который может содержать только целое значение до 128, приведет к ошибке компиляции, потому что литерал слишком большой, чтобы поместиться в переменную.

Здесь общераспространенные арифметические операторы.

Операторы +, - и * довольно простые, однако оператор деления целых чисел слегка хитрый.

Например, если 2 разделить на 3, результат будет 0.

Оператор модуля, который представлен знаком процентов, дает остаток от деления первого операнда на второй операнд.

Например, 2 модуль 3 возвращает 2 как результат.

Оператор модуля в Java работает также для чисел с плавающей запятой.

Рассмотрим другой пример использования оператора модуля.

Когда переменная со значением 104 делится на другую переменную b со значением 3, результат будет 34 с остатком 2.

Числовые значения хранятся как целые или числа с плавающей запятой.

Для целочисленного деления результат – это целая часть деления, десятичная часть результата игнорируется.

Другими словами, целочисленное деление всегда возвращает целое число путем усечения без округления.

При этом может быть потеряна информация, когда десятичная часть отсекается.

Например, при делении 2 на 3 результат должен быть 0.66, но мы получаем 0 из-за отсечения. Или 3 делим на 2 и получаем 1 вместо 1.5.

Если вы делите double на double, результат будет double, как и ожидалось.

Как Java оперирует со смешанными делениями, включающими целые числа и числа с плавающей запятой?

В общем, деление double дает double.

Когда целое делится на double или double делится на целое, результатом будет double.

Это позволяет программе максимально сохранить информацию.

Например, если 2 делится 3.0, 0.6666 будет результатом вместо 0.

Также, деление 3.0 на 2 даст результат 1.5.

Деление двух double 10.0 и 2.0 даст результат double 5.0.

Когда выражение вычисляется, мы должны определить порядок для выполнения операций, если в выражении больше одного оператора.

Когда мы изучали алгебру, мы узнали, что операции * и / выполняются перед операциями + и -, и такое же правило действует и в Java.

Например, в выражении m*x + b, m умножается на x перед прибавлением b к результату умножения.

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

Стандартный порядок, которому следует Java:

( )

* / %

- +

Выражение, заключенное в круглые скобки, вычисляется первым.













Для вложенных скобок внутреннее выражение вычисляется первым.

Операторы *, / и % вычисляются вторыми, и если их несколько, вычисление идет слева направо.

Операторы сложения и вычитания вычисляются после остальных операторов, и если их несколько, вычисление идет слева направо.

Другая важная вещь в вычислении выражений это концепция ассоциативности.

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

Правило ассоциации в этом примере – это вычисление слева направо, и называется левой ассоциативностью.

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

Вы можете подумать, что все операции должны следовать левой ассоциации. Однако это не всегда случается в Java, и мы уже видели оператор, который следует правой ассоциации – это оператор присваивания =.

Присваивание

Мы видели много утверждений со знаком равенства в предыдущих примерах.

Они называются операторами присваивания.

Синтаксис оператора присваивания представляет собой размещение переменной на левой стороне знака равенства, выражения на его правой стороне и точки с запятой в конце.

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

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

Например, вы можете иметь что-то вроде а = а + 1;

Это не корректно в качестве математического выражения, но это верное утверждение присваивания.

Переменная здесь имеет начальное значение 1, и ее значение будет изменено на 2 после присвоения.

Для определенного типа существует набор действительных операторов, которые могут быть применены к этому типу.

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

Преобразование типа может быть сделано двумя способами: это явные и неявные преобразования.

Неявное преобразование изменяет значение одного типа в другой без специальной инструкции от программиста.

Например, целый тип int разрешено присвоить float, хотя может быть потеряна точность.

Основное правило заключается в том, что неявное преобразование разрешено, если диапазон значений первого типа является подмножеством второго.

Его часто называют расширяющим преобразованием.

Обратное, это сужающее преобразование, которое, как правило, не допускается без явного преобразования.

Явное преобразование выполняется приведением типов.

Приведение типов делается путем размещения имени целевого типа в скобках перед типом данных, которые будут преобразованы.

Например, если dValue является double переменной, компилятор не допустит присвоения int или float без преобразования явного типа, указав int или float в скобках.

Далее вернемся к примеру CourseGrade и используем то, что мы только что узнали о переменных, объявлениях, типах данных и арифметических выражениях, чтобы получить более глубокое понимание того, как эта программа выполняется.