Приоритет арифметических операций



Основы программирования на Java

Структура программы

Основным строительным блоком программа на языке Java являются инструкции (statement). Каждая инструкция выполняет некоторое действие, например, вызовы методов, объявление переменных и присвоение им значений. После завершения инструкции в Java ставится точка с запятой (;). Данный знак указывает компилятору на конец инструкции. Например:

1 System.out.println("Hello Java!");

Данная строка представляет вызов метода System.out.println, который выводит на консоль строку "Hello Java!". В данном случае вызов метода является инструкцией и поэтому завершается точкой с запятой.

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

1 2 3 4 { System.out.println("Hello!"); System.out.println("Welcome to Java!"); }

В этом блоке кода две инструкции, которые выводят на консоль определенную строку.

Выполнение программы. Метод main

Java является объектно-ориентированным языком, поэтому всю программу можно представить как набор взаимодествующих между собой классов и объектов. В первой главе при создании первого приложения программа была определена следующим образом:

1 2 3 4 5 6 7 public class Program{   public static void main (String args[]){   System.out.println("Hello Java!"); } }

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

Входной точкой в программу на языке Java является функция main, которая определена в классе Program. Именно с нее начинается выполнение программы. Он обязательно должен присутствовать в программе. При этом его заголовок может быть только таким:

1 public static void main (String args[])

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

Вначале заголовка метода идет модификатор public, который указывает, что метод будет доступен извне. Слово static указывает, что метод main - статический, а слово void - что он не возвращает никакого значения. Далее в скобках у нас идут параметры метода - String args[] - это массив args, который хранит значения типа String, то есть строки. При запуске программы через этот массив мы можем передать в программу различные данные.

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

Комментарии

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

В Java есть два типа комментариев: однострочный и многострочный. Однострочный комментарий размещается на одной строке после двойного слеша //. А многострочный комментарий заключается между символами /* текст комментария */. Он может размещаться на нескольких строках. Например:

