Блок 1. Раздел 1. Тема 3

Объявляем переменные,
вычисляем выражения
Операторы +=, -=, *=,/=, ++, --

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

Это можно закодить так:
// Объявим по одной переменной для каждого вида расходов
// Слева от равно пишем double - значит у нас будет дробное число
// transp - имя переменной, мы его выбрали сами
// Справа от равно - начальное значение
double transp = 100;   // на транспорт за один день тратим порядка 100 рублей
double food = 500;      // на еду за один заход в магазин в среднем 500 рублей
double dress = 2000; // на одежду - 2000

//Начальное значение переменной result вычислим по выражению:
double result = transp*365 + food*2*4*12 + dress*5;

// То есть 365 раз за год потратились на транспорт, 
// еду покупали 2 раза в неделю, а недель 4 в месяце, а месяцев 12, 
// одежду купили 5 раз в год. 
// Теперь переменная result хранит сумму затрат за год - можно ее распечатать, 
// сравнить с другими переменными или использовать в дальнейших расчетах. 
// Удобно, что теперь мы можем менять значения исходных данных, 
// и смотреть, как это отразится на итоговом результате.
Определение. Переменная – это имя, которое обозначает некоторое число. Переменные могут получать начальное значение и потом менять его. У переменных есть тип – либо это целые числа (int), либо дробные (double и float), либо символы (char). Переменные участвуют в любых выражениях наравне с обычными числами.
Объявить переменную - значит дать ей имя, указать, какого она типа, и указать начальное значение справа от знака равно. В коде это делается так:
int x = 10;
Это значит завести переменную с именем x, у которой тип – int, сокращенно от integer (по-английски «целое число»). Справа от знака равно ставится начальное значение переменной. Оно может быть просто равно заданному числу, например, 10, а может вычисляться через любое выражение.

В общем случае объявление переменной выглядит так:
тип имя = числовое выражение;
Типы данных бывают такие – целое число int, дробное число double, символ char. Переменная - это имя, обозначающее заданное число. Вы можете это число по ходу программы менять. Как только вы объявили переменную, под неё выделяется место в оперативной памяти компьютера - ячейка. В ней записаны цифры данного числа в двоичной системе исчисления, где вместо привычных цифр 0, 1, 2, …, 9 есть только цифры 0 и 1.

Давайте поменяем значение переменной x вот так:
int x = 10;
x = 200; //изменить значение икс - забыть 10, и запомнить 200
//слева int не указан, значит мы используем уже объявленную переменную
Разберем популярную ошибку - объявление одной и той же переменной дважды:
int x = 100;
int x = 300; 
// ошибка - указав int, мы говорим "объявить новую x", но переменная x уже объявлена

