first changed, second done

This commit is contained in:
Ivan I. Ovchinnikov 2022-12-01 00:36:44 +03:00
parent 4a0778de1b
commit fbf148ee14
9 changed files with 136 additions and 126 deletions

Binary file not shown.

Binary file not shown.

View File

@ -21,7 +21,7 @@
\subsection{Краткая история (причины возникновения)} \subsection{Краткая история (причины возникновения)}
\begin{itemize} \begin{itemize}
\item Язык создавали для разработки встраиваемых систем, сетевых приложений и прикладного \nom{ПО}{(программное обеспечение) - программа или множество программ, используемых для управления компьютером.}; \item Язык создавали для разработки встраиваемых систем, сетевых приложений и прикладного \nom{ПО}{(программное обеспечение) -- программа или множество программ, используемых для управления компьютером.};
\item Популярен из-за скорости исполнения и полного абстрагирования от исполнителя кода; \item Популярен из-за скорости исполнения и полного абстрагирования от исполнителя кода;
\item Часто используется для программирования бэк-энда веб-приложений из-за изначальной нацеленности на сетевые приложения. \item Часто используется для программирования бэк-энда веб-приложений из-за изначальной нацеленности на сетевые приложения.
\end{itemize} \end{itemize}
@ -44,10 +44,10 @@
\subsection{Базовый инструментарий, который понадобится (выбор IDE)} \subsection{Базовый инструментарий, который понадобится (выбор IDE)}
\begin{itemize} \begin{itemize}
\item NetBeans - хороший, добротный инструмент с лёгким ностальгическим оттенком; \item NetBeans -- хороший, добротный инструмент с лёгким ностальгическим оттенком;
\item Eclipse - для поклонников Eclipse Foundation и швейцарских ножей с полусотней лезвий; \item Eclipse -- для поклонников Eclipse Foundation и швейцарских ножей с полусотней лезвий;
\item IntelliJ IDEA - стандарт де-факто, используется на курсе и в большинстве современных компаний; \item IntelliJ IDEA -- стандарт де-факто, используется на курсе и в большинстве современных компаний;
\item Android Studio - если заниматься мобильной разработкой. \item Android Studio -- если заниматься мобильной разработкой.
\end{itemize} \end{itemize}
\subsubsection{Задания для самопроверки} \subsubsection{Задания для самопроверки}
@ -66,7 +66,7 @@
В последнее время, с развитием контейнеризации приложений, часто устанавливают инструментарий в Docker-контейнер и ведут разработку прямо в контейнере, это позволяет не захламлять компьютер разработчика разными версиями инструментария и быстро разворачивать свои приложения в \nom{CI}{(англ. Continious Integration) практика разработки программного обеспечения, которая заключается в постоянном слиянии рабочих копий в общую основную ветвь разработки и выполнении частых автоматизированных сборок проекта для скорейшего выявления потенциальных дефектов и решения интеграционных проблем.} или на целевом сервере. В последнее время, с развитием контейнеризации приложений, часто устанавливают инструментарий в Docker-контейнер и ведут разработку прямо в контейнере, это позволяет не захламлять компьютер разработчика разными версиями инструментария и быстро разворачивать свои приложения в \nom{CI}{(англ. Continious Integration) практика разработки программного обеспечения, которая заключается в постоянном слиянии рабочих копий в общую основную ветвь разработки и выполнении частых автоматизированных сборок проекта для скорейшего выявления потенциальных дефектов и решения интеграционных проблем.} или на целевом сервере.
\begin{frm} \begin{frm}
\info В общем случае, для разработки на любом языке программирования нужны так называемые \nom{SDK}{(от англ. software development kit, комплект для разработки программного обеспечения) — это набор инструментов для разработки программного обеспечения в одном устанавливаемом пакете. Они облегчают создание приложений, имея компилятор, отладчик и иногда программную среду. В основном они зависят от комбинации аппаратной платформы компьютера и операционной системы.} (Software Development Kit, англ. - инструментарий разработчика приложений или инструментарий для разработки приложений). Частный случай такого SDK - инструментарий разработчика на языке Java - Java Development Kit. \info В общем случае, для разработки на любом языке программирования нужны так называемые \nom{SDK}{(от англ. software development kit, комплект для разработки программного обеспечения) — это набор инструментов для разработки программного обеспечения в одном устанавливаемом пакете. Они облегчают создание приложений, имея компилятор, отладчик и иногда программную среду. В основном они зависят от комбинации аппаратной платформы компьютера и операционной системы.} (Software Development Kit, англ. -- инструментарий разработчика приложений или инструментарий для разработки приложений). Частный случай такого SDK -- инструментарий разработчика на языке Java -- Java Development Kit.
\end{frm} \end{frm}
На курсе будет использоваться BellSoft Liberica JDK 11, но возможно использовать и других производителей, например, самую распространённую Oracle JDK. Производителя следует выбирать из требований по лицензированию, так, например, Oracle JDK можно использовать бесплатно только в личных целях, за коммерческую разработку с использованием этого инструментария придётся заплатить. На курсе будет использоваться BellSoft Liberica JDK 11, но возможно использовать и других производителей, например, самую распространённую Oracle JDK. Производителя следует выбирать из требований по лицензированию, так, например, Oracle JDK можно использовать бесплатно только в личных целях, за коммерческую разработку с использованием этого инструментария придётся заплатить.
@ -104,7 +104,7 @@ TL;DR:
Как именно всё работает? Если коротко, то слой за слоем накладывая абстракции. Программы на любом языке программирования исполняются на компьютере, то есть, так или иначе, задействуют процессор, оперативную память и прочие аппаратурные компоненты. Эти аппаратурные компоненты предоставляют для доступа к себе низкоуровневые интерфейсы, которые задействует операционная система, предоставляя в свою очередь интерфейс чуть проще программам, взаимодействующим с ней. Этот интерфейс взаимодействия с \nom{ОС}{(операционная система) — комплекс управляющих и обрабатывающих программ, которые, с одной стороны, выступают как интерфейс между устройствами вычислительной системы и прикладными программами, а с другой стороны — предназначены для управления устройствами, управления вычислительными процессами, эффективного распределения вычислительных ресурсов между вычислительными процессами и организации надёжных вычислений.} мы для простоты будем называть Native API. Как именно всё работает? Если коротко, то слой за слоем накладывая абстракции. Программы на любом языке программирования исполняются на компьютере, то есть, так или иначе, задействуют процессор, оперативную память и прочие аппаратурные компоненты. Эти аппаратурные компоненты предоставляют для доступа к себе низкоуровневые интерфейсы, которые задействует операционная система, предоставляя в свою очередь интерфейс чуть проще программам, взаимодействующим с ней. Этот интерфейс взаимодействия с \nom{ОС}{(операционная система) — комплекс управляющих и обрабатывающих программ, которые, с одной стороны, выступают как интерфейс между устройствами вычислительной системы и прикладными программами, а с другой стороны — предназначены для управления устройствами, управления вычислительными процессами, эффективного распределения вычислительных ресурсов между вычислительными процессами и организации надёжных вычислений.} мы для простоты будем называть Native API.
С ОС взаимодействует JVM (\href{https://ru.m.wikipedia.org/wiki/Список_виртуальных_машин_Java}{Wikipedia: Список виртуальных машин Java}), то есть, используя Native API, нам становится всё равно, какая именно ОС установлена на компьютере, главное уметь выполняться на JVM. Это открывает простор для создания целой группы языков, они носят общее бытовое название JVM-языки, к ним относят Scala, Groovy, Kotlin и другие. Внутри JVM осуществляется управление памятью, существует механизм исполнения программ, специальный JIT\footnote{JIT, just-in-time - англ. в\'{о}время, прямо сейчас}-компилятор, генерирующий платформенно-зависимый код. С ОС взаимодействует JVM (\href{https://ru.m.wikipedia.org/wiki/Список_виртуальных_машин_Java}{Wikipedia: Список виртуальных машин Java}), то есть, используя Native API, нам становится всё равно, какая именно ОС установлена на компьютере, главное уметь выполняться на JVM. Это открывает простор для создания целой группы языков, они носят общее бытовое название JVM-языки, к ним относят Scala, Groovy, Kotlin и другие. Внутри JVM осуществляется управление памятью, существует механизм исполнения программ, специальный JIT\footnote{JIT, just-in-time -- англ. в\'{о}время, прямо сейчас}-компилятор, генерирующий платформенно-зависимый код.
JVM для своей работы запрашивает у ОС некоторый сегмент оперативной памяти, в котором хранит данные программы. Это хранение происходит «слоями»: JVM для своей работы запрашивает у ОС некоторый сегмент оперативной памяти, в котором хранит данные программы. Это хранение происходит «слоями»:
\begin{enumerate} \begin{enumerate}
@ -125,7 +125,7 @@ JVM самостоятельно осуществляет сборку так н
\label{jvm:structure} \label{jvm:structure}
\end{figure} \end{figure}
На пользовательском уровне важно не только исполнять базовые инструкции программы, но чтобы эти базовые инструкции умели как-то взаимодействовать со внешним миром, в том числе другими программами, поэтому JVM интегрирована в JRE - Java Runtime Environment. JRE - это набор из классов и интерфейсов, реализующих На пользовательском уровне важно не только исполнять базовые инструкции программы, но чтобы эти базовые инструкции умели как-то взаимодействовать со внешним миром, в том числе другими программами, поэтому JVM интегрирована в JRE -- Java Runtime Environment. JRE -- это набор из классов и интерфейсов, реализующих
\begin{itemize} \begin{itemize}
\item возможности сетевого взаимодействия; \item возможности сетевого взаимодействия;
\item рисование графики и графический пользовательский интерфейс; \item рисование графики и графический пользовательский интерфейс;
@ -166,7 +166,7 @@ Java Development Kit является изрядно дополненным сп
\subsubsection{Задания для самопроверки} \subsubsection{Задания для самопроверки}
\begin{enumerate} \begin{enumerate}
\item JVM и JRE - это одно и тоже? \item JVM и JRE -- это одно и тоже?
\item Что входит в состав JDK, но не входят в состав JRE? \item Что входит в состав JDK, но не входят в состав JRE?
\item Утечки памяти \item Утечки памяти
\begin{itemize} \begin{itemize}
@ -201,13 +201,13 @@ public class Main {
\textbf{Обычный проект} состоит из пакетов, которые содержат классы, которые в свою очередь как-то связаны между собой и содержат код, который исполняется. \textbf{Обычный проект} состоит из пакетов, которые содержат классы, которые в свою очередь как-то связаны между собой и содержат код, который исполняется.
\begin{itemize} \begin{itemize}
\item Пакеты. Пакеты объединяют классы по смыслу. Классы, находящиеся в одном пакете доступны друг другу даже если находятся в разных проектах. У пакетов есть правила именования: обычно это обратное доменное имя (например, для gb.ru это будет ru.gb), название проекта, и далее уже внутренняя структура. Пакеты именуют строчными латинскими буквами. Чтобы явно отнести класс к пакету, нужно прописать в классе название пакета после оператора \code{package}. \item Пакеты. Пакеты объединяют классы по смыслу. Классы, находящиеся в одном пакете доступны друг другу даже если находятся в разных проектах. У пакетов есть правила именования: обычно это обратное доменное имя (например, для gb.ru это будет ru.gb), название проекта, и далее уже внутренняя структура. Пакеты именуют строчными латинскими буквами. Чтобы явно отнести класс к пакету, нужно прописать в классе название пакета после оператора \code{package}.
\item Классы. Основная единица исходного кода программы. Одному файлу следует сопоставлять один класс. Название класса - это имя существительное в именительном падеже, написанное с заглавной буквы. Если требуется назвать класс в несколько слов, применяют UpperCamelCase. \item Классы. Основная единица исходного кода программы. Одному файлу следует сопоставлять один класс. Название класса -- это имя существительное в именительном падеже, написанное с заглавной буквы. Если требуется назвать класс в несколько слов, применяют UpperCamelCase.
\item \code{public static void main(String[] args)}. Метод, который является точкой входа в программу. Должен находиться в публичном классе. При создании этого метода важно полностью повторить его сигнатуру и обязательно написать его с название со строчной буквы. \item \code{public static void main(String[] args)}. Метод, который является точкой входа в программу. Должен находиться в публичном классе. При создании этого метода важно полностью повторить его сигнатуру и обязательно написать его с название со строчной буквы.
\item Комментарии. Это часть кода, которую игнорирует компилятор при преобразовании исходного кода. Комментарии бывают: \item Комментарии. Это часть кода, которую игнорирует компилятор при преобразовании исходного кода. Комментарии бывают:
\begin{itemize} \begin{itemize}
\item \code{// comment} - до конца строки. Самый простой и самый часто используемый комментарий. \item \code{// comment} -- до конца строки. Самый простой и самый часто используемый комментарий.
\item \code{/* comment */} - внутристрочный или многострочный. Никогда не используйте его внутри строк, несмотря на то, что это возможно. \item \code{/* comment */} -- внутристрочный или многострочный. Никогда не используйте его внутри строк, несмотря на то, что это возможно.
\item \code{/** comment */} - комментарий-документация. Многострочный. Из него утилитой Javadoc создаётся веб-страница с комментарием. \item \code{/** comment */} -- комментарий-документация. Многострочный. Из него утилитой Javadoc создаётся веб-страница с комментарием.
\end{itemize} \end{itemize}
\end{itemize} \end{itemize}
@ -368,7 +368,7 @@ Here is your number: 4.
\item \code{-subpackages} нужно ли заглядывать в пакеты-с-пакетами; \item \code{-subpackages} нужно ли заглядывать в пакеты-с-пакетами;
\end{itemize} \end{itemize}
Часто необходимо указать, в какой кодировке записан файл исходных кодов, и в какой кодировке должна быть выполнена документация (например, файлы исходников на языке Java всегда сохраняются в кодировке \nom{UTF-8}{(от англ. Unicode Transformation Format, 8-bit — «формат преобразования Юникода, 8-бит») — распространённый стандарт кодирования символов, позволяющий более компактно хранить и передавать символы Юникода, используя переменное количество байт (от 1 до 4), и обеспечивающий полную обратную совместимость с 7-битной кодировкой ASCII. Кодировка UTF-8 сейчас является доминирующей в веб-пространстве. Она также нашла широкое применение в UNIX-подобных операционных системах.}, а основная кодировка для ОС Windows - \nom{cp1251}{набор символов и кодировка, являющаяся стандартной 8-битной кодировкой для русских версий Microsoft Windows до 10-й версии. Была создана на базе кодировок, использовавшихся в ранних русификаторах Windows.}) Часто необходимо указать, в какой кодировке записан файл исходных кодов, и в какой кодировке должна быть выполнена документация (например, файлы исходников на языке Java всегда сохраняются в кодировке \nom{UTF-8}{(от англ. Unicode Transformation Format, 8-bit — «формат преобразования Юникода, 8-бит») — распространённый стандарт кодирования символов, позволяющий более компактно хранить и передавать символы Юникода, используя переменное количество байт (от 1 до 4), и обеспечивающий полную обратную совместимость с 7-битной кодировкой ASCII. Кодировка UTF-8 сейчас является доминирующей в веб-пространстве. Она также нашла широкое применение в UNIX-подобных операционных системах.}, а основная кодировка для ОС Windows -- \nom{cp1251}{набор символов и кодировка, являющаяся стандартной 8-битной кодировкой для русских версий Microsoft Windows до 10-й версии. Была создана на базе кодировок, использовавшихся в ранних русификаторах Windows.})
\begin{itemize} \begin{itemize}
\item \code{-locale ru_RU} язык документации (для правильной расстановки переносов и разделяющих знаков); \item \code{-locale ru_RU} язык документации (для правильной расстановки переносов и разделяющих знаков);
\item \code{-encoding} кодировка исходных текстов программы; \item \code{-encoding} кодировка исходных текстов программы;
@ -446,7 +446,7 @@ Docker также не привносит ничего технологичес
RUN mkdir ./out RUN mkdir ./out
\end{lstlisting} \end{lstlisting}
Последнее, что будет сделано при создании образа - запущена компиляция. Последнее, что будет сделано при создании образа -- запущена компиляция.
\begin{lstlisting}[style=ASMStyle] \begin{lstlisting}[style=ASMStyle]
RUN javac -sourcepath ./src -d out ./src/ru/gb/dj/Main.java RUN javac -sourcepath ./src -d out ./src/ru/gb/dj/Main.java
\end{lstlisting} \end{lstlisting}
@ -460,7 +460,7 @@ Docker-образ и, как следствие, Docker-контейнеры в
Часто команды разработчиков эмулируют таким образом реальный продакшн сервер, используя в качестве исходного образа не JDK, а образ целевой ОС, вручную устанавливают на ней JDK, запуская далее своё приложение. Часто команды разработчиков эмулируют таким образом реальный продакшн сервер, используя в качестве исходного образа не JDK, а образ целевой ОС, вручную устанавливают на ней JDK, запуская далее своё приложение.
\subsection*{Домашнее задание} \subsection*{Практическое задание}
\begin{itemize} \begin{itemize}
\item Создать проект из трёх классов (основной с точкой входа и два класса в другом пакете), которые вместе должны составлять одну программу, позволяющую производить четыре основных математических действия и осуществлять форматированный вывод результатов пользователю; \item Создать проект из трёх классов (основной с точкой входа и два класса в другом пакете), которые вместе должны составлять одну программу, позволяющую производить четыре основных математических действия и осуществлять форматированный вывод результатов пользователю;
\item Скомпилировать проект, а также создать для этого проекта стандартную веб-страницу с документацией ко всем пакетам; \item Скомпилировать проект, а также создать для этого проекта стандартную веб-страницу с документацией ко всем пакетам;

View File

@ -3,7 +3,6 @@
\begin{document} \begin{document}
\pagestyle{plain} \pagestyle{plain}
\sloppy \sloppy
%\setcounter{tocdepth}{3}
\tableofcontents \tableofcontents
\section{Специализация: данные и функции} \section{Специализация: данные и функции}
\subsection{В предыдущем разделе} \subsection{В предыдущем разделе}
@ -21,9 +20,9 @@
\begin{itemize} \begin{itemize}
\item \nom{Метод}{функция в языке программирования, принадлежащая классу}; \item \nom{Метод}{функция в языке программирования, принадлежащая классу};
\item \nom{Типизация}{классификация по типам}; \item \nom{Типизация}{классификация по типам};
\item \nom{Переполнение}{целочи́сленное переполне́ние (англ. integer overflow) — ситуация в компьютерной арифметике, при которой вычисленное в результате операции значение не может быть помещено в тип данных}; \item \nom{Переполнение}{целочисленное переполнение (англ. integer overflow) — ситуация в компьютерной арифметике, при которой вычисленное в результате операции значение не может быть помещено в тип данных};
\item \nom{Инициализация}{одновременной объявление переменной и присваивание ей значения}; \item \nom{Инициализация}{одновременной объявление переменной и присваивание ей значения};
\item \nom{Идентификатор}{идентификатор переменной - название переменной, по которому возможно получить доступ к области памяти, соответствующей этой переменной}; \item \nom{Идентификатор}{идентификатор переменной -- название переменной, по которому возможно получить доступ к области памяти, соответствующей этой переменной};
\item \nom{Typecasting}{преобразование типов переменных в типизированных языках программирования}; \item \nom{Typecasting}{преобразование типов переменных в типизированных языках программирования};
\item \nom{Массив}{структура данных, хранящая набор значений в непрерывной области памяти}; \item \nom{Массив}{структура данных, хранящая набор значений в непрерывной области памяти};
\end{itemize} \end{itemize}
@ -40,26 +39,26 @@
\end{frm} \end{frm}
\begin{itemize} \begin{itemize}
\item Статическая - у каждой переменной должен быть тип, и этот тип изменить нельзя. Этому свойству противопоставляется динамическая типизация; \item Статическая -- у каждой переменной должен быть тип, и этот тип изменить нельзя. Этому свойству противопоставляется динамическая типизация.
\item Явная - при создании переменной ей обязательно необходимо присвоить какой-то тип, явно написав это в коде. В более поздних версиях языка (с 9й) стало возможным инициализировать переменные типа \code{var}, обозначающий нужный тип тогда, когда его возможно однозначно вывести из значения справа. Бывают языки с неявной типизацией, например, Python; \item Явная -- при создании переменной ей обязательно необходимо присвоить какой-то тип, явно написав это в коде. В более поздних версиях языка (с девятой) стало возможным инициализировать переменные типа \code{var}, обозначающего нужный тип тогда, когда его возможно однозначно вывести из значения справа\footnote{аналог типа \code{auto} в языке C++}. Бывают языки с неявной типизацией, например, Python.
\item Строгая(сильная) - невозможно смешивать разнотипные данные. С другой стороны, существует JavaScript, в котором запись \code{2 + true} выдаст результат \code{3}. \item Строгая(сильная) -- невозможно смешивать разнотипные данные. С другой стороны, существует, например, JavaScript, в котором запись \code{2 + true} выдаст результат \code{3}.
\end{itemize} \end{itemize}
\subsubsection{Антипаттерн «магические числа»} \subsubsection{Антипаттерн «магические числа»}
Почти во всех примерах, которые используются для обучения, можно увидеть так называемый антипаттерн - плохой стиль для написания кода. Числа, которые находятся справа от оператора присваивания используются в коде без пояснений. Такой антипаттерн называется «магическое число». Магическое, потому что непонятно, что это за число, почему это число именно такое и что будет, если это число изменить. Почти во всех примерах, которые используются для обучения, можно увидеть так называемый антипаттерн -- плохой стиль для написания кода. Числа, которые находятся справа от оператора присваивания используются в коде без пояснений. Такой антипаттерн называется «магическое число». Магическое, потому что непонятно, что это за число, почему это число именно такое и что будет, если это число изменить.
Так лучше не делать. Заранее нужно сказать, что рекомендуется помещать все числа в коде в именованные константы, которые хранятся в начале файла. Плюсом такого подхода является возможность легко корректировать значения переменных в достаточно больших проектах. В реальных проектах так лучше не делать. Заранее нужно сказать, что рекомендуется помещать все числа в коде в именованные константы, которые хранятся в начале файла. Плюсом такого подхода является возможность легко корректировать значения переменных в достаточно больших проектах.
Например, в вашем коде несколько тысяч строк, а какое-то число, скажем, возраст совершеннолетия, число 18, использовалось несколько десятков раз. При использовании приложения в стране, где совершеннолетием считается $21$ год вы должны будете перечитывать весь код в поисках магических «18» и исправить их на «21». В этом вопросе будет также важно не запутаться, действительно ли это $18$, которые означают совершеннолетие, а не количество карманов в жилетке Анатолия Вассермана\footnote{мы то знаем, что их 26}. Например, в вашем коде несколько тысяч строк, а какое-то число, скажем, возраст совершеннолетия, число 18, использовалось несколько десятков раз. При использовании приложения в стране, где совершеннолетием считается 21 год вы должны будете перечитывать весь код в поисках магических «18» и исправить их на «21». В этом вопросе будет также важно не запутаться, действительно ли это 18, которые означают совершеннолетие, а не количество карманов в жилетке Анатолия Вассермана\footnote{мы то знаем, что их 26}.
В случае с константой изменить число нужно в одном месте. В случае с константой изменить число нужно в одном месте.
\subsection{Примитивные типы данных} \subsection{Примитивные типы данных}
Все данные в Java делятся на две основные категории: примитивные и ссылочные. Таблица \hrf{tab:types} демонстрирует все восемь примитивных типов языка и их размерности. Чтобы отправить на хранение какие-то данные используется оператор присваивания. Присваивание в программировании - это не тоже самое, что математическое равенство, демонстрирующее тождественность, а полноценная операция. Все данные в Java делятся на две основные категории: примитивные и ссылочные. Таблица \hrf{tab:types} демонстрирует все восемь примитивных типов языка и их размерности. Чтобы отправить на хранение какие-то данные используется оператор присваивания. Присваивание в программировании -- это не тоже самое, что математическое равенство, демонстрирующее тождественность, а полноценная операция.
Все присваивания всегда происходят справа налево, то есть сначала вычисляется правая часть, а потом результат вычислений присваивается левой. Исключений нет, именно поэтому в левой части не может быть никаких вычислений. Все присваивания всегда происходят справа налево, то есть сначала вычисляется правая часть, а потом результат вычислений присваивается левой. Исключений нет, именно поэтому в левой части не может быть никаких вычислений.
\begin{table} \begin{table}[H]
\centering \centering
\begin{tabular}{|p{17mm}|p{80mm}|p{55mm}|} \begin{tabular}{|p{17mm}|p{80mm}|p{55mm}|}
\hline \hline
@ -86,18 +85,20 @@
\label{tab:types} \label{tab:types}
\end{table} \end{table}
% TODO По умолчанию, создавая примитивную переменную ей из-за примитивности данных, присваивается начальное значение - ноль для числовых и ложь для булева. Что ещё раз доказывает, что мы храним там просто числа в двоичной системе счисления, мы не можем туда положить пустоту, а ноль - это тоже значение. \begin{frm}\info
По умолчанию, создавая примитивную переменную, ей из-за примитивности данных, Java присваивает начальное значение -- ноль для числовых и ложь для булева. Что ещё раз доказывает, что мы храним там просто числа в двоичной системе счисления, мы не можем туда положить пустоту, а ноль -- это тоже значение.
\end{frm}
Шесть из восьми типов имеет диапазон значений, а значит основное их отличие в объёме занимаемой памяти. У \code{double} и \code{float} тоже есть диапазоны, но они заключаются в точности представления дробной части. Диапазоны означают, что если попытаться положить в переменную меньшего типа большее значение, произойдёт «переполнение переменной». Шесть из восьми типов имеет диапазон значений, а значит основное их отличие в объёме занимаемой памяти. У \code{double} и \code{float} тоже есть диапазоны, но они заключаются в точности представления дробной части. Диапазоны означают, что если попытаться положить в переменную меньшего типа большее значение, произойдёт «переполнение переменной».
\subsubsection{Переполнение целочисленных переменных} \subsubsection{Переполнение целочисленных переменных}
Чем именно чревато переполнение переменной легче показать на примере (по ссылке - \href{https://habr.com/ru/company/pvs-studio/blog/306748/}{расследование} крушения ракеты из-за переполнения переменной) Чем именно чревато переполнение переменной, легче показать на примере (по ссылке -- \href{https://habr.com/ru/company/pvs-studio/blog/306748/}{расследование} крушения ракеты из-за переполнения переменной)
\begin{frm} \excl Переполнение переменных не распознаётся компилятором. \end{frm} \begin{frm} \excl Переполнение переменных не распознаётся компилятором. \end{frm}
Если создать переменную типа byte, диапазон которого от $[-128, +127]$, и присвоить этой переменной значение $200$ произойдёт переполнение, как если попытаться влить пакет молока в напёрсток. Если создать переменную типа \code{byte}, диапазон которого от $[-128, +127]$, и присвоить этой переменной значение $200$ произойдёт переполнение, как если попытаться влить пакет молока в напёрсток.
\begin{frm} \info Переполнение переменной - это ситуация, в которой происходит попытка положить большее значение в переменную меньшего типа. \end{frm} \begin{frm} \info Переполнение переменной -- это ситуация, в которой происходит попытка положить большее значение в переменную меньшего типа. \end{frm}
Важным вопросом при переполнении остаётся следующий: какое в переполненной переменной останется значение? Максимальное, $127$? $200 - 127 = 73$? Какой-то мусор? Каждый язык, а зачастую и разные компиляторы одного языка ведут себя в этом вопросе по разному. Важным вопросом при переполнении остаётся следующий: какое в переполненной переменной останется значение? Максимальное, $127$? $200 - 127 = 73$? Какой-то мусор? Каждый язык, а зачастую и разные компиляторы одного языка ведут себя в этом вопросе по разному.
@ -112,13 +113,13 @@
\subsubsection{Задание для самопроверки} \subsubsection{Задание для самопроверки}
\begin{enumerate} \begin{enumerate}
\item Возможно ли объявить в Java целочисленную переменную и присвоить ей дробное значение? \item Возможно ли объявить в Java целочисленную переменную и присвоить ей дробное значение?
\item Магическое число - это: \item Магическое число -- это:
\begin{enumerate} \begin{enumerate}
\item числовая константа без пояснений; \item числовая константа без пояснений;
\item число, помогающее в вычислениях; \item число, помогающее в вычислениях;
\item числовая константа, присваиваемая при объявлении переменной. \item числовая константа, присваиваемая при объявлении переменной.
\end{enumerate} \end{enumerate}
\item Переполнение переменной - это: \item Переполнение переменной -- это:
\begin{enumerate} \begin{enumerate}
\item слишком длинное название переменной; \item слишком длинное название переменной;
\item слишком большое значение переменной; \item слишком большое значение переменной;
@ -127,11 +128,11 @@
\end{enumerate} \end{enumerate}
\subsubsection{Бинарное (битовое) представление данных} \subsubsection{Бинарное (битовое) представление данных}
После разговора о переполнении, нельзя не сказать о том, что именно переполняется. Далее будут представлены сведения которые касаются не только языка Java но и любого другого языка программирования. Эти сведения помогут разобраться в деталях того как хранится значение переменной в программе и как, в целом, происходит работа компьютерной техники. После информации о переполнении, нельзя не сказать о том, что именно переполняется. Далее будут представлены сведения которые касаются не только языка Java но и любого другого языка программирования. Эти сведения помогут разобраться в деталях того как хранится значение переменной в программе и как, в целом, происходит работа компьютерной техники.
\begin{frm} \info Все современные компьютеры, так или иначе работают от электричества и являются примитивными по своей сути устройствами, которые понимают только два состояния: есть напряжение в электрической цепи или нет. Эти два состояния принято записывать в виде 1 и 0, соответственно. \end{frm} \begin{frm} \info Все современные компьютеры, так или иначе работают от электричества и являются примитивными по своей сути устройствами, которые понимают только два состояния: есть напряжение в электрической цепи или нет. Эти два состояния принято записывать в виде 1 и 0, соответственно. \end{frm}
Все данные в любой программе - это единицы и нули. Данные в программе на Java не исключение, удобнее всего это явление рассматривать на примере примитивных данных. Поскольку в компьютере можно оперировать только двумя значениями то естественным образом используется двоичная система счисления. Все данные в любой программе -- это единицы и нули. Данные в программе на Java не исключение, удобнее всего это явление рассматривать на примере примитивных данных. Поскольку в компьютере можно оперировать только двумя значениями то естественным образом используется двоичная система счисления.
\begin{table}[H] \begin{table}[H]
\centering \centering
@ -165,21 +166,21 @@
Двоичная система счисления это система счисления с основанием два. Существуют и другие системы счисления, например, восьмеричная, но сейчас она отходит на второй план полностью уступая своё место шестнадцатеричной системе счисления. Каждая цифра в десятичной записи числа называется разрядом, аналогично в двоичной записи чисел каждая цифра тоже называется разрядом, но для компьютерной техники этот разряд называется битом. Двоичная система счисления это система счисления с основанием два. Существуют и другие системы счисления, например, восьмеричная, но сейчас она отходит на второй план полностью уступая своё место шестнадцатеричной системе счисления. Каждая цифра в десятичной записи числа называется разрядом, аналогично в двоичной записи чисел каждая цифра тоже называется разрядом, но для компьютерной техники этот разряд называется битом.
\begin{frm} \begin{frm}
\info Одна единица или ноль - это один \textbf{бит} передаваемой или хранимой информации. \info Одна единица или ноль -- это один \textbf{бит} передаваемой или хранимой информации.
\end{frm} \end{frm}
Биты принято собирать в группы по восемь штук, по восемь разрядов, эти группы называются \textbf{байт}. В языке Java возможно оперировать минимальной единицей информации, такой как байт для этого есть соответствующий тип. Диапазон байта, согласно таблицы $[-128, +127]$, то есть байт информации может в себе содержать ровно 256 значений. Само число $127$ в двоичной записи это семиразрядное число, все разряды которого единицы (то есть байт выглядит как \code{01111111}). Последний, восьмой, самый старший бит, определяет знак числа\footnote{Здесь можно начать долгий и скучный разговор о схемотехнике и хранении отрицательных чисел с применением техники дополнительного кода.}. Достаточно знать формулу расчёта записи отрицательных значений: Биты принято собирать в группы по восемь штук, по восемь разрядов, эти группы называются \textbf{байт}. В языке Java возможно оперировать минимальной единицей информации, такой как байт для этого есть соответствующий тип. Диапазон байта, согласно таблицы $[-128, +127]$, то есть байт информации может в себе содержать ровно 256 значений. Само число $127$ в двоичной записи это семиразрядное число, все разряды которого единицы (то есть байт выглядит как \code{01111111}). Последний, восьмой, самый старший бит, определяет знак числа\footnote{Для более детального понимания данной темы желательно ознакомиться с информацией о цифровой схемотехнике и хранении отрицательных чисел с применением техники дополнительного кода.}. Для нас достаточно знать формулу расчёта записи отрицательных значений:
\begin{enumerate} \begin{enumerate}
\item в прямой записи поменять все нули на единицы и единицы на нули; \item в прямой записи поменять все нули на единицы и единицы на нули;
\item поставить старший бит в единицу. \item поставить старший бит в единицу.
\end{enumerate} \end{enumerate}
Так возможно получить на единицу меньшее отрицательное число, то есть преобразовав 0 получим -1, 1 будет -2, 2 станет -3 и так далее. Так возможно получить на единицу меньшее отрицательное число, то есть преобразовав 0 получим -1, 1 будет -2, 2 станет -3 и так далее.
Числа б\'{о}льших разрядностей могут хранить б\'{о}льшие значения, теперь преобразование диапазонов из десятичной системы счисления в двоичную покажет что \code{byte} это один байт, \code{short} это два байта, то есть 16 бит, \code{int} это 4 байта то есть 32 бита, а \code{long} это 8 байт или 64 бита хранения информации. Числа б\'{о}льших разрядностей могут хранить б\'{о}льшие значения, таким образом, преобразование диапазонов из десятичной системы счисления в двоичную покажет что \code{byte} это один байт, \code{short} это два байта, то есть 16 бит, \code{int} это 4 байта то есть 32 бита, а \code{long} это 8 байт или 64 бита хранения информации.
\subsubsection{Задания для самопроверки} \subsubsection{Задания для самопроверки}
\begin{enumerate} \begin{enumerate}
\item Возможно ли число 3000000000 (3 миллиарда) записать в двоичном представлении? \item Возможно ли число 3000000000 (три миллиарда) записать в двоичном представлении?
\item Как вы думаете, почему шестнадцатеричная система счисления вытеснила восьмеричную? \item Как вы думаете, почему шестнадцатеричная система счисления вытеснила восьмеричную?
\end{enumerate} \end{enumerate}
@ -191,11 +192,11 @@
Значения в целочисленных типах могут быть только целые, никак и никогда невозможно присвоить им дробных значений. Про эти типы следует помнить следующее: Значения в целочисленных типах могут быть только целые, никак и никогда невозможно присвоить им дробных значений. Про эти типы следует помнить следующее:
\begin{itemize} \begin{itemize}
\item \code{int} - это самый часто используемый тип. Если сомневаетесь, какой целочисленный тип использовать, используйте \code{int}; \item \code{int} -- это самый часто используемый тип. Если сомневаетесь, какой целочисленный тип использовать, используйте \code{int};
\item все целые числа, которые пишутся в коде - это \code{int}, даже если вы пытаетесь их присвоить переменной другого типа. \item все целые числа, которые пишутся в коде -- это \code{int}, даже если вы пытаетесь их присвоить переменной другого типа.
\end{itemize} \end{itemize}
Как \code{int} преобразуется в меньше типы? Если написать цифрами справа число, которое может поместиться в переменную меньшего типа слева, то статический анализатор кода его пропустит, а компилятор преобразует в меньший тип автоматически (строка 9 на рис. \hrf{pic:byte-overflow}). Как \code{int} преобразуется в меньше типы? Если написать цифрами \textit{справа} число, которое может поместиться в переменную меньшего типа \textit{слева}, то статический анализатор кода его пропустит, а компилятор преобразует в меньший тип автоматически (строка 9 на рис. \hrf{pic:byte-overflow}).
\begin{figure}[H] \begin{figure}[H]
\centering \centering
\includegraphics[width=12cm]{jc-02-byte-overflow.png} \includegraphics[width=12cm]{jc-02-byte-overflow.png}
@ -203,7 +204,7 @@
\label{pic:byte-overflow} \label{pic:byte-overflow}
\end{figure} \end{figure}
Как видно, к маленькому \code{byte} успешно присваивается \code{int}. Если же написать число которое больше типа слева и, соответственно, поместиться не может, среда разработки выдает предупреждение компилятора, что ожидался \code{byte}, а передан \code{int} (строка 10 рис \hrf{pic:byte-overflow}). Как видно, к маленькому \code{byte} успешно присваивается \code{int}. Если же написать число которое больше типа слева и, соответственно, поместиться не может, среда разработки выдает предупреждение компилятора, что ожидался \code{byte}, а передан \code{int} (строка 10 рис. \hrf{pic:byte-overflow}).
Часто нужно записать в виде числа какое-то значение большее чем может принимать \code{int}, и явно присвоить начальное значение переменной типа \code{long}. Часто нужно записать в виде числа какое-то значение большее чем может принимать \code{int}, и явно присвоить начальное значение переменной типа \code{long}.
@ -214,7 +215,7 @@
\label{pic:int-overflow} \label{pic:int-overflow}
\end{figure} \end{figure}
В примере на рис. \hrf{pic:int-overflow} показана попытка присвоить значение 5000000000 переменной типа \code{long}. Из текста ошибки ясно, что невозможно положить такое большое значение в переменную типа \code{int}, а это значит, что справа \code{int}. Почему большой \code{int} без проблем присваивается к маленькому байту? В примере на рис. \hrf{pic:int-overflow} показана попытка присвоить значение 5000000000 (пять миллиардов) переменной типа \code{long}. Из текста ошибки ясно, что невозможно положить такое большое значение в переменную типа \code{int}, а это значит, что справа \code{int}. Почему большой \code{int} без проблем присваивается к маленькому байту?
\begin{figure}[H] \begin{figure}[H]
\centering \centering
@ -223,21 +224,25 @@
\label{pic:overflow-solution} \label{pic:overflow-solution}
\end{figure} \end{figure}
На рис. \hrf{pic:overflow-solution} продемонстрировано, что аналогичная ситуация возникает с типами \code{float} и \code{double}. Все дробные числа, написанные в коде - это \code{double}, поэтому положить их во \code{float} без дополнительных усилий невозможно. В этих случаях к написанному справа числу нужно добавить явное указание на его тип. Для \code{long} пишем \code{L}, а для \code{float} - \code{f}. Чаще всего \code{L} пишут заглавную, чтобы подчеркнуть, что тип больше, а \code{f} пишут маленькую, чтобы подчеркнуть, что мы уменьшаем тип. Но регистр в этом конкретном случае значения не имеет, можно писать и так и так. На рис. \hrf{pic:overflow-solution} продемонстрировано, что аналогичная ситуация возникает с типами \code{float} и \code{double}. Все дробные числа, написанные в коде -- это \code{double}, поэтому положить их во \code{float} без дополнительных усилий невозможно. В этих случаях к написанному справа числу нужно добавить явное указание на его тип.
\begin{frm}\excl
Для \code{long} пишем \code{L}, а для \code{float} -- \code{f}. Чаще всего \code{L} пишут заглавную, чтобы подчеркнуть, что тип больше, а \code{f} пишут маленькую, чтобы подчеркнуть, что мы уменьшаем тип. Но регистр в этом конкретном случае значения не имеет, можно писать и так и так.
\end{frm}
\subsubsection{Числа с плавающей запятой (точкой)} \subsubsection{Числа с плавающей запятой (точкой)}
Как видно из таблицы \hrf{tab:types}, два из восьми типов не имеют диапазонов значений. Это связано с тем, что диапазоны значений флоута и дабла заключаются не в величине возможных хранимых чисел, а в точности этих чисел после запятой. Как видно из таблицы \hrf{tab:types}, два из восьми типов не имеют диапазонов значений. Это связано с тем, что диапазоны значений \code{float} и \code{double} заключаются не в величине возможных хранимых чисел, а в точности этих чисел после запятой.
\begin{frm} \info Числа с плавающей запятой в англоязычной литературе называются числа с плавающей точкой (от англ. floating point). Такое различие связано с тем, что в русскоязычной литературе принято отделять дробную часть числа запятой, а в европейской и американской - точкой. \end{frm} \begin{frm} \info Числа с плавающей запятой в англоязычной литературе называются числа с плавающей точкой (от англ. floating point). Такое различие связано с тем, что в русскоязычной литературе принято отделять дробную часть числа запятой, а в европейской и американской -- точкой. \end{frm}
Хранение чисел с плавающей запятой\footnote{хорошо и подробно, но на С в посте на \href{https://habr.com/ru/post/112953/}{Хабре}.} работает по стандарту IEEE 754 (1985 г). Для работы с числами с плавающей запятой на аппаратурном уровне к обычному процессору добавляют математический сопроцессор (FPU, floating point unit). Хранение чисел с плавающей запятой\footnote{хорошо и подробно, но на С, в посте на \href{https://habr.com/ru/post/112953/}{Хабре}.} работает по стандарту IEEE 754 (1985 г). Для работы с числами с плавающей запятой на аппаратурном уровне к обычному процессору добавляют математический сопроцессор (FPU, floating point unit).
\begin{figure}[H] \begin{figure}[H]
\centering \centering
\begin{subfigure}[b]{0.48\textwidth} \begin{subfigure}[b]{0.48\textwidth}
\centering \centering
\def\svgwidth{\textwidth} \def\svgwidth{\textwidth}
\input{pics/jc-02-float-struct.pdf_tex} \includesvg{pics/jc-02-float-struct.svg}
\caption{double} \caption{double}
\label{pic:float-double} \label{pic:float-double}
\end{subfigure} \end{subfigure}
@ -245,7 +250,7 @@
\begin{subfigure}[b]{0.48\textwidth} \begin{subfigure}[b]{0.48\textwidth}
\centering \centering
\def\svgwidth{\textwidth} \def\svgwidth{\textwidth}
\input{pics/jc-02-float-struct32.pdf_tex} \includesvg{pics/jc-02-float-struct32.svg}
\caption{float} \caption{float}
\label{pic:float-float} \label{pic:float-float}
\end{subfigure} \end{subfigure}
@ -253,7 +258,7 @@
\label{pic:float-struct} \label{pic:float-struct}
\end{figure} \end{figure}
Рисунок \hrf{pic:float-struct} демонстрирует, как распределяются биты в числах с плавающей запятой разных разрядностей, где S - Sign (знак), E - Exponent (8(11) разрядов поля порядка, экспонента), M - Mantissa (23(52) бита мантиссы, дробная часть числа). Также на рисунке показана так называемая, мнимая единица, она всегда есть в самом старшем разряде мантиссы, поэтому её всегда подразумевают, но в явном виде не хранят, экономя один бит информации. Рисунок \hrf{pic:float-struct} демонстрирует, как распределяются биты в числах с плавающей запятой разных разрядностей, где S -- Sign (знак), E -- Exponent, 8 (или 11) разрядов поля порядка, экспонента, M -- Mantissa, 23 (или 52) бита мантиссы, дробная часть числа. Также на рисунке показана так называемая, мнимая единица, она всегда есть в самом старшем разряде мантиссы, поэтому её всегда подразумевают, но в явном виде не хранят, экономя один бит информации.
Если попытаться уложить весь стандарт в два предложения, то получится примерно следующее: получить число в соответствующих разрядностях возможно по формулам: Если попытаться уложить весь стандарт в два предложения, то получится примерно следующее: получить число в соответствующих разрядностях возможно по формулам:
\begin{equation*} \begin{equation*}
@ -277,7 +282,7 @@
Отсюда становится очевидно, что чем сложнее мантисса и чем меньше порядок, тем более точные и интересные числа мы можем получить. Отсюда становится очевидно, что чем сложнее мантисса и чем меньше порядок, тем более точные и интересные числа мы можем получить.
\end{frm} \end{frm}
Возьмём для примера число $-0,15625$, чтобы понять как его записывать, откинем знак, это будет единица в разряде, отвечающем за знак, и посчитаем мантиссу с порядком. Представим число как положительное и будем от него последовательно отнимать числа, являющиеся отрицательными степенями двойки, чтобы получить максимально близкое к нулю значение. Возьмём для примера число $-0,15625$, чтобы понять как его записывать, откинем знак, это будет единица в разряде, отвечающем за знак, и посчитаем мантиссу с порядком. Представим число как положительное и будем от него последовательно отнимать числа, являющиеся отрицательными степенями двойки, чтобы получить максимально близкое к нулю значение, но не превысить его.
\begin{equation*} \begin{equation*}
\begin{gathered} \begin{gathered}
@ -287,7 +292,7 @@
Очевидно, что $-1$ и $-2$ степени отнять не получится, поскольку мы явно уходим за границу нуля, а вот $-3$ прекрасно отнимается, значит порядок будет $127-3 = 124$, осталось понять, что получится в мантиссе. Очевидно, что $-1$ и $-2$ степени отнять не получится, поскольку мы явно уходим за границу нуля, а вот $-3$ прекрасно отнимается, значит порядок будет $127-3 = 124$, осталось понять, что получится в мантиссе.
Видим, что оставшееся после первого вычитания ($0,15625 - 0,125$) число - это $2^{-5}$. Значит в мантиссе пишем \code{01} и остальные нули, то есть слева направо указываем, какие степени после $-3$ будут нужны. $-4$ не нужна, а $-5$ нужна. Видим, что оставшееся после первого вычитания ($0,15625 - 0,125$) число -- это $2^{-5}$. Значит в мантиссе пишем \code{01} и остальные нули, то есть слева направо указываем, какие степени после $-3$ будут нужны. $-4$ не нужна, а $-5$ нужна.
Получится, что Получится, что
\begin{equation*} \begin{equation*}
@ -323,7 +328,7 @@
\item Почему нельзя напрямую сравнивать целочисленные данные и числа с плавающей запятой, даже если там точно лежит число без дробной части? \item Почему нельзя напрямую сравнивать целочисленные данные и числа с плавающей запятой, даже если там точно лежит число без дробной части?
\item Внутри переполненной переменной остаётся значение: \item Внутри переполненной переменной остаётся значение:
\begin{enumerate} \begin{enumerate}
\item переданное - максимальное для типа; \item переданное -- максимальное для типа;
\item максимальное для типа; \item максимальное для типа;
\item не определено. \item не определено.
\end{enumerate} \end{enumerate}
@ -378,24 +383,30 @@
\label{table:utf-8-ascii} \label{table:utf-8-ascii}
\end{table} \end{table}
Тип \code{char} единственный беззнаковый целочисленный тип в языке, то есть его старший разряд хранит полезное значение, а не признак положительности. Тип целочисленный но по умолчанию среда исполнения интерпретирует его как символ по таблице utf-8 (см фрагмент в таблице \hrf{table:utf-8-ascii}). В языке Java есть разница между одинарными и двойными кавычками. В одинарных кавычках всегда записывается символ, который на самом деле является целочисленным значением, а в двойных кавычках всегда записывается строка, которая фактически является экземпляром класса \code{String}. Поскольку типизация строгая, то невозможно записать в \code{char} строки, а в строки числа. Тип \code{char} единственный беззнаковый целочисленный тип в языке, то есть его старший разряд хранит полезное значение, а не признак положительности. Тип целочисленный но по умолчанию среда исполнения интерпретирует его как символ по таблице utf-8 (см. фрагмент в таблице \hrf{table:utf-8-ascii}).
\begin{frm}\excl
В языке Java есть разница между одинарными и двойными кавычками.
\end{frm}
В одинарных кавычках всегда записывается символ (\code{char}), который на самом деле является целочисленным значением, а в двойных кавычках всегда записывается строка, которая фактически является экземпляром класса \code{String}. Поскольку типизация строгая, то невозможно записать в \code{char} строки, а в строки числа.
\begin{frm} \info В Java есть три основных понятия, связанных с данными переменными и использованием значений: объявление, присваивание, инициализация. \begin{frm} \info В Java есть три основных понятия, связанных с данными переменными и использованием значений: объявление, присваивание, инициализация.
Для того чтобы \textit{объявить} переменную, нужно написать её тип и название, также часто вместо названия можно встретить термин идентификатор. Для того чтобы \textit{объявить} переменную, нужно написать её тип и название, также часто вместо названия можно встретить термин идентификатор.
Далее в любой момент можно \textit{присвоить} этой переменной значение, то есть необходимо написать идентификатор использовать оператор присваивания и справа написать значение, которое вы хотите присвоить данной переменной, поставить в конце строки точку с запятой. Далее в любой момент можно \textit{присвоить} этой переменной значение, то есть необходимо написать идентификатор, использовать оператор присваивания, и справа написать значение, которое вы хотите присвоить данной переменной. Поставить в конце строки точку с запятой.
Также существует понятие \textit{инициализации} - это когда объединяются на одной строке объявление и присваивание.\end{frm} Также существует понятие \textit{инициализации} -- это когда объединяются на одной строке объявление и присваивание.\end{frm}
\subsubsection{Преобразование типов} \subsubsection{Преобразование типов}
Java - это язык со строгой статической типизацией, но преобразование типов в ней всё равно есть. Простыми словами, преобразование типов - это когда компилятор видит, что типы переменных по разные стороны присваивания разные, начинает разрешать это противоречие. Преобразование типов бывает явное и неявное. Java - это язык со строгой статической типизацией, но преобразование типов в ней всё равно есть. Простыми словами, преобразование типов -- это когда компилятор видит, что типы переменных по разные стороны присваивания разные, начинает разрешать это противоречие, успешно или нет. Преобразование типов бывает явное и неявное. Неявное преобразование типов происходит когда компилятор в состоянии сам преобразовать типы, явное, когда ему нужна помощь.
\begin{frm} \begin{frm}
\info В разговоре или в сообществах можно услышать или прочитать термины тайпкастинг, кастинг, каст, кастануть, и другие производные от английского typecasting. \info В разговоре или в сообществах можно услышать или прочитать термины тайпкастинг, кастинг, каст, кастануть, и другие производные от английского typecasting.
\end{frm} \end{frm}
Неявное преобразование типов происходит, когда присваиваются числа переменным меньшей размерности, чем \code{int}. Число справа это \code{int}, а значит 32 разряда, а слева, например, \code{byte}, и в нём всего 8 разрядов, но ни среда ни компилятор не поругались, потому что значение в большом \code{int} не превысило 8 разрядов маленького \code{byte}. Итак неявное преобразование типов происходит в случаях, когда, «всё и так понятно». В случае, если неявное преобразование невозможно, статический анализатор кода выдаёт ошибку, что ожидался один тип, а был дан другой. Неявное преобразование типов происходит, когда присваиваются числа переменным меньшей размерности, чем \code{int}. Число справа это \code{int}, а значит 32 разряда, а слева, например, \code{byte}, и в нём всего 8 разрядов, но ни среда ни компилятор не «поругались», потому что значение в большом \code{int} не превысило 8 разрядов маленького \code{byte}. Итак неявное преобразование типов происходит в случаях, когда, «всё и так понятно». В случае, если неявное преобразование невозможно, статический анализатор кода выдаёт ошибку, что ожидался один тип, а был дан другой.
Явное преобразование типов происходит, когда мы явно пишем в коде, что некоторое значение должно иметь определённый тип. Этот вариант приведения типов тоже был рассмотрен, когда к числам дописывались типовые квалификаторы \code{L} и \code{f}. Но чаще всего случается, что происходит присваивание переменным не тех значений, которые были написаны в тексте программы, а те, которые получились в результате каких-то вычислений. Явное преобразование типов происходит, когда мы явно пишем в коде, что некоторое значение должно иметь определённый тип. Этот вариант приведения типов тоже был рассмотрен, когда к числам дописывались типовые квалификаторы \code{L} и \code{f}. Но чаще всего случается, что происходит присваивание переменным не тех значений, которые были написаны в тексте программы, а те, которые получились в результате каких-то вычислений.
\begin{figure}[H] \begin{figure}[H]
@ -414,29 +425,29 @@ Java - это язык со строгой статической типизац
\end{figure} \end{figure}
\subsubsection{Константность} \subsubsection{Константность}
Constare - (лат. стоять твёрдо). Константность это свойство неизменяемости. В Java ключевое слово \code{const} не реализовано, хоть и входит в список ключевых, зарезервированных. Константы создаются при помощи ключевого слова \code{final}. Ключевое слово файнал возможно применять не только с примитивами, но и со ссылочными типами, методами, классами. Constare -- (лат. стоять твёрдо). Константность это свойство неизменяемости. В Java ключевое слово \code{const} не реализовано, хоть и входит в список ключевых, зарезервированных. Константы создаются при помощи ключевого слова \code{final}. Ключевое слово \code{final} возможно применять не только с примитивами, но и со ссылочными типами, методами, классами.
\begin{frm} \begin{frm}
\info Константа - это переменная или идентификатор с конечным значением. \info Константа -- это переменная или идентификатор с конечным значением.
\end{frm} \end{frm}
\subsubsection{Задания для самопроверки} \subsubsection{Задания для самопроверки}
\begin{enumerate} \begin{enumerate}
\item Какая таблица перекодировки используется для представления символов? \item Какая таблица перекодировки используется для представления символов?
\item Каких действий требует от программиста явное преобразование типов? \item Каких действий требует от программиста явное преобразование типов?
\item какое значение будет содержаться в переменной a после выполнения строки int а = 10.0f/3.0f; \item какое значение будет содержаться в переменной a после выполнения строки \code{int а = 10.0f/3.0f;}
\end{enumerate} \end{enumerate}
\subsection{Ссылочные типы данных, массивы} \subsection{Ссылочные типы данных, массивы}
Ссылочные типы данных - это все типы данных, кроме восьми перечисленных примитивных. Самым простым из ссылочных типов является массив. Фактически массив выведен на уровень языка и не имеет специального ключевого слова. Ссылочные типы данных -- это все типы данных, кроме восьми перечисленных примитивных. Самым простым из ссылочных типов является массив. Фактически, массив выведен на уровень языка и не имеет специального ключевого слова.
Ссылочные типы отличаются от примитивных местом хранения информации. В примитивах данные хранятся там, где существует переменная и где написан её идентификатор, а по идентификатору ссылочного типа хранится не значение, а ссылка. Ссылку можно представить как ярлык на рабочем столе, то есть очевидно, что непосредственная информация хранится не там, где написан идентификатор. Такое явное разделение идентификатора переменной и данных важно помнить и понимать при работе с ООП. Ссылочные типы отличаются от примитивных местом хранения информации. В \textit{примитивах} данные хранятся там, где существует переменная и где написан её идентификатор, а по идентификатору \textit{ссылочного} типа хранится не значение, а ссылка. Ссылку можно представить как ярлык на рабочем столе, то есть, очевидно, что непосредственная информация хранится не там, где написан идентификатор. Такое явное разделение идентификатора переменной и данных важно помнить и понимать при работе с ООП.
\begin{frm} \info \textbf{Массив} - это единая, сплошная область данных, в связи с чем в массивах возможно осуществление доступа по индексу \end{frm} \begin{frm} \info \textbf{Массив} -- это единая, сплошная область данных, в связи с чем в массивах возможно осуществление доступа по индексу \end{frm}
Самый младший индекс любого массива - ноль, поскольку \textbf{индекс} - это значение смещения по элементам относительно начального адреса массива. То есть, для получения самого первого элемента нужно сместиться на ноль шагов. Очевидно, что самый последний элемент в массиве из десяти значений, будет храниться по девятому индексу. Самый младший индекс любого массива -- \textit{ноль}, поскольку \textbf{индекс} -- это значение смещения по элементам относительно начального адреса массива. То есть, для получения самого первого элемента нужно сместиться на ноль шагов. Очевидно, что самый последний элемент в массиве из десяти значений, будет храниться по \textit{девятому} индексу.
Массивы возможно создавать несколькими способами (листинг \hrf{lst:array-init}). В общем виде объявление - это тип, квадратные скобки как обозначение того, что это будет массив из переменных этого типа, идентификатор (строка \hrf{codeline:arr-define}). Инициализировать массив можно либо ссылкой на другой массив (строка \hrf{codeline:arr-link}), пустым массивом (строка \hrf{codeline:arr-new}) или заранее заданными значениями, записанными через запятую в фигурных скобках (строка \hrf{codeline:arr-values}). Присвоить в процессе работы идентификатору возможно только значение ссылки из другого идентификатора или новый пустой массив. Массивы возможно создавать несколькими способами (листинг \hrf{lst:array-init}). В общем виде объявление -- это тип, квадратные скобки как обозначение того, что это будет массив из переменных этого типа, идентификатор (строка \hrf{codeline:arr-define}). Инициализировать массив можно либо ссылкой на другой массив (строка \hrf{codeline:arr-link}), пустым массивом (строка \hrf{codeline:arr-new}) или заранее заданными значениями, записанными через запятую в фигурных скобках (строка \hrf{codeline:arr-values}). Присвоить в процессе работы идентификатору возможно только значение ссылки из другого идентификатора или новый пустой массив.
\begin{lstlisting}[language=Java,style=JCodeStyle,caption={Объявление массива},label={lst:array-init}] \begin{lstlisting}[language=Java,style=JCodeStyle,caption={Объявление массива},label={lst:array-init}]
int[] array0;<@ \label{codeline:arr-define} @> int[] array0;<@ \label{codeline:arr-define} @>
@ -444,18 +455,18 @@ Constare - (лат. стоять твёрдо). Константность эт
int[] array2 = new int[5];<@ \label{codeline:arr-new} @> int[] array2 = new int[5];<@ \label{codeline:arr-new} @>
int[] array3 = {5, 4, 3, 2, 1};<@ \label{codeline:arr-values} @> int[] array3 = {5, 4, 3, 2, 1};<@ \label{codeline:arr-values} @>
array2 = {1, 2, 3, 4, 5}; // <@%\lh{dkgreen}{<-- здесь недопустима инициализация}@> <@ \label{codeline:arr-invalid} @> array2 = {1, 2, 3, 4, 5}; // <@\lh{dkgreen}{<-- здесь недопустимо присваивание}@> <@ \label{codeline:arr-invalid} @>
\end{lstlisting} \end{lstlisting}
% TODO Если мы не определяем переменную, понятно, данные мы хранить не планируем. Если определяем примитивную, помним, она инициализируется нулём, а вот если мы определяем ссылочный идентификатор, он имеет начальное значение null, то есть явно демонстрирует, что не ссылается ни на какой объект. Нулевой указатель - это гораздо более серьёзное явление, чем просто временное отсутствие объекта по идентификатору, очень часто это не инициализированные объекты и попытки вызова невозможных методов, но о том, почему NullPointerException это ваш лучший друг мы поговорим позже \\ \hline Если мы не определяем переменную, понятно, данные мы хранить не планируем. Если определяем примитивную, помним, она инициализируется нулём, а если мы определяем ссылочный идентификатор, он имеет начальное значение \code{null}, то есть явно демонстрирует, что не ссылается ни на какой объект. \textbf{Нулевой указатель} -- это гораздо более серьёзное явление, чем просто временное отсутствие объекта по идентификатору, очень часто это не инициализированные объекты и попытки вызова невозможных методов. Поэтому в работе очень часто помогает понять, что именно пошло не так \code{NullPointerException}.
\begin{frm} \excl Никак и никогда нельзя присвоить идентификатору целый готовый массив в процессе работы, нельзя стандартными средствами переприсвоить ряд значений части массива (так называемые слайсы или срезы). \end{frm} \begin{frm} \excl Никак и никогда нельзя присвоить идентификатору целый готовый массив (создаваемый здесь и сейчас) в процессе работы, нельзя стандартными средствами переприсвоить ряд значений части массива (так называемые слайсы или срезы). \end{frm}
Массивы бывают как одномерные, так и многомерные. Многомерный массив - это всегда массив из массивов меньшего размера: двумерный массив - это массив одномерных, трёхмерный - массив двумерных и так далее. Правила инициализации у них не отличаются. Преобразовать тип массива нельзя никогда, но можно преобразовать тип каждого отдельного элемента при чтении. Это связано с тем, что под массивы сразу выделяется непрерывная область памяти, а со сменой типа всех значений массива эту область нужно будет или значительно расширять или значительно сужать. Массивы бывают как одномерные, так и многомерные. Многомерный массив -- это всегда массив из массивов меньшего размера: двумерный массив -- это массив одномерных, трёхмерный -- массив двумерных и так далее. Правила инициализации у них не отличаются. Преобразовать тип массива нельзя никогда, но можно преобразовать тип каждого отдельного элемента при чтении. Это связано с тем, что под массивы сразу выделяется непрерывная область памяти, а со сменой типа всех значений массива эту область нужно будет или значительно расширять или значительно сужать.
Ключевое слово \code{final} работает только с идентификатором массива, то есть не запрещает изменять значения его элементов. Ключевое слово \code{final} работает только с идентификатором массива, то есть не запрещает изменять значения его элементов.
Если логика программы предполагает создание нижних измерений массива в процессе работы программы, то при инициализации массива верхнего уровня не следует указывать размерности нижних уровней. Это связано с тем, что при инициализации, Java сразу выделяет память под все измерения, а присваивание нижним измерениям новых ссылок на создаваемые в процессе работы массивы, будет пересоздавать области памяти, получается небольшая утечка памяти. Если алгоритм приложения предполагает создание нижних измерений массива в процессе работы программы, то при инициализации массива верхнего уровня не следует указывать размерности нижних уровней. Это связано с тем, что при инициализации, Java сразу выделяет память под все измерения, а присваивание нижним измерениям новых ссылок на создаваемые в процессе работы массивы, будет пересоздавать области памяти, получается небольшая утечка памяти.
Прочитать из массива значение возможно обратившись к ячейке массива по индексу. Записать в массив значение возможно обратившись к ячейке массива по индексу, и применив оператор присваивания. Прочитать из массива значение возможно обратившись к ячейке массива по индексу. Записать в массив значение возможно обратившись к ячейке массива по индексу, и применив оператор присваивания.
\begin{lstlisting}[language=Java,style=JCodeStyle] \begin{lstlisting}[language=Java,style=JCodeStyle]
@ -463,14 +474,14 @@ Constare - (лат. стоять твёрдо). Константность эт
array[1] = 10; array[1] = 10;
\end{lstlisting} \end{lstlisting}
% В каждом объекте массива есть специальное поле (рис. \hrf{pic:array-length}), которое обозначает длину данного массива. Поле находится в классе \code{__Array__} и является публичной константой. В каждом объекте массива есть специальное поле (рис. \hrf{pic:array-length}), которое обозначает длину данного массива. Поле находится в классе \code{__Array__} и является публичной константой.
% \begin{figure}[H] \begin{figure}[H]
% \centering \centering
% \includegraphics[width=12cm]{jc-02-array-length.png} \includegraphics[width=12cm]{jc-02-array-length.png}
% \caption{Константа с длиной массива} \caption{Константа с длиной массива}
% \label{pic:array-length} \label{pic:array-length}
% \end{figure} \end{figure}
\subsubsection{Задания для самопроверки} \subsubsection{Задания для самопроверки}
\begin{enumerate} \begin{enumerate}
@ -481,12 +492,12 @@ Constare - (лат. стоять твёрдо). Константность эт
\subsection{Базовый функционал языка} \subsection{Базовый функционал языка}
\subsubsection{Математические операторы} \subsubsection{Математические операторы}
Математические операторы работают как и предполагается - складывают, вычитают, делят, умножают, делают это по приоритетам известным нам с пятого класса, а если приоритет одинаков - слева направо. Специального оператора возведения в степень как в пайтоне нет. Единственное, что следует помнить, что оператор присваивания продолжает быть оператором присваивания, а не является математическим равенством, а значит сначала посчитается всё, что слева, а потом результат попробует присвоиться переменной справа. Припоминаем что там за дела с целочисленным делением и отбрасыванием дробной части. Математические операторы работают как и предполагается -- складывают, вычитают, делят, умножают, делают это по приоритетам, известным нам с пятого класса, а если приоритет одинаков -- слева направо. Специального оператора возведения в степень как в Python нет. Единственное, что следует помнить, что оператор присваивания продолжает быть оператором присваивания, а не является математическим тождеством, а значит сначала посчитается всё, что слева, а потом результат попробует присвоиться переменной справа. Припоминаем какие есть особенности у операции целочисленного деления, связанные с отбрасыванием дробной части.
\subsubsection{Условия} \subsubsection{Условия}
Условия представлены в языке привычными \code{if}, \code{else if}, \code{else}, «если», «иначе если», «в противном случае», которые являются единым оператором выбора, то есть если исполнение программы пошло по одной из веток, то в другую ветку условия программа точно не зайдёт. Каждая ветвь условного оператора - это отдельный кодовый блок со своим окружением и локальными переменными. Условия представлены в языке привычными \code{if}, \code{else if}, \code{else}, «если», «иначе если», «в противном случае», которые являются единым оператором выбора, то есть, если исполнение программы пошло по одной из веток, то в другую ветку условия программа никогда не зайдёт. Каждая ветвь условного оператора -- это отдельный кодовый блок со своим окружением и локальными переменными.
Существует альтернатива оператору \code{else if} - использование оператора \code{switch}, который позволяет осуществлять множественный выбор между числовыми значениями. У оператора есть ряд особенностей: Существует альтернатива оператору \code{else if} -- использование оператора \code{switch}, который позволяет осуществлять множественный выбор между числовыми значениями. У оператора есть ряд особенностей:
\begin{itemize} \begin{itemize}
\item это оператор, состоящий из одного кодового блока, то есть сегменты кода находятся в одной области видимости. Если не использовать оператор \code{break}, есть риск «проваливаться» в следующие кейсы; \item это оператор, состоящий из одного кодового блока, то есть сегменты кода находятся в одной области видимости. Если не использовать оператор \code{break}, есть риск «проваливаться» в следующие кейсы;
\item нельзя создать диапазон значений; \item нельзя создать диапазон значений;
@ -501,12 +512,12 @@ Constare - (лат. стоять твёрдо). Константность эт
\item \code{for (;;) {}} \item \code{for (;;) {}}
\end{itemize} \end{itemize}
Цикл - это набор повторяющихся до наступления условия действий. \code{while} - самый простой, чаще всего используется, когда нужно описать бесконечный цикл. \code{do-while} единственный цикл с постусловием, то есть сначала выполняется тело, а затем принимается решение о необходимости зацикливания, используется для ожидания ответов на запрос и возможного повторения запроса по условию. \code{for} - классический счётный цикл, его почему-то программисты любят больше всего. Цикл -- это набор повторяющихся до наступления условия действий. \code{while} -- самый простой, чаще всего используется, когда нужно описать бесконечный цикл. \code{do-while} единственный цикл с постусловием, то есть сначала выполняется тело, а затем принимается решение о необходимости зацикливания, используется для ожидания ответов на запрос и возможного повторения запроса по условию. \code{for} -- классический счётный цикл, его почему-то программисты любят больше всего.
Существует также активно пропагандируемый цикл - \code{foreach}, работает не совсем очевидным образом, для понимания его работы необходимо ознакомиться с ООП и понятием итератора. Существует также активно пропагандируемый цикл -- \code{foreach}, работает не совсем очевидным образом, для понимания его работы необходимо ознакомиться с ООП и понятием итератора.
\subsubsection{Бинарные арифметические операторы} \subsubsection{Бинарные арифметические операторы}
В современных реалиях мегамощных компьютеров вряд ли кто-то задумывается об оптимизации скорости выполнения программы или экономии занимаемой памяти. Но всё меняется, когда программист впервые принимает сложное решение: запрограммировать микроконтроллер или другой «интернет вещей». Там в вашем распоряжении жалкие пара сотен килобайт памяти, если очень повезёт, в которые нужно не только как-то вложить текст программы и исполняемый бинарный код, но и какие-то промежуточные, пользовательские и другие данные, буферы обмена и обработки. Другая ситуация, в которой нужно начинать «думать о занимаемом пространстве» это разработка протоколов передачи данных, чтобы протокол был быстрый, не передавал по сети большие объёмы данных и быстро преобразовывался. На помощь приходит натуральная для информатики система счисления, двоичная. В современных реалиях мегамощных компьютеров вряд ли кто-то задумывается об оптимизации скорости выполнения программы или экономии занимаемой памяти. Но всё меняется, когда программист впервые принимает сложное решение: запрограммировать микроконтроллер или другой «интернет вещей». Там в вашем распоряжении пара сотен килобайт памяти, если очень повезёт, в которые нужно не только как-то вложить текст программы и исполняемый бинарный код, но и какие-то промежуточные, пользовательские и другие данные, буферы обмена и обработки. Другая ситуация, в которой нужно начинать «думать о занимаемом пространстве» это разработка протоколов передачи данных, чтобы протокол был быстрый, не передавал по сети большие объёмы данных и быстро преобразовывался. На помощь приходит натуральная для информатики система счисления, двоичная.
Манипуляции двоичными данными представлены в Джава следующими операторами: Манипуляции двоичными данными представлены в Джава следующими операторами:
\begin{itemize} \begin{itemize}
@ -520,7 +531,7 @@ Constare - (лат. стоять твёрдо). Константность эт
Литеральные «и», «или», «не» уже знакомы по условным операторам. Литеральные операции применяются ко всему числовому литералу целиком, а не к каждому отдельному биту. Их особенность заключается в том, как язык программирования интерпретирует числа. Литеральные «и», «или», «не» уже знакомы по условным операторам. Литеральные операции применяются ко всему числовому литералу целиком, а не к каждому отдельному биту. Их особенность заключается в том, как язык программирования интерпретирует числа.
\begin{frm} \info В Java в литеральных операциях может участвовать только тип \code{boolean}, а C++ воспринимает любой ненулевой целочисленный литерал как истину, а нулевой, соответственно, как ложь. \begin{frm} \info В Java в литеральных операциях может участвовать только тип \code{boolean}, в то время, как, например, C++ воспринимает любой ненулевой целочисленный литерал как истину, а нулевой, соответственно, как ложь.
\end{frm} \end{frm}
Логика формирования значения при этом остаётся такой же, как и при битовых операциях. Логика формирования значения при этом остаётся такой же, как и при битовых операциях.
@ -572,8 +583,7 @@ Constare - (лат. стоять твёрдо). Константность эт
\label{table:bin-truth-tables} \label{table:bin-truth-tables}
\end{table} \end{table}
Когда говорят о битовых операциях волей-неволей появляется необходимость поговорить о таблицах истинности. В таблице \hrf{table:bin-truth-tables} вы видите таблицы истинности для арифметических битовых операций. Битовые операции отличаются тем, что для неподготовленного взгляда они производят почти магические действия, потому что манипулируют двоичным представлением числа. Когда говорят о битовых операциях, так или иначе, появляется необходимость поговорить о таблицах истинности. В таблице \hrf{table:bin-truth-tables} вы видите таблицы истинности для арифметических битовых операций. Битовые операции отличаются тем, что для неподготовленного взгляда они производят почти магические действия, потому что манипулируют двоичным представлением числа.
\begin{figure}[H] \begin{figure}[H]
\begin{arithmetic} \begin{arithmetic}
@ -608,45 +618,45 @@ Constare - (лат. стоять твёрдо). Константность эт
\hline \hline
Число & Бинарное & Сдвиг \\ [0.5ex] Число & Бинарное & Сдвиг \\ [0.5ex]
\hline\hline \hline\hline
2 & 000000010 & \code{2 << 0} \\ 2 & 00000010 & \code{2 << 0} \\
4 & 000000100 & \code{2 << 1} \\ 4 & 00000100 & \code{2 << 1} \\
8 & 000001000 & \code{2 << 2} \\ 8 & 00001000 & \code{2 << 2} \\
16 & 000010000 & \code{2 << 3} \\ 16 & 00010000 & \code{2 << 3} \\
32 & 000100000 & \code{2 << 4} \\ 32 & 00100000 & \code{2 << 4} \\
64 & 001000000 & \code{2 << 5} \\ 64 & 01000000 & \code{2 << 5} \\
128 & 010000000 & \code{2 << 6} \\ 128 & 10000000 & \code{2 << 6} \\
\hline \hline
\end{tabular} \end{tabular}
\begin{tabular}{||c|c|c||} \begin{tabular}{||c|c|c||}
\hline \hline
Число & Бинарное & Сдвиг \\ [0.5ex] Число & Бинарное & Сдвиг \\ [0.5ex]
\hline\hline \hline\hline
128 & 010000000 & \code{128 >> 0} \\ 128 & 10000000 & \code{128 >> 0} \\
64 & 001000000 & \code{128 >> 1} \\ 64 & 01000000 & \code{128 >> 1} \\
32 & 000100000 & \code{128 >> 2} \\ 32 & 00100000 & \code{128 >> 2} \\
16 & 000010000 & \code{128 >> 3} \\ 16 & 00010000 & \code{128 >> 3} \\
8 & 000001000 & \code{128 >> 4} \\ 8 & 00001000 & \code{128 >> 4} \\
4 & 000000100 & \code{128 >> 5} \\ 4 & 00000100 & \code{128 >> 5} \\
2 & 000000010 & \code{128 >> 6} \\ 2 & 00000010 & \code{128 >> 6} \\
\hline \hline
\end{tabular} \end{tabular}
\caption{Битовые сдвиги} \caption{Битовые сдвиги}
\label{table:bit-shift} \label{table:bit-shift}
\end{table} \end{table}
С битовыми сдвигами работать гораздо интереснее и выгоднее. Они производят арифметический сдвиг значения слева на количество разрядов, указанное справа, в таблице \hrf{table:bit-shift} представлены числа, в битовом представлении это одна единственная единица, находящаяся в разных разрядах числа. Это демонстрация сдвига на один разряд влево, и, как следствие, умножение на два. Обратная ситуация со сдвигом вправо, он является целочисленным делением. С битовыми сдвигами работать гораздо интереснее и выгоднее. Они производят арифметический сдвиг значения слева на количество разрядов, указанное справа, в таблице \hrf{table:bit-shift} представлены восьмиразрядные беззнаковые числа, в битовом представлении это одна единственная единица, находящаяся в разных разрядах числа. Это демонстрация сдвига на один разряд влево, и, как следствие, умножение на два. Обратная ситуация со сдвигом вправо, он является целочисленным делением.
\begin{frm} \info \begin{frm} \info
\begin{itemize} \begin{itemize}
\item \code{X && Y} - литеральная; \item \code{X && Y} -- литеральная;
\item \code{X || Y} - литеральная; \item \code{X || Y} -- литеральная;
\item \code{!X} - литеральная; \item \code{!X} -- литеральная;
\item \code{N << K} - $N * 2^K$; \item \code{N << K} -- $N * 2^K$;
\item \code{N >> K} - $N / 2^K$; \item \code{N >> K} -- $N / 2^K$;
\item \code{x & y} - битовая. 1 если оба x = 1 и y = 1; \item \code{x & y} -- битовая. 1 если оба x = 1 и y = 1;
\item \code{x | y} - битовая. 1 если хотя бы один из x = 1 или y = 1; \item \code{x | y} -- битовая. 1 если хотя бы один из x = 1 или y = 1;
\item \code{~x} - битовая. 1 если x = 0; \item \code{~x} -- битовая. 1 если x = 0;
\item \code{x ^ y} - битовая. 1 если x отличается от y. \item \code{x ^ y} -- битовая. 1 если x отличается от y.
\end{itemize} \end{itemize}
\end{frm} \end{frm}
@ -658,7 +668,7 @@ Constare - (лат. стоять твёрдо). Константность эт
\end{enumerate} \end{enumerate}
\subsection{Функции} \subsection{Функции}
\textbf{Функция} - это исполняемый блок кода. Функция, принадлежащая классу называется \textbf{методом}. \textbf{Функция} -- это исполняемый блок кода. Функция, принадлежащая классу называется \textbf{методом}.
\begin{lstlisting}[language=Java,style=JCodeStyle] \begin{lstlisting}[language=Java,style=JCodeStyle]
void method(int param1, int param2) { void method(int param1, int param2) {
@ -670,27 +680,26 @@ Constare - (лат. стоять твёрдо). Константность эт
} }
\end{lstlisting} \end{lstlisting}
При объявлении функции в круглых скобках указываются параметры, а при вызове - аргументы. При объявлении функции в круглых скобках указываются параметры, а при вызове -- аргументы.
У функций есть правила именования: функция - это переходный глагол совершенного вида в настоящем времени (вернуть, посчитать, установить, создать), часто снабжаемый дополнением, субъектом действия. Методы в Java пишутся lowerCamelCase. Важно, в каком порядке записаны параметры метода, от этого будет зависеть порядок передачи в неё аргументов. Методы обособлены и их параметры локальны, то есть не видны другим функциям. У функций есть правила именования: функция -- это переходный глагол совершенного вида в настоящем времени (вернуть, посчитать, установить, создать), часто снабжаемый дополнением, субъектом действия. Методы в Java пишутся lowerCamelCase. Важно, в каком порядке записаны параметры метода, от этого будет зависеть порядок передачи в неё аргументов. Методы обособлены и их параметры локальны, то есть не видны другим функциям.
\begin{frm} \begin{frm}
\excl Нельзя писать функции внутри других функций. \excl Нельзя писать функции внутри других функций.
\end{frm} \end{frm}
Все аргументы передаются копированием, не важно, копирование это числовой константы, числового значения переменной или хранимой в переменной ссылке на массив. Сам объект в метод не копируется, а копируется только его ссылка. Все аргументы передаются копированием, не важно, копирование это числовой константы, числового значения переменной или хранимой в переменной ссылке на массив. Сам объект в метод не копируется, а копируется только его ссылка.
% TODO void от англ пустота & Возвращаемого значения у метода может и не быть, в некоторых языках такие функции и методы называются процедурами, а в джаве для них просто придумали специальное возвращаемое значение - войд. войд от англ пустота, причём это не какое-то там банальное эмптинесс, а серьёзное масштабное космическое войд, чтобы подчеркнуть, что метод прям совсем ничего точно не возвращает, ох и затейники эти авторы языков программирования. \\ \hline
Возвращаемые из методов значения появляются в том месте, где метод был вызван. Если будет вызвано несколько методов, то весь контекст исполнения первого метода сохраняется, кладётся (на стек) в стопку уже вызванных методов и процессор идёт выполнять только что вызванный второй метод. По завершении вызванного второго метода, мы снимаем со стека лежащий там контекст первого метода, кладём в него вернувшееся из второго метода значение, если оно есть, и продолжаем исполнять первый метод. Возвращаемые из методов значения появляются в том месте, где метод был вызван. Если будет вызвано несколько методов, то весь контекст исполнения первого метода сохраняется, кладётся (на стек) в стопку уже вызванных методов и процессор идёт выполнять только что вызванный второй метод. По завершении вызванного второго метода, мы снимаем со стека лежащий там контекст первого метода, кладём в него вернувшееся из второго метода значение, если оно есть, и продолжаем исполнять первый метод.
\textbf{Вызов метода} - это, по смыслу, тоже самое, что подставить в код сразу его возвращаемое значение. Возвращаемого значения у метода может и не быть, в некоторых языках такие функции и методы называются процедурами, а в Java для них просто придумали специальное возвращаемое значение -- \code{void}. Void (от англ. пустота), интересно отметить, что это не какое-то простое emptyness, а серьёзное масштабное космическое void, чтобы подчеркнуть, что метод совсем ничего точно не возвращает.
\textbf{Сигнатура метода} — это имя метода и его параметры. В сигнатуру метода не входит возвращаемое значение. Нельзя написать два метода с одинаковой сигнатурой. \textbf{Вызов метода} -- это, по смыслу, тоже самое, что подставить в код сразу его возвращаемое значение.
\textbf{Перегрузка методов} - это механизм языка, позволяющий написать методы с одинаковыми названиями и разными оставшимися частями сигнатуры, чтобы получить единообразие при вызове семантически схожих методов с разнотипными данными. \textbf{Сигнатура метода} -- это имя метода и его параметры. В сигнатуру метода не входит возвращаемое значение. Нельзя написать два метода с одинаковой сигнатурой.
\subsection{Практическое задание} \textbf{Перегрузка методов} -- это механизм языка, позволяющий написать методы с одинаковыми названиями и разными оставшимися частями сигнатуры, чтобы получить единообразие при вызове семантически схожих методов с разнотипными данными.
\subsection*{Практическое задание}
\begin{enumerate} \begin{enumerate}
\item Написать метод «Шифр Цезаря», с булевым параметром зашифрования и расшифрования и числовым ключом; \item Написать метод «Шифр Цезаря», с булевым параметром зашифрования и расшифрования и числовым ключом;
\item Написать метод, принимающий на вход массив чисел и параметр n. Метод должен осуществить циклический (последний элемент при сдвиге становится первым) сдвиг всех элементов массива на n позиций; \item Написать метод, принимающий на вход массив чисел и параметр n. Метод должен осуществить циклический (последний элемент при сдвиге становится первым) сдвиг всех элементов массива на n позиций;

View File

@ -33,6 +33,7 @@
\makeindex \makeindex
\makenomenclature \makenomenclature
\newcommand\lh[2]{\texttt{\textcolor{#1}{#2}}}
\newcommand\hrf[1]{\hyperref[#1]{\ref{#1}}} \newcommand\hrf[1]{\hyperref[#1]{\ref{#1}}}
\newcommand\hRf[1]{\hyperref[#1]{\nameref{#1}}} \newcommand\hRf[1]{\hyperref[#1]{\nameref{#1}}}
\newcommand{\wordcount}{\input{/tmp/wordcount.tex}} \newcommand{\wordcount}{\input{/tmp/wordcount.tex}}

View File

@ -1,6 +1,6 @@
%% Creator: Inkscape 1.2.1 (9c6d41e4, 2022-07-14), www.inkscape.org %% Creator: Inkscape 1.2.1 (9c6d41e4, 2022-07-14), www.inkscape.org
%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010 %% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010
%% Accompanies image file 'jc-02-float-struct32.pdf' (pdf, eps, ps) %% Accompanies image file 'jc-02-float-struct32_svg-tex.pdf' (pdf, eps, ps)
%% %%
%% To include the image in your LaTeX document, write %% To include the image in your LaTeX document, write
%% \input{<filename>.pdf_tex} %% \input{<filename>.pdf_tex}
@ -64,6 +64,6 @@
\put(0.6763757,0.20365416){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}23\end{tabular}}}}% \put(0.6763757,0.20365416){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}23\end{tabular}}}}%
\put(0.38849754,0.11856962){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}1,\end{tabular}}}}% \put(0.38849754,0.11856962){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}1,\end{tabular}}}}%
\put(0.47646943,0.0470878){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}32\end{tabular}}}}% \put(0.47646943,0.0470878){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}32\end{tabular}}}}%
\put(0,0){\includegraphics[width=\unitlength,page=1]{jc-02-float-struct32.pdf}}% \put(0,0){\includegraphics[width=\unitlength,page=1]{jc-02-float-struct32_svg-tex.pdf}}%
\end{picture}% \end{picture}%
\endgroup% \endgroup%

