Краткое содержание
Этот урок открывает второй раздел курса, посвящённый данным и их типам. Он объясняет, для чего нужен раздел: показать, что любые данные программы живут в памяти вместе с типом, который определяет, какие значения они могут принимать, сколько места занимают и какие операции допускают, и что у этих ограничений есть наблюдаемые последствия; представляет четыре урока раздела и нить, которая их связывает, от переменной как ячейки с именем и значением до преобразований между типами и констант; напоминает, что раздел считает известным из первого, а именно умение написать, скомпилировать и запустить программу, которая считывает и выводит данные; формулирует задачу, которую решает раздел, то есть задачу программы, с виду правильной, чьи вычисления не совпадают с вычислениями математики, начиная с суммы , которая в компьютере не равна в точности ; и показывает, куда раздел ведёт: к следующим разделам и к курсу «Программирование на C++ II».
Цели обучения
- Описывать последовательность содержания раздела и объяснять, что каждый урок даёт уроку, который идёт за ним.
- Вспоминать необходимое из раздела 1 (цикл компиляции и запуска, форматированный вывод, чтение с помощью
std::cinи чтение сообщений компилятора) и при необходимости повторять это. - Объяснять на примере, почему число в программе не является числом математики, и предвидеть, почему в компьютере не равно в точности .
- Понимать, что ожидается уметь к концу раздела, и отличать это от того, что будет изучено в следующих разделах.
Входная проверка
Прежде чем проходить раздел, полезно определить исходный уровень. Эта проверка является самопроверкой: она не оценивается, и её единственная цель состоит в том, чтобы направить занятия. Первые четыре вопроса касаются того, что раздел считает известным из первого: выполнения процедуры шаг за шагом, записи числа с двумя знаками после запятой, округления и чтения сообщения об ошибке. Следующие шесть в порядке уроков касаются центральных идей раздела. Никто не обязан пока отвечать на них верно, а в одном из них «пока не знаю» является честным ответом: каждый ответ, верный или нет, объясняет суть дела и называет урок, где она разбирается. Те же умения измеряются снова в конце, в уроке итогов.
Перед началом раздела оцени свою отправную точку. Это короткая самопроверка: она не оценивается, а результат хранится только в твоём браузере.
Вопрос 1Из предыдущих разделовПроцедура гласит: «1. принимает значение 17. 2. принимает значение . 3. принимает значение ». Чему равно в конце?
Предполагает, что каждый шаг исходит из начального значения; второй исходит из значения, оставленного первым.Читает «принимает значение» как математическое равенство; это команда, которая заменяет значение .Путает переменную с константой: значение переменной меняется всякий раз, когда ей присваивают другое.Каждый шаг исходит из значения, которое имеет в этот момент, а не из начального. Выполнять процедуру вручную, записывая значение каждой переменной после каждого шага, значит строить таблицу трассировки из раздела 1, и урок 2.1 превращает её в инструмент для рассуждений о состоянии программы.Повторить: От задачи к алгоритму
Вопрос 2Из предыдущих разделовЧто выводит инструкция
std::println("{:.2f}", 2.0 / 3);?Считает, что спецификация формата отбрасывает лишние цифры; она округляет до ближайшего десятичного знака.Не учитывает спецификацию формата: это запись без.2f.Считает деление целочисленным; с2.0, у которого есть дробная часть, деление вещественное.Спецификация.2fвыводит число с двумя знаками после запятой, округляя: выводится как0.67. Хранимое значение не меняется; меняется только его запись.Повторить: Ввод, вывод и ошибки
Вопрос 3Из предыдущих разделовНужно записать с двумя знаками после запятой, с округлением. Что получится?
Отбрасывает вместо того, чтобы округлять: выбрасывает третью цифру, не глядя на неё.Округляет до одного знака, а не до двух.Увеличивает второй знак после запятой больше, чем нужно: лежит между и , и округление выбирает одно из этих двух чисел.Округлить до двух знаков значит выбрать ближайшее число с двумя знаками после запятой: ближе к , чем к . Урок 2.3 покажет, что компьютер округляет так же, но по основанию 2, и что поэтому почти ни одно число с дробной частью не хранится точно.Повторить: Ввод, вывод и ошибки
Вопрос 4Из предыдущих разделовВ строке 5 программы стоит
const int pages{12}, а в строке 6std::println("{}", pages);. Компилятор пишет6:5: error: expected ',' or ';' before 'std'. Где дефект?Строка 6 правильна; компилятор указывает на неё, потому что именно там заметил нехватку.stdраспознаётся; сообщение говорит, что перед ним ожидалась точка с запятой.В сообщении написаноerror, а неwarning: исполняемого файла нет.Компилятор обнаруживает нехватку, когда встречает то, что не может следовать за объявлением, в начале строки 6, и указывает на это место. Если указанная строка правильна, дефект обычно находится в конце предыдущей.Повторить: Анатомия программы
Вопрос 5Программа объявляет
int a{2};иint b{7};, а затем выполняетa = b;иb = 10;. Чему равноaв конце?Считает, что присваивание связывает две переменные, как будтоaбыло другим именемb; оно лишь копирует значение.Читаетa = bнаоборот, как будтоaкопируется вb; значение идёт справа налево.Складывает два значения; присваивание заменяет, а не накапливает.Присваиваниеa = bкопирует вaзначение, котороеbимеет в этот момент; после этогоaиbявляются независимыми ячейками, и изменениеbне меняетa.Повторить: Переменные и память
Вопрос 6Как записывается число 13 по основанию 2?
Это честный ответ: урок 2.2 учит записывать число по основанию 2 и читать его, и итоговая проверка спросит об этом снова.Читает остатки последовательных делений в том порядке, в каком они появляются; их читают от последнего к первому.Неверно складывает веса: .По основанию 2 каждая позиция весит вдвое больше, чем соседняя справа, а цифрами служат только 0 и 1. Этому учит урок 2.2, потому что так хранится любое целое число программы.Повторить: Целые числа и их представление
Вопрос 7
intразмером 4 байта хранит , своё максимальное значение, и программа прибавляет к нему 1. Что можно утверждать?Не учитывает предел представления: это число не помещается вintразмером 4 байта.Так ведут себя беззнаковые целые, арифметика которых модульная; для знаковых целых стандарт этого не гарантирует.Компилятор не знает значений, которые программа будет иметь при выполнении, если только они не константы; почти всегда он компилирует молча.Целое число в программе имеет фиксированное количество битов и, следовательно, конечный диапазон значений. Выход за диапазон знакового целого нарушает предусловие сложения; санитайзер курса останавливает программу, а без него программа может вывести что угодно. Это изучает урок 2.2.Повторить: Целые числа и их представление
Вопрос 8Имеет ли конечную десятичную запись?
является приближением: , а не 1.Сколько бы их ни записать, всегда остаётся остаток; разложение периодическое, а не конечное.Это свойство числа и основания, а не инструмента; калькулятор показывает лишь приближение.Несократимая дробь имеет конечную десятичную запись тогда и только тогда, когда у её знаменателя нет простых множителей, кроме 2 и 5, множителей основания 10. По основанию 2 условие строже: знаменатель должен быть степенью 2, и поэтому не имеет конечной двоичной записи. Урок 2.3 выводит из этого следствия.Повторить: Числа с плавающей точкой
Вопрос 9Что выводит
std::println("{}", 0.1 + 0.2);?Предполагает, что компьютер складывает точные десятичные дроби; он складывает двоичные приближения.Путает запись по умолчанию со спецификацией{:.2f}, которая округляет до двух знаков.Сумма двухdoubleзаконна; удивляет её результат, а не запись.Ни , ни не хранятся в двоичной системе точно, и сумма их приближений не является приближением .std::printlnвыводит кратчайшую запись, которая однозначно определяет хранимое значение, и эта запись обнаруживает разницу. Урок 2.3 объясняет цифра за цифрой, откуда она берётся.Повторить: Числа с плавающей точкой
Вопрос 10Программа объявляет
const double ratio{7 / 2};и выводитratio. Что появится?Считает, что тип переменной решает, как выполняется деление; это решает тип операндов.Считает, что целочисленное деление округляет; оно отбрасывает дробную часть.Значение 3 является константой и точно представляется вdouble: потери нет, и фигурные скобки это допускают.Деление7 / 2выполняется над целыми и даёт целое частное, 3; лишь после этого 3 преобразуется вdouble. Какое деление выполняется, решается внутри операции, в зависимости от типа операндов, а не при сохранении результата. Урок 2.4 учит, куда поставить преобразование, чтобы получить 3,5.Повторить: Символы, логические значения, преобразования и константы
Загрузка содержимого…