// Создадим другую переменную с именем y
int y = 100;
// Объявим ее еще раз с другим типом
double y = 200.5; // ошибка - переменная y уже была раньше объявлена.
// Теперь, когда мы указали новый тип, компилятор просто не может определиться,
// что же имелось в виду, y - целое, или y - дробное. Вы можете получить ошибку 
// ambiguous name, то есть многозначное имя. 
Посмотрим новый пример с несколькими переменными. Кстати я пишу, что делает очередная строчка в комментарии к ней. Комментарии не исполняются в программе, в них можно просто пояснять код. Комментарии на одну строчку в Java обозначаются // , а также внутри блока /* Можно писать всё что угодно */ - это комментарий на много строчек. Вы легко опознаете комментарии, когда увидите их в этом коде:
package javaapplication1;
public class JavaApplication1 {
public static void main(String[] args) {
//вызовем функцию println
  System.out.println ("Щас будем вычислять!");
// Объявим переменную x целого типа, равную 10
  int x = 10;
// Объявим переменную y целого типа, равную 30
  int y = 30;
// Объявим переменную z, равную выражению:
  int z = x + y /2;
// Распечатаем значение z – это будет 25
  System.out.println (z);
// Изменим z снова, пусть оно будет теперь x/2
  z = x / 2;
// Выведем на экран новое значение z – это будет 5
  System.out.println (z);

// Можно объявить несколько переменных в одной строчке
  int a = 10, b = 20;
/* В принципе можно объявить переменную без начального значения, 
но Java ударит вас по рукам, если вы позже не присвоите ей значение. 
Лучше так не делать, потому что от переменных без начального значения пользы никакой,
а навредить они могут сильно – если вдруг Java не заметит, что вы её используете, 
то вы получите непредсказуемое поведение программы, 
каждый раз разное – эту ошибку очень сложно отловить, 
иногда на её поиск уходят недели. */
  int w; // Лучше не надо, поверьте..
  w = 5;
// Объявим переменную дробного типа double
  double some = 0.5;
// Изменим значение переменной some на новое
  some = 1.5;
// Сделаем some равной y
  some = y;
// Объявим символ с равным коду буквы b
  char c = ‘b’;
/* Здесь можно писать только одну букву или цифру в одинарных кавычках. 
Символы нельзя складывать, зато из них можно делать строки и тексты – 
мы займемся этим на следующих уроках*/

// Объявим дробное d, равное 2.5
  double d = 2.5;
/* Используем саму переменную, чтобы например, увеличить ее на 5: */
  d = d + 5;       
// теперь d равно 7.5, старое значение забыто
 }   
/* В конце переменные, объявленные в main, удаляются - 
так происходит всегда по достижении конца блока фигурных скобок, 
внутри которого они были объявлены */
}
/* По сути переменная – это число, записанное в ячейке памяти компьютера. 
Объявить переменную – значит назвать эту ячейку именем. 
Имя может быть одной буквой, а может быть и словом. 
Вы можете поменять число, сидящее в ячейке, 
или использовать его для вычисления других чисел. 
Это очень удобно, иначе вам пришлось бы указывать «вон то число», 
а потом «вот это число», чтобы сделать любые вычисления. 
Так писали программы в 80ых годах прошлого века – 
это было настолько неудобно, что элементарный калькулятор приходилось писать месяцами. 
Теперь, заводя переменные, мы пишем его за несколько минут. */
Привычные нам знаки арифметических действий +, -, *, / называются операторами, они служат для простых вычислений. Знак = тоже оператор и означает приравнять, то есть изменить старое значение переменной на новое. Но есть еще операторы +=, -=, *=, /= . Они читаются увеличить (уменьшить, умножить, поделить) переменную на значение справа. Рассмотрим пример ниже:
int x = 10;
// Увеличим x на 10
x = x + 10;
// Ту же фразу можно записать короче с оператором +=
x += 10;
То есть оператор += является просто сокращением и означает увеличить переменную на значение, стоящее справа. Аналогично, операторы -=, *=, /= вычитают, умножают, делят переменную на значение, стоящее справа, например:
double y = 12;
double z = 3;
// Поделим y на 3 и запишем новое значение в y
y /= z;
// Умножим на 4, затем на (z-2)
y *= 4;
y *= z-2;
/* Все это допустимые операции, их удобно делать с операторами +=, -=, *=, /=          */
Ещё операцию x += 1 тоже можно записать короче с помощью оператора инкремента ++ . То есть ++ означает "увеличить переменную на один". Аналогично -- значит "уменьшить на 1". Посмотрим в коде:
int x = 10;

x ++; // теперь x равен 11

x ++; // теперь x равен 12

x --; // теперь x снова 11
Можно писать x++ (постфиксный инкремент), а можно ++x (префиксный инкремент). Аналогично и с декрементом. Если эти операции стоят в коде отдельно от прочих, то оба варианта записи эквивалентны, они увеличивают x на 1. Если же x++ используется прямо в выражении, то разница есть . Поясним в коде:
int a = 10; // зададим a и b равным 10
int b = 10;
        
// a++ означает в выражении использовать старое значение a, но в потом a увеличить
int y = 5 + a++; // итого будет 5+10
// ++b означает уже в выражении увеличить b
int z = 5 + ++b; // итого будет 5 + 11
        
System.out.println (a);
System.out.println (b);
System.out.println (y);
System.out.println (z);
        
/* Вывод программы:
11
11
15
16
*/
Ещё поясняющий пример:

// вариант с использованием x ++ 
// постфиксная запись, как бы "увеличить x после" выражения
int x = 10; 
int y = 5 + x++;
// будет эквивалентно следующему:
int x = 10; 
int y = 5 + x; // в выражении старое значение
x += 1; // уже после выражения мы увеличим x

// а теперь то же самое с использование x-- 
// префиксная запись, как бы "увеличить перед" выражением
int x = 10; 
int y = 5 + ++x;
// будет эквивалентно следующему:
int x = 10; 
x += 1; // перед выражением мы увеличим x
int y = 5 + x; // в выражении новое увеличенное значение