View File

@ -1,6 +1,6 @@
%% Creator: Inkscape 1.2.1 (9c6d41e4, 2022-07-14), www.inkscape.org %% Creator: Inkscape 1.2.1 (9c6d41e4, 2022-07-14), www.inkscape.org
%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010 %% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010
%% Accompanies image file 'jc-02-float-struct.pdf' (pdf, eps, ps) %% Accompanies image file 'jc-02-float-struct_svg-tex.pdf' (pdf, eps, ps)
%% %%
%% To include the image in your LaTeX document, write %% To include the image in your LaTeX document, write
%% \input{<filename>.pdf_tex} %% \input{<filename>.pdf_tex}
@ -64,6 +64,6 @@
\put(0.67681651,0.20337675){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}52\end{tabular}}}}% \put(0.67681651,0.20337675){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}52\end{tabular}}}}%
\put(0.38933048,0.11840811){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}1,\end{tabular}}}}% \put(0.38933048,0.11840811){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}1,\end{tabular}}}}%
\put(0.47718254,0.04702366){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}64\end{tabular}}}}% \put(0.47718254,0.04702366){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}64\end{tabular}}}}%
\put(0,0){\includegraphics[width=\unitlength,page=1]{jc-02-float-struct.pdf}}% \put(0,0){\includegraphics[width=\unitlength,page=1]{jc-02-float-struct_svg-tex.pdf}}%
\end{picture}% \end{picture}%
\endgroup% \endgroup%