Типизация данных

Содержание

Слайд 2

Объекты данных

Любая программа содержит набор операций, которые применяются к определенным данным в

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

Слайд 3

Объекты данных

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

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

Слайд 4

Объекты данных

В ходе вычислений существует великое множество различных объектов данных.
Более того, объекты

Объекты данных В ходе вычислений существует великое множество различных объектов данных. Более
данных и отношения между ними динамически меняются в разные моменты вычислительного процесса.
Две категории объектов данных:
создаются и явно управляются программистом – переменные, константы, файлы;
создаются операционной системой (программист не имеет к ним непосредственного доступа) - стеки, записи активации функций, файловые буферы, списки свободной памяти.

Слайд 5

Атрибуты объектов данных

Объект данных представляет собой достаточно сложную структуру (некий контейнер), имеющую

Атрибуты объектов данных Объект данных представляет собой достаточно сложную структуру (некий контейнер),
многочисленный набор атрибутов.
Основные атрибуты:
тип данных – задает возможные значения, применимые операции и формат хранения данных;
имя – перечень имен, по которым к объекту данных обращаются в процессе вычислений. Пример: у объекта «целое число 5» может быть несколько имен: int a = 5, b = 5, c = 5;
местоположение (адрес) – хранит координаты области памяти (адрес), отведенной под объект данных (определяется системными программными средствами, т.е. программист, как правило, не имеет доступа к этим средствам).

Слайд 6

Атрибуты объектов данных

Основные атрибуты:
значение – текущая величина (или набор величин)

Атрибуты объектов данных Основные атрибуты: значение – текущая величина (или набор величин)
объекта данных;
время жизни – период существования объекта данных в программе;
область видимости – часть программы, в которой существует доступ к объекту данных. Существует две разновидности: локальная и глобальная.

Слайд 7

Тип данных

Тип данных - это механизм классификации объектов данных.
Тип данных определяет:

Тип данных Тип данных - это механизм классификации объектов данных. Тип данных

возможные значения объектов;
операции, применимые к значениям объектов данного типа;
размещение значений объектов в памяти компьютера (данные разного типа хранятся в разных областях памяти).
В каждом языке программирования имеется некий набор примитивных встроенных типов данных (int, float, char).
В большинстве современных языков, как правило, предусматриваются средства для создания новых собственных типов данных и операций для работы с ними (объектно-ориентированные языки).

Слайд 8

Тип данных

Каждая переменная (константа) считается экземпляром конкретного типа данных.
Тип данных является важнейшим

Тип данных Каждая переменная (константа) считается экземпляром конкретного типа данных. Тип данных
элементом системы контроля языка.
Знание типа переменной позволяет ответить на вопросы:
можно или нельзя присвоить переменной конкретное значение;
можно или нельзя применить к переменной конкретную операцию.
Примеры:
нельзя занести в переменную целого типа строковую переменную;
нельзя применить операцию деления к двум строковым переменным.

Слайд 9

Объявления

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

Объявления В ходе создания программы программист задает имя и тип каждого используемого
данных.
Существует два вида объявлений – явное и неявное.
Явное объявление – это оператор программы, сообщающий компилятору об имени и типе объекта данных, который будет использоваться в программе.
Место размещения объявления в программе определяет время жизни объекта данных.
Возможны два варианта:
локальные переменные – объявляются в начале блока, время жизни ограничено этим блоком;
глобальные переменные – объявляются вне всех блоков и функций, время жизни ограничено временем работы программы.

Слайд 10

Объявления

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

Объявления В некоторых языках программирования допускаются неявные объявления, или объявления по умолчанию.
объявление – это такое объявления, в котором тип данных объекта данных не указан.
Пример. В языке FORTRAN все переменные, начинающиеся с букв I, J, K, L, M, N по умолчанию считаются целочисленными. Если нужно переменную NUMBER сделать вещественной, то это надо прописать явно: REAL NUMBER.
Замечание. Неявные объявления могут быть пагубными для надежности ПО, поскольку препятствуют выявлению на этапе компиляции различных опечаток или ошибок программиста.

Слайд 11

Логический вывод типа

Еще одна разновидность неявного объявления основана на контексте. Иногда его