// Начинающим обучение можно лишний раз не думать об разнице x++, ++x
// Просто не пишите их прямо в выражения, и считайте, что это просто "увеличить на 1"
// Но если где-то встретите, то будете готовы :)

Более сложные выражения с участием скобок (...)

Скобки позволяют указать программе, что нужно в выражении вычислить раньше, а что потом. Выражения в скобках имеют абсолютный приоритет - сначала вычисляется то что в скобках, потом умножение и деление, потом уже сложение и вычитание. Разберёмся в приоритетах на примере:
double x =  10 + 5 * 2 - 3; // будет конечно 10+10-3, то есть 17

double y = (10 + 5) * 2 - 3; // теперь есть скобки , поэтому 15*2 - 3, то есть 27

double z = 100 / 4 * 2 + 5; 
// при равнозначном приоритете компилятор читает слева направо:
// получится 100/4 - это 25, умножить на 2 - это 50, и добавить 5 - в итоге z=55

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

z = z*z; // получается, возвести z в квадрат,
// поскольку мы взяли старое значение, умножили его само на себя и записали в z.
// Аналогично можно возвести в куб и вообще в любую степень:
x = x*x*x ; // возвели x в куб.

// Также можно получить обратную к исходной величину:
x = 1 / x; // но помните, что если бы x был int, а не double, 
// то тут часто получался бы чистый ноль, 
// т.к. при делении целых дробные части отбрасываются.


// Теперь пример на несколько скобок
x = 10;
x = (x + 10) / 2 - 5 * (x-2); // будет 20 / 2 - 5 * 8, то есть -30.

// А также вложенные скобки:
x = 10;
x = (x + 5*(x-1)  ) * 2 + 1; // будет (10 + 5 * 9) * 2 + 1 = 55 * 2 + 1 = 111.
Самое главное мы уже освоили. Теперь время решать задачи. Ответьте на несколько вопросов, чтобы лучше усвоился новый материал:
Вопрос 1. Что значит объявить переменную? (ответы по кнопке "плюс")
Это значит назвать число заданного типа (целые, дробные или коды букв) каким-то своим именем. Под это число будет выделено место в оперативной памяти. Это число в дальнейшем можно менять и использовать в любых расчетах.
Вопрос 2. Что будет, если объявить две переменных с одним и тем же именем внутри одного блока фигурных скобок { } ?
Компилятор выдаст ошибку, потому что с его точки зрения, вы говорите, что одно и то же имя теперь может отвечать двум разным переменным. Он не может разобраться, какой же из двух переменных это имя отвечает, и сообщит, что это имя двусмысленное и его нужно изменить.

То есть в таком коде есть ошибка:
int x = 100;
int x = 200; // ошибка, x уже был объявлен
А в таком коде все нормально:
int x = 100;
x = 200; //поменять значение x на 200
//именно отсутствие int в начале строчки говорит о том, что x просто меняет свое значение, и мы не пытаемся завести новую переменную.
Задача 1. Ниже дан код с двумя переменными. Что будет распечатано на экране?
package javaapplication1;
public class JavaApplication1 {
public static void main(String[] args) {
  int x = 100;
  x = x*10/2 + x;
  System.out.println (x);

  double y = x - 5.5;

  System.out.println (y);
 }   
}
Ответ
600
594.5
Решение
Посчитаем выражения для введенных в коде переменных x и y.
Сначала x = 100;
Затем в строчке
x = x*10/2 + x;
компилятор сначала рассчитывает числовое выражение справа от равно
на основе старого значения x
100*10/2 + 100, то есть 600.
Поэтому строчка читается как "икс присвоить 600". Это значение и будет распечатано на экране.

На его основе будет вычислено значение y = x - 5.5, то есть 594.5.
Переменная y обладает типом double, то есть дробное, поэтому в ней можно сохранить дробную часть 0.5 . Если бы y было целым, то в такой переменной невозможно было бы сохранить дробную часть, и компилятор подчеркнул бы эту строчку красным и выдал ошибку. В ошибке было бы сказано, что идет отбрасывание дробной части, и это может привести к потере точности.
Решайте больше задач по этому разделу здесь.
В следующей теме расскажем подробнее
о типах данных в Java