Краткое содержание
Этот урок завершает второй раздел курса, посвящённый данным и их типам. Он восстанавливает цепочку понятий, ведущую от переменной к константе, за которой следит компилятор, через двоичное представление целых чисел и два их переполнения, приближённые вещественные числа и допуск, символы как коды и преобразования, теряющие информацию; отделяет то, что из этого верно для любого языка, от того, что присуще C++; собирает неопределённое поведение раздела, с тем, что обнаруживает компилятор, что обнаруживает санитайзер и чего не обнаруживает никто; повторяет в итоговой проверке навыки входной; и заканчивается шестью задачами повышенной трудности, объединяющими весь раздел.
Цели обучения
- Выбирать и обосновывать тип каждого данного задачи по значениям, которые оно может принимать, по требуемой точности и по операциям, которые с ним будут выполняться.
- Предсказывать последствия пределов представления в данной программе: переполнение целых чисел, округление чисел с плавающей точкой и потерю информации при преобразовании.
- Использовать именованные константы и явные преобразования и объяснять, что контролирует компилятор в каждом случае.
- Распознавать неопределённое поведение раздела и говорить для каждого случая, что его обнаруживает и как его предотвратить.
- Отделять в изученном за раздел то, что верно для любого языка, от того, что присуще C++.
Чего достиг раздел
Раздел ставил целью научить тому, что всякое данное живёт в памяти с типом, который определяет, какие значения оно может принимать, сколько места занимает и какие операции допускает, и что эти пределы имеют наблюдаемые последствия. Цель достигнута с опорой лишь на то, что введение объявило известным: рабочий цикл компиляции и запуска с параметрами курса, форматированный вывод, чтение через std::cin и чтение сообщений компилятора. Программу с четырьмя вычислениями, которой введение поставило задачу, теперь можно объяснить строка за строкой и исправить.
Переменные и память
Урок Переменные и память установил, что переменная есть ячейка памяти с именем, неизменным типом и меняющимся значением и что тип определяет её размер, который измеряет sizeof. Он отличил инициализацию от присваивания, показал, что фигурные скобки отвергают преобразование с потерей, и научил тому, что присваивание копирует, а не связывает, и что заменённое значение теряется; отсюда следует вспомогательная переменная при обмене значениями. Он определил состояние программы как совокупность значений её переменных и научил следить за ним с помощью таблицы трассировки. Он установил соглашения об именах и закончил первым неопределённым поведением раздела: чтением переменной, которая так и не получила значения.
Целые числа и их представление
Урок Целые числа и их представление научил позиционной системе счисления в основаниях 10, 2 и 16. Из того, что тип имеет бит, он вывел его диапазон значений: битовых комбинаций, которые без знака представляют числа от до , а со знаком, в дополнительном коде, от до , причём отрицательных на одно больше, чем положительных. Он различил два переполнения: переполнение беззнаковых целых, которое есть арифметика по модулю и определено (0u - 1 равно ), и переполнение знаковых целых, которое есть неопределённое поведение и которое останавливает санитайзер. Он показал, что сравнение знакового целого с беззнаковым преобразует первое, так что сравнение ложно, и закончил критерием выбора целочисленного типа по предвидимому диапазону данного.
Числа с плавающей точкой
Урок Числа с плавающей точкой показал, что вещественное число хранится как знак, порядок и двоичная мантисса, так что представимые значения образуют конечное множество рациональных чисел со знаменателем, равным степени 2. Отсюда последовало, что числа в машине нет: вместо него хранится ближайшее значение double, и 0.1 + 0.2 выводится как 0.30000000000000004. Урок оценил погрешность каждого округления, показал, что погрешности накапливаются и что сложение перестаёт быть ассоциативным; откуда вывел, что два вычисленных вещественных числа сравниваются не через ==, а по расстоянию между ними, с обоснованным допуском. Он закрепил double как вещественный тип по умолчанию и представил бесконечность и не-число, NaN.
Символы, логические значения, преобразования и константы
Урок Символы, логические значения, преобразования и константы показал, что тип есть правило чтения битов: char хранит байт, значение которого есть код ASCII символа, и поскольку цифры и буквы имеют последовательные коды, '7' - '0' равно 7; bool есть истина или ложь, и любое число, отличное от нуля, преобразуется в истину. Он изучил неявные преобразования и установил, что преобразование происходит внутри операции, по типу операндов, а не при сохранении результата: в double r{7 / 2} значение равно 3. Он научил записывать желаемое преобразование через static_cast, который не устраняет потерю, а объявляет её; уточнил, что фигурные скобки отвергают сужение, и показал третье неопределённое поведение раздела, преобразование в целое вещественного числа, которое не помещается. Он закончил константами (const, constexpr и static_assert), типом литералов и auto.
Загрузка содержимого…