Логический вывод типа Еще одна разновидность неявного объявления основана на контексте. Иногда
называют логическим выводом типа.
В простейшем случае контекст задает тип начального значения, которое присваивается переменной в операторе объявления.
Пример. В языке C# объявление переменной var включает в себя начальное значение, тип которого задает тип переменной:
var sum = 0; - тип переменной sum = int;
var total = 0.0; - тип переменной total = float;
var name = “Olga”; - тип переменной name = string.

Слайд 12

Контроль типов

На аппаратном уровне компьютера контроль типов не осуществляется.
Например, аппаратная реализация

Контроль типов На аппаратном уровне компьютера контроль типов не осуществляется. Например, аппаратная
операции целочисленного сложения не способна проверить, являются ли переданные ей два операнда целыми числами, для нее это просто последовательность битов.
Вывод: на аппаратном уровне обычные компьютеры очень ненадёжны ! Поскольку они не реагируют на ошибки в типах данных.
Поэтому контроль типов осуществляет компилятор. Именно он проверяет факт получения каждой операцией нужного количества операндов нужного типа.
Пример. Перед выполнением операции y = a * b + с компилятор должен проверить наличие у каждой операции (в данном случае – умножение, сложение и присваивание) операндов правильного типа. Т.е. если переменная b – это строка, то компилятор выдаст ошибку «несоответствие типов операндов».

Слайд 13

Виды контроля типов

Различают два вида контроля типов:
статический контроль типов −

Виды контроля типов Различают два вида контроля типов: статический контроль типов −
осуществляется на этапе компиляции программы; необходимые сведения о типах данных поступают компилятору из явных объявлений;
динамический контроль типов – осуществляется в процессе выполнения программы; явные объявления типов данных отсутствуют.

Слайд 14

Статический контроль типов

Исходные данные, необходимые для организации статического контроля типов:
для

Статический контроль типов Исходные данные, необходимые для организации статического контроля типов: для
каждой операции определены количество и типы данных, (как для операндов, так и для результата);
тип каждого объекта данных (переменной или экземпляра типа) известен и не меняется в ходе выполнения программы;
типы всех констант тоже понятны: тип литеральной константы определяется из её синтаксиса (10 – целая константа, 254.53 – вещественная константа), а тип именованной константы зафиксирован в её определении.

Слайд 15

Статический контроль типов

Вся исходная информация собирается компилятором при анализе текста программы

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

Слайд 16

Динамический контроль типов