1 2 3 4 5 6 7 8 9 10 11 12 13 /* многострочный комментарий Объявление нового класса, который содержит код программы */ public class Program{ // начало объявления класса Program   // определение метода main public static void main (String args[]){ // объявление нового метода   System.out.println("Hello Java!"); // вывод строки на консоль } // конец объявления нового метода } // конец объявления класса Program

Переменные и константы

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

Переменные объявляются следующим образом:

1 тип_данных имя_переменной;

Например, определим переменную, которая будет называться x и будет иметь тип int:

1 int x;

В этом выражении мы объявляем переменную x типа int. То есть x будет хранить некоторое число не больше 4 байт.

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

· имя может содержать любые алфавитно-цифровые символы, а также знак подчеркивания, при этом первый символ в имени не должен быть цифрой

· в имени не должно быть знаков пунктуации и пробелов

· имя не может быть ключевым словом языка Java

Кроме того, при объявлении и последующем использовании надо учитывать, что Java - регистрозависимый язык, поэтому следующие объявления int num; и int NUM; будут представлять две разных переменных.

Объявив переменную, мы можем присвоить ей значений:

1 2 3 int x; // объявление переменной x = 10; // присвоения значения System.out.println(x); // 10

Также можно привоить значение переменной при ее объявлении. Этот процесс называется инициализацией:

1 2 int x = 10; // объявление и инициализация переменной System.out.println(x); // 10

Если мы не присвоим переменной значение до ее использования, то мы можем получить ошибку, например, в следующем случае:

1 2 int x; System.out.println(x);

Через запятую можно объявить сразу несколько переменных одного типа:

1 2 3 4 5 int x, y; x = 10; y = 25; System.out.println(x); // 10 System.out.println(y); // 25

Также можно их сразу инициализировать:

1 2 3 int x = 8, y = 15; System.out.println(x); // 8 System.out.println(y); // 15

Отличительной особенностью переменных является то, что мы можем в процессе работы программы изменять их значение:

1 2 3 4 int x = 10; System.out.println(x); // 10 x = 25; System.out.println(x); // 25

Ключевое слово var

Начиная с Java 10 в язык было добавлено ключевое слово var, которое также позволяет определять переменную:

1 2 var x = 10; System.out.println(x); // 10

Слово var ставится вместо типа данных, а сам тип переменной выводится из того значения, которое ей присваивается. Например, переменой x приваивается число 10, значит, переменная будет представлять тип int.

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

1 2 var x; // ! Ошибка, переменная не инициализирована x = 10;

Константы

Кроме переменных, в Java для хранения данных можно использовать константы. В отличие от переменных константам можно присвоить значение только один раз. Константа объявляется также, как и переменная, только вначале идет ключевое слово final:

1 2 3 final int LIMIT = 5; System.out.println(LIMIT); // 5 // LIMIT=57; // так мы уже не можем написать, так как LIMIT - константа

Как правило, константы имеют имена в верхнем регистре.

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

Типы данных

Одной из основных особенностей Java является то, что данный язык является строго типизированным. А это значит, что каждая переменная и константа представляет определенный тип и данный тип строго определен. Тип данных определяет диапазон значений, которые может хранить переменная или константа.

Итак, рассмотрим систему встроенных базовых типов данных, которая используется для создания переменных в Java. А она представлена следующими типами.

· boolean: хранит значение true или false

1 2 boolean isActive = false; boolean isAlive = true;

· byte: хранит целое число от -128 до 127 и занимает 1 байт

1 2 byte a = 3; byte b = 8;

· short: хранит целое число от -32768 до 32767 и занимает 2 байта

1 2 short a = 3; short b = 8;

· int: хранит целое число от -2147483648 до 2147483647 и занимает 4 байта

1 2 int a = 4; int b = 9;

· long: хранит целое число от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 и занимает 8 байт

1 2 long a = 5; long b = 10;

· double: хранит число с плавающей точкой от ±4.9*10-324 до ±1.8*10308 и занимает 8 байт

1 2 double x = 8.5; double y = 2.7;

· В качестве разделителя целой и дробной части в дробных литералах используется точка.

· float: хранит число с плавающей точкой от -3.4*1038 до 3.4*1038 и занимает 4 байта

1 2 float x = 8.5F; float y = 2.7F;

· char: хранит одиночный символ в кодировке UTF-16 и занимает 2 байта, поэтому диапазон хранимых значений от 0 до 65536

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

Целые числа

Все целочисленные литералы, например, 10,4, -5, воспринимаются как значения типа int, однако мы можем присваивать целочисленные литералы другим целочисленным типам: byte, long, short. В этом случае Java автоматически осуществляет соответствующие преобразования:

1 2 3 byte a = 1; short b = 2; long c = 2121;

Однако если мы захотим присвоить переменной типа long очень большое число, которое выходит за пределы допустимых значений для типа int, то мы столкнемся с ошибкой во время компиляции:

1 long num = 2147483649;

Здесь число 2147483649 является допустимым для типа long, но выходит за предельные значения для тпа int. И так как все целочисленные значения по умолчанию расцениваются как значения типа int, то компилятор укажет нам на ошибку. Чтобы решить проблему, надо добавить к числу суффикс l или L, который указывает, что число представляет тип long:

1 long num = 2147483649L;

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

1 2 3 int num111 = 0x6F; // 16-тиричная система, число 111 int num8 = 010; // 8-ричная система, число 8 int num13 = 0b1101; // 2-ичная система, число 13

Для задания шестнадцатеричного значения после символов 0x указывается число в шестнадцатеричном формате. Таким же образом восьмеричное значение указывается после символа 0, а двоичное значение - после символов 0b.

Также целые числа поддерживают разделение разрядов числа с помощью знака подчеркивания:

1 2 3 4 int x = 123_456; int y = 234_567__789; System.out.println(x); // 123456 System.out.println(y); // 234567789

Числа с плавающей точкой

При присвоении переменной типа float дробного литерала с плавающей точкой, например, 3.1, 4.5 и т.д., Java автоматически рассматривает этот литерал как значение типа double. И чтобы указать, что данное значение должно рассматриваться как float, нам надо использовать суффикс f:

1 2 float fl = 30.6f; double db = 30.6;

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

Символы и строки

В качестве значения переменная символьного типа получает одиночный символ, заключенный в ординарные кавычки: char ch='e';. Кроме того, переменной символьного типа также можно присвоить целочисленное значение от 0 до 65536. В этом случае переменная опять же будет хранить символ, а целочисленное значение будет указывать на номер символа в таблице символов Unicode (UTF-16). Например:

1 2 char ch=102; // символ 'f' System.out.println(ch);

Еще одной формой задания символьных переменных является шестнадцатеричная форма: переменная получает значение в шестнадцатеричной форме, которое следует после символов "\u". Например, char ch='\u0066'; опять же будет хранить символ 'f'.

Символьные переменные не стоит путать со строковыми, 'a' не идентично "a". Строковые переменные представляют объект String, который в отличие от char или int не является примитивным типов в Java:

1 2 String hello = "Hello..."; System.out.println(hello);

Консольный ввод/вывод в Java

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

Вывод на консоль

Для создания потока вывода в класс System определен объект out. В этом объекте определен метод println, который позволяет вывести на консоль некоторое значение с последующим переводом консоли на следующую строку. Например:

1 2 3 4 5 6 7 8 public class Program {   public static void main(String[] args) {   System.out.println("Hello world!"); System.out.println("Bye world..."); } }

В метод println передается любое значение, как правило, строка, которое надо вывести на консоль. И в данном случае мы получим следующий вывод:

Hello world!Bye world...

При необходимости можно и не переводить курсор на следующую строку. В этом случае можно использовать методSystem.out.print(), который аналогичен println за тем исключением, что не осуществляет перевода на следующую строку.

1 2 3 4 5 6 7 8 public class Program {   public static void main(String[] args) {   System.out.print("Hello world!"); System.out.print("Bye world..."); } }

Консольный вывод данной программы:

Hello world!Bye world...

Но с помощью метода System.out.print также можно осуществить перевод каретки на следующую строку. Для этого надо использовать escape-последовательность \n:

1 System.out.print("Hello world \n");

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

1 2 3 4 5 6 7 8 9 public class Program {   public static void main(String[] args) {   int x=5; int y=6; System.out.println("x=" + x + "; y=" + y); } }

Консольный вывод программы:

x=5; y=6

Но в Java есть также функция для форматированного вывода, унаследованная от языка С: System.out.printf(). С ее помощью мы можем переписать предыдущий пример следующим образом:

1 2 3 int x=5; int y=6; System.out.printf("x=%d; y=%d \n", x, y);

В данном случае символы %d обозначают спецификатор, вместо которого подставляет один из аргументов. Спецификаторов и соответствующих им аргументов может быть множество. В данном случае у нас только два аргумента, поэтому вместо первого %dподставляет значение переменной x, а вместо второго - значение переменной y. Сама буква d означает, что данный спецификатор будет использоваться для вывода целочисленных значений.

Кроме спецификатора %d мы можем использовать еще ряд спецификаторов для других типов данных:

· %x: для вывода шестнадцатеричных чисел

· %f: для вывода чисел с плавающей точкой

· %e: для вывода чисел в экспоненциальной форме, например, 1.3e+01

· %c: для вывода одиночного символа

· %s: для вывода строковых значений

Например:

1 2 3 4 5 6 7 8 9 10 11 public class Program {   public static void main(String[] args) {   String name = "Tom"; int age = 30; float height = 1.7f;   System.out.printf("Name: %s Age: %d Height: %.2f \n", name, age, height); } }

При выводе чисел с плавающей точкой мы можем указать количество знаков после запятой, для этого используем спецификатор на %.2f, где .2 указывает, что после запятой будет два знака. В итоге мы получим следующий вывод:

Name: Tom Age: 30 Height: 1,70

Ввод с консоли

Для получения ввода с консоли в классе System определен объект in. Однако непосредственно через объект System.in не очень удобно работать, поэтому, как правило, используют класс Scanner, который, в свою очередь использует System.in. Например, напишем маленькую программу, которая осуществляет ввод чисел:

1 2 3 4 5 6 7 8 9 10 11 12 13 import java.util.Scanner;   public class Program {   public static void main(String[] args) {   Scanner in = new Scanner(System.in); System.out.print("Input a number: "); int num = in.nextInt();   System.out.printf("Your number: %d \n", num); } }

Так как класс Scanner находится в пакете java.util, то мы вначале его импортируем с помощью инструкции import java.util.Scanner.

Для создания самого объекта Scanner в его конструктор передается объект System.in. После этого мы можем получать вводимые значения. Например, в данном случае вначале выводим приглашение к вводу и затем получаем вводимое число в переменную num.

Чтобы получить введенное число, используется метод in.nextInt();, который возвращает введенное с клавиатуры целочисленное значение.

Пример работы программы:

Input a number: 5Your number: 5

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

· next(): считывает введенную строку до первого пробела

· nextLine(): считывает всю введенную строку

· nextInt(): считывает введенное число int

· nextDouble(): считывает введенное число double

· nextBoolean(): считывает значение boolean

· nextByte(): считывает введенное число byte

· nextFloat(): считывает введенное число float

· nextShort(): считывает введенное число short

То есть для ввода значений каждого примитивного типа в классе Scanner определен свой метод.

Например, создадим программу для ввода информации о человеке:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import java.util.Scanner;   public class Program {   public static void main(String[] args) {   Scanner in = new Scanner(System.in); System.out.print("Input name: "); String name = in.nextLine(); System.out.print("Input age: "); int age = in.nextInt(); System.out.print("Input height: "); float height = in.nextFloat(); System.out.printf("Name: %s Age: %d Height: %.2f \n", name, age, height); } }

Здесь последовательно вводятся данные типов String, int, float и потом все введенные данные вместе выводятся на консоль. Пример работы программы:

Input name: TomInput age: 34Input height: 1,7Name: Tom Age: 34 Height: 1,70

Обратите внимание для ввода значения типа float (то же самое относится к типу double) применяется число "1,7", где разделителем является запятая, а не "1.7", где разделителем является точка. В данном случае все зависит от текущей языковой локализации системы. В моем случае русскоязычная локализация, соответственно вводить необходимо числа, где разделителем является запятая. То же самое касается многих других локализаций, например, немецкой, французской и т.д., где применяется запятая.

Арифметические операции

Большинство операций в Java аналогичны тем, которые применяются в других си-подобных языках. Есть унарные операции (выполняются над одним операндом), бинарные - над двумя операндами, а также тернарные - выполняются над тремя операндами. Операндом является переменная или значение (например, число), участвующее в операции. Рассмотрим все виды операций.

В арифметических операциях участвуют числами. В Java есть бинарные арифметические операции (производятся над двумя операндами) и унарные (выполняются над одним операндом). К бинарным операциям относят следующие:

· +

операция сложения двух чисел:

1 2 3 4 int a = 10; int b = 7; int c = a + b; // 17 int d = 4 + b; // 11

· -

операция вычитания двух чисел:

1 2 3 4 int a = 10; int b = 7; int c = a - b; // 3 int d = 4 - a; // -6

· *

операция умножения двух чисел

1 2 3 4 int a = 10; int b = 7; int c = a * b; // 70 int d = b * 5; // 35

· /

операция деления двух чисел:

1 2 3 4 int a = 20; int b = 5; int c = a / b; // 4 double d = 22.5 / 4.5; // 5.0

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

1 2 double k = 10 / 4; // 2 System.out.println(k);

Чтобы результат представлял числос плавающей точкой, один из операндов также должен представлять число с плавающей точкой:

1 2 double k = 10.0 / 4; // 2.5 System.out.println(k);

· %

получение остатка от деления двух чисел:

1 2 3 4 int a = 33; int b = 5; int c = a % b; // 3 int d = 22 % 4; // 2 (22 - 4*5 = 2)

Также есть две унарные арифметические операции, которые производятся над одним числом: ++ (инкремент) и -- (декремент). Каждая из операций имеет две разновидности: префиксная и постфиксная:

· ++ (префиксный инкремент)

Предполагает увеличение переменной на единицу, например, z=++y (вначале значение переменной y увеличивается на 1, а затем ее значение присваивается переменной z)

1 2 3 4 int a = 8; int b = ++a; System.out.println(a); // 9 System.out.println(b); // 9

· ++ (постфиксный инкремент)

Также представляет увеличение переменной на единицу, например, z=y++ (вначале значение переменной y присваивается переменной z, а потом значение переменной y увеличивается на 1)

1 2 3 4 int a = 8; int b = a++; System.out.println(a); // 9 System.out.println(b); // 8

· -- (префиксный декремент)

уменьшение переменной на единицу, например, z=--y (вначале значение переменной y уменьшается на 1, а потом ее значение присваивается переменной z)

1 2 3 4 int a = 8; int b = --a; System.out.println(a); // 7 System.out.println(b); // 7

· -- (постфиксный декремент)

z=y-- (сначала значение переменной y присваивается переменной z, а затем значение переменной y уменьшается на 1)

1 2 3 4 int a = 8; int b = a--; System.out.println(a); // 7 System.out.println(b); // 8

Приоритет арифметических операций

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

++ (инкремент), -- (декремент)

* (умножение), / (деление), % (остаток от деления)

+ (сложение), - (вычитание)

Приоритет операций следует учитывать при выполнении набора арифметических выражений:

1 2 3 4 int a = 8; int b = 7; int c = a + 5 * ++b; System.out.println(c); // 48

Вначале будет выполняться операция инкремента ++b, которая имеет больший приоритет - она увеличит значение переменной b и возвратит его в качестве результата. Затем выполняется умножение 5 * ++b, и только в последнюю очередь выполняется сложение a + 5 * ++b

Скобки позволяют переопределить порядок вычислений:

1 2 3 4 int a = 8; int b = 7; int c = (a + 5) * ++b; System.out.println(c); // 104

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

Ассоциативность операций

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

· Левоассоциативные операторы, которые выполняются слева направо

· Правоассоциативные операторы, которые выполняются справа налево

Так, некоторые операции, например, операции умножения и деления, имеют один и тот же приоритет. Какой же тогда будет результат в выражении:

1 int x = 10 / 5 * 2;

Стоит нам трактовать это выражение как (10 / 5) * 2 или как 10 / (5 * 2)? Ведь в зависимости от трактовки мы получим разные результаты.

Поскольку все арифметические операторы (кроме префиксного инкремента и декремента) являются левоассоциативными, то есть выполняются слева направо. Поэтому выражение 10 / 5 * 2 необходимо трактовать как (10 / 5) * 2, то есть результатом будет 4.


Дата добавления: 2019-02-22; просмотров: 359; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!