Рассмотрим пример.
double x = 2.7;
// какой-то код
int y = x; // значение переменной y становится равным 2
С момента определения переменной y вы могли забыть, что переменная x имеет тип double, или упустить из виду, что преобразование double в int приводит к усечению (округлению вниз). Результат вполне предсказуем: семь десятых потеряны. Преобразование int в char не порождает проблем с усечением — ни тип int, ни тип char невозможно представить в виде дробной части целого числа. Однако переменная типа char может хранить только очень небольшие целые числа. В персональных компьютерах переменная типа char занимает 1 байт, в то время как переменная типа int — 4 байта.
Итак, мы не можем записать большое число, например 1000, в переменную типа char без потери информации: значение “сужается”. Рассмотрим пример.
int a = 1000;
char b = a; // переменная b становится равной –24
Не все значения типа int эквивалентны значению типа char. Точный диапазон значения типа char зависит от конкретной реализации. На персональных компьютерах значения типа char колеблются в диапазоне [–128:127], но мобильность программ можно обеспечить только в диапазоне [0:127], поскольку не каждый компьютер является персональным, и на некоторых из них значения типа char лежат в диапазоне [0:255].
Почему люди смирились с проблемой суживающих преобразований? Основная причина носит исторический характер: язык С++ унаследовал суживающие преобразования от предшественника, языка С. К первому дню существования языка С++ уже было множество программ, написанных на языке С и содержащих суживающие преобразования. Кроме того, многие такие преобразования на самом деле не создают никаких проблем, поскольку используемые значения не выходят за пределы допустимых диапазонов, и многие программисты жалуются, что “компиляторы указывают им, что надо делать”. В частности, опытные программисты легко справляются с проблемой опасных преобразований в небольших программах. Однако в более крупных программах и для неопытных программистов это может стать источником ошибок. Тем не менее компиляторы могут предупреждать программистов о суживающих преобразованиях — и многие из них делают это.
Итак, что делать, если вы подозреваете, что преобразование может привести к неверным результатам? Перед присваиванием проверьте значение, как это сделано в рассмотренном примере. Более простой способ такой проверки описан в разделах 5.6.4 и 7.4.
Задание
На каждом этапе выполнения задания запустите программу и убедитесь, что она делает именно то, что вы ожидали. Создайте список сделанных ошибок, чтобы предотвратить их в будущем.
1. Напишите программу, формирующую простую форму для письма на основе входной информации. Для начала наберите программу из раздела 3.1, предложив пользователю ввести свое имя и предусмотрев вывод строки “Hello, first_name”, где first_name — это имя, введенное пользователем. Затем модифицируйте программу следующим образом: измените приглашение на строку “Введите имя адресата” и измените вывод на строку “Dear first_name,”. Не забудьте о запятой.
2. Введите одну или две вступительные фразы, например “Как дела? У меня все хорошо. Я скучаю по тебе”. Убедитесь, что первая строка отделена от других. Добавьте еще несколько строк по своему усмотрению — это же ваше письмо.
3. Предложите пользователю ввести имя другого приятеля и сохраните его в переменной friend_name. Добавьте в ваше письмо следующую строку: “Видел ли ты friend_name недавно?”.
4. Объявите переменную типа char с именем friend_sex и инициализируйте его нулем. Предложите пользователю ввести значение m, если ваш друг — мужчина, и f — если женщина. Присвойте переменной friend_sex введенное значение. Затем с помощью двух инструкций if запишите следующее. Если друг — мужчина, то напишите строку: “Если ты увидишь friend_name, пожалуйста, попроси его позвонить мне”. Если друг — женщина, то напишите строку: “Если ты увидишь friend_name, пожалуйста, попроси ее позвонить мне”.
5. Предложите пользователю ввести возраст адресата и присвойте его переменной age, имеющей тип int. Ваша программа должна вывести на экран строку: “Я слышал, ты только что отметил день рождения и тебе исполнилось age лет”. Если значение переменной age меньше или равно 0 или больше или равно 110, выведите на экран строку simple_error("ты шутишь!"), используя функцию simple_error() из заголовочного файла std_lib_facilities.h.
6. Добавьте в ваше письмо следующие строки Если вашему другу меньше 12 лет, напишите: “На следующий год тебе исполнится age+1 лет”. Если вашему другу 18 лет, напишите: “На следующий год ты сможешь голосовать”. Если вашему другу больше 60 лет, напишите: “Я надеюсь, что ты не скучаешь на пенсии”. Убедитесь, что ваша программа правильно обрабатывает каждое из этих значений.
7. Добавьте строку “Искренне твой,” затем введите две пустые строки для подписи и укажите свое имя.
Контрольные вопросы
1. Что подразумевается под приглашением?
2. Какой оператор используется для ввода переменной?
3. Какие две строки следует добавить в программу, чтобы предложить пользователю ввести значение в вашу программу, если хотите, чтобы он ввел целое значение для переменной с именем number?
4. Как называется символ n и для чего он предназначен?
5. Что является признаком конца строки?
6. Как прекращается ввод значения в целочисленную переменную?
7. Как записать
cout << "Hello, ";
cout << first_name;
cout << "!n";
в одной строке?
8. Что такое объект?
9. Что такое литерал?
10. Какие существуют виды литералов?
11. Что такое переменная?
12. Назовите типичные размеры переменных типов char, int и double?
13. В каких единицах измеряется объем памяти, занимаемой небольшими переменными, например объектами типов int и string?
14. В чем заключается разница между операторами = и ==?
15. Что такое определение?
16. Что такое инициализация и чем она отличается от присваивания?
17. Что такое конкатенация строк и как она выполняется в языке С++?
18. Какие из следующих имен являются допустимыми в языке С++? Если имя является недопустимым, то укажите, по какой причине.
This_little_pig This_1_is fine 2_For_1_special
latest thing the_$12_method _this_is_ok
MiniMineMine number correct?
19. Приведите пять примеров допустимых имен, которые вы не стали бы использовать, чтобы не создавать недоразумений.
20. Сформулируйте разумные правила для выбора имен.
21. Что