явные объявления типов данных отсутствуют (как для операндов, так

Динамический контроль типов явные объявления типов данных отсутствуют (как для операндов, так
и для результата), т.е. все объекты считаются объектами, не имеющими типа;
тип каждого объекта данных (переменной или экземпляра типа) может изменяться в ходе выполнения программы;
контроль типов (возможность осуществления той или иной операции) производится на каждом шаге по ходу выполнения программы.
Основное преимущество – гибкость программы. Объявлений типов нет => объект данных может изменить свой тип в любой момент вычислений. Программист может создавать настраиваемые программы, работающие с данными любого типа.

Слайд 17

Динамический контроль типов

Основные недостатки:
понижение надежности вычислений – работа над возможными ошибками типизации

Динамический контроль типов Основные недостатки: понижение надежности вычислений – работа над возможными
переносится с подготовительного этапа (этап компиляции) на исполнительный этап (этап вычислений); проверке подвергаются только отдельные объекты данных, задействованные в текущей операции, т.е. многие из объектов остаются вне контроля;
снижение скорости вычислений – динамический контроль типов основан на информации, которая хранится в дескрипторах объектов данных, доступ к которым должен быть реализован на программном уровне, т.к. аппаратура таких действий не обеспечивает. Это приводит к существенному замедлению скорости вычислений;
возрастание накладных расходов памяти - дескриптор объекта данных должен храниться в течении всего вычислительного процесса, что предъявляет повышенные запросы к требуемой памяти.

Слайд 18

Системы типизации данных

Система типизации данных – вся сумма правил, связанных с типами

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

Слайд 19

Когда осуществляется связывание ?

Связывание может происходить:
при проектировании языка;
при

Когда осуществляется связывание ? Связывание может происходить: при проектировании языка; при разработке
разработке компилятора языка;
при компиляции программы;
при загрузке программы в память;
при выполнении программы.

Слайд 20

Примеры связывания

символ «+» обычно связывается с операцией сложения на этапе проектирования

Примеры связывания символ «+» обычно связывается с операцией сложения на этапе проектирования
языка;
тип int в языке С++ связывается с диапазоном возможных значений во время компиляции программы (в зависимости от типа процессора – это 2 байта или 4 байта);
в языках С++, Java и др. переменная связывается с конкретным типом данных на этапе компиляции программы;
переменная может связываться с ячейкой памяти при загрузке программы в память;
вызов библиотечной функции связывается с кодом этой функции на этапе редактирования связей и загрузки (сборка программы).
Замечание. Как правило, программист может участвовать в связывании только на этапах компиляции и выполнения программы.

Слайд 21

Примеры связывания

связывание типа
(имя связывается с типом)
связывание значения
(имя

Примеры связывания связывание типа (имя связывается с типом) связывание значения (имя связывается со значением)
связывается со значением)

Слайд 22

Примеры связывания

Необходимые связывания для операции: var = var + 10;
связывание типа

Примеры связывания Необходимые связывания для операции: var = var + 10; связывание
для переменной var – на этапе компиляции;
связывание символа «+» после определения типов операндов – на этапе компиляции;
внутреннее представление константы 10 – связывание на этапе компиляции;
значение переменной var – связывание во время выполнения оператора.

Слайд 23

Разновидности связывания
Статическое связывание выполняется на этапе компиляции.
Динамическое связывание выполняется в процессе выполнения

Разновидности связывания Статическое связывание выполняется на этапе компиляции. Динамическое связывание выполняется в
программы.
Основной постулат динамического связывания – любой переменной может быть присвоено значение любого типа !

Слайд 24

Динамическое связывание типов

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

Динамическое связывание типов Основные постулаты динамического связывания: любой переменной может быть присвоено
значение любого типа;
во время выполнения программы тип одной и той же переменной может меняться многократно.
Таким образом:
при динамическом связывании оператор объявления переменной не содержит имени типа;
тип переменной определяется после присвоения ей значения оператором присваивания;
при выполнении оператора присваивания переменная в его левой части получает тип переменной, выражения или значения, находящегося в его правой части.
Примеры.
var = 10; - переменной var присвоился тип int;
fvar = 6.5; - переменной fvar присвоился тип float;
fvar = var; - переменной fvar присвоился тип int.

Слайд 25

Динамическое связывание типов

Примеры языков со статическим связыванием: C++, Java
Примеры языков с динамическим

Динамическое связывание типов Примеры языков со статическим связыванием: C++, Java Примеры языков
связыванием: Python, Ruby, JavaScript, PHP
Примеры на языке Python.
list = [4.5, 6.8, 7.4] – list – это список (массив) вещественных чисел;
list = 25; - list - это целочисленная переменная.
В языках с динамической типизацией все переменные являются фактически ссылками на объекты данных, т.е. любая переменная может ссылаться на любой объект.

Слайд 26

Динамическое связывание типов

Основные недостатки:
снижение надежности программ – неправильные типы на правой

Динамическое связывание типов Основные недостатки: снижение надежности программ – неправильные типы на
стороне оператора присваивания (=) не будут распознаны как ошибки; вместо этого тип переменной на левой стороне изменится на неправильный тип;
повышенные затраты памяти – каждая переменная несет в себе сложный дескриптор; для хранения любой переменной задействуется область памяти переменного размера, поскольку формат сохраняемого значения меняется от типа к типу;
снижение скорости вычислений – чистая интерпретация выполняется, как правило, в 10 раз медленнее, чем эквивалентный машинный код (компиляция).

Слайд 27

Явные приведения типа в языке С++

Современная версия языка С++ предлагает четыре специальных

Явные приведения типа в языке С++ Современная версия языка С++ предлагает четыре
оператора для выполнения явного приведения типа:
static_cast;
const_cast;
reinterpret_cast;
dynamic_cast.

Слайд 28

Оператор static_cast

Оператор static_cast обеспечивает обычные статические приведения типов, а также преобразования, которые

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

Слайд 29

Оператор static_cast

Оператор static_cast также обеспечивает преобразования, которые компилятор не способен выполнить автоматически.

Оператор static_cast Оператор static_cast также обеспечивает преобразования, которые компилятор не способен выполнить

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

Слайд 30

Оператор const_cast

Оператор const_cast преобразует тип операнда с ключевым словом const в аналогичный

Оператор const_cast Оператор const_cast преобразует тип операнда с ключевым словом const в
тип, но без ключевого слова const. При этом все остальные атрибуты «типа-источника» и «типа-приёмника» должны совпадать.
Пример. Переменная типа Key (Key key) хранит пароль системы. В целях безопасности пользователю выдается указатель на ключ как на константу. Но пользователь хочет получить возможность изменять пароль. Для этого ему необходимо создать свой указатель (неконстантный).
Теперь пользователь может делать с паролем всё, что угодно. Использование любой другой формы приведения типа в данном случае привело бы к ошибке при компиляции.

Слайд 31

Оператор dynamic_cast

Оператор dynamic_cast применяется для преобразования указателя на объект базового класса в

Оператор dynamic_cast Оператор dynamic_cast применяется для преобразования указателя на объект базового класса
указатель на объект производного класса.
Класс объекта, на который будет указывать указатель, в процессе компиляции известен не всегда, поскольку в указателе на объект базового класса может храниться адрес объекта производного класса.
В результате динамического приведения типа указатель на объект базового класса заменяется указателем на объект производного класса.

Слайд 32

Совместимость типов

В конкретном контексте многие языки программирования не требуют эквивалентности типов операндов

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

Слайд 33

Неявные преобразования типов

Если язык программирования позволяет использовать значение одного типа в контексте,

Неявные преобразования типов Если язык программирования позволяет использовать значение одного типа в
где ожидается другой тип, то в таком случае выполняется автоматическое, или неявное преобразование типов.
Различают два типа неявных преобразований типов:
сужающее приведение - уменьшает диапазон возможных значений (float → int, double → float);
расширяющее приведение - увеличивает диапазон возможных значений (int → float, float → double).
Расширяющее приведение безопасно практически всегда..
При сужающем приведении возможна потеря точности.

Слайд 34

Неявные преобразования типов

Если в программе используются смешанные выражения, в которых операнды имеют

Неявные преобразования типов Если в программе используются смешанные выражения, в которых операнды
разные типы, то начинают работать соглашения языка о неявном приведении типов.
Пример.
Компилятор языка C++ или Java не воспримет такой код, как ошибочный.
Однако есть языки, которые не скомпилировали бы такой код.
Примеры.
в языке Ada есть ограничения на неявные преобразования типов (запрещено смешивать целые и вещественные числа);
в языках ML и F# неявные преобразования типов запрещены (все преобразования типов должны быть явными).

Слайд 35

Неявные преобразования типов

С точки зрения проектирования языка вопрос формулируется следующим образом: кто

Неявные преобразования типов С точки зрения проектирования языка вопрос формулируется следующим образом:
должен находить в выражениях ошибки типизации – компилятор или программист ?
Поэтому неявное приведение типов – спорный вопрос в проектировании языка.
Основной аргумент противников неявного преобразования – снижение надежности программ.
Основной аргумент сторонников неявного преобразования – повышение гибкости ПО.
Наиболее современные языки программирования отражают тенденцию перехода к статической типизации и отказа от неявного приведения типов.
Язык C++, напротив, предлагает предельно богатый, в том числе, расширяемый программистом (с помощью всевозможных перегрузок), набор правил неявного приведения типов. Однако этот функционал традиционно относится к наиболее трудным для понимания понятиям.

Слайд 36

Уровень типизации языка

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

Уровень типизации языка С точки зрения безопасности выделяют два типа языков: сильно
типизированные языки – языки, в которых каждая операция безопасна в отношении типа. Сильная система типизации разрешает только безопасные выражения, которые гарантируют вычисления без ошибок типизации;
слабо типизированные языки – языки, система типизации которых не является сильной.
Основная проблема. Сильная система типизации будет разрешать только некоторое подмножество безопасных программ и отвергать очень многие программы.
Патологический пример – система типизации, которая будет отвергать все программы. Такая система типизации будет сильной, но бесполезной.
Поэтому большинство языков ищут разумный компромисс.
Имя файла: Типизация-данных.pptx
Количество просмотров: 27
Количество скачиваний: 0