
- •2. Структура и основные элементы программы
- •3.Общее понятие типов данных
- •4. Переменные и константы
- •5.Основные типы данных
- •6. Спецификаторы типов данных
- •7. Определение переменных и констант в программе
- •8. Инициализация переменных различных типов
- •9.Целочисленные типы данных
- •10. Вещественные типы данных
- •11. Особенности представления вещественных типов данных
- •12.Логический тип данных
- •13. Символьный тип данных
- •14. Управляющие последовательности
- •15. Операции и выражения
- •16. Операция присваивания, составные операции присваивания
- •17. Понятие l-значения
- •18. Преобразование типов данных
- •19. Арифметические операции
- •20. Операции инкремента и декремента, их разновидности
- •21. Операции отношения
- •22. Логические операции
- •23. Побитовые операции сдвига
- •24. Побитовые логические операции
- •25. Примеры применения побитовых операций
- •26. Условная операция и ее использование
- •27. Определение объема памяти, необходимого для размещения объектов
- •28. Понятие приоритета операций и его влияние на результаты вычислений
- •31.Флаги форматирования потоков ввода-вывода
- •32. Форматирование ввода-вывода с помощью манипуляторов
- •33.Форматирование ввода-вывода с помощью функций потоков ввода-вывода
- •34. Управление шириной поля вывода и выравниванием данных при выводе
- •35. Управление форматом вывода вещественных значений
- •36. Основные понятия структурного программирования
- •37. Базовый набор управляющих структур
- •39.Условная инструкция (if)
- •40. Инструкция множественного выбора (switch)
- •42. Цикл с постусловием (do while)
- •43. Итерационный цикл (for)
- •46. Инструкция перехода goto
- •47. Понятие рекуррентных вычислений, примеры
- •48. Понятие инварианта цикла
- •49. Понятие и определение массива
- •52. Ввод элементов массивов с клавиатуры
- •53. Декларативная и программная инициализация массивов
- •54. Копирование массивов
- •55. Нахождение минимальных и максимальных значений в массивах
- •56. Сдвиг элементов массивов
- •57. Перестановка элементов в массивах
- •58. Поиск данных в массивах
- •59. Сортировка данных в массивах
- •60. Вычисление сумм и произведений элементов массивов
- •61. Представление текстовых строк в виде массива символов
- •62. Ввод-вывод символьных строк
- •63. Определение фактической длины строки
- •64. Копирование символьных строк
- •65. Основные функции обработки строк библиотеки cstring
- •66. Массивы текстовых строк (двумерные массивы символов)
- •67. Указатели Понятие указателя
- •Работа с указателями
- •68. Арифметика указателей
- •69. Индексирование указателей
- •70. Ссылки
- •71. Определение функции
- •72. Инструкция return
- •73. Завершение работы функции
- •74. Механизмы передачи данных через параметры функций
- •75. Передача данных по значению
- •76. Передача данных через указатели
- •77. Передача данных по ссылке
- •78. Параметры по умолчанию
- •79. Функции с переменным числом параметров
- •80. Inline функции
- •81. Перегрузка функций
- •82. Рекурсия
- •83. Прототипы функций
18. Преобразование типов данных
В языке C++ различают неявное (автоматическое) и явное преобразование типов данных.
Неявное преобразование типов данных при выполнении операций, подобной рассмотренной выше (и в ряде других случаев), выполняется компилятором по определенным правилам автоматически. В чем же состоят эти правила?
Схема преобразования, используемая при выполнении арифметических операций, называется обычными арифметическими преобразованиями. Эта схема может быть описана следующими правилами:
1. Все данные типов char и short int преобразуются к типу int.
2. Если хотя бы один из операндов имеет тип double, то и другой операнд преобразуется к типу double (если он другого типа); результат вычисления имеет тип double.
3. Если хотя бы один из операндов имеет тип float, то и другой операнд преобразуется к типу float (если он другого типа); результат вычисления имеет тип float.
4. Если хотя бы один операнд имеет тип long, то и другой операнд преобразуется к типу long (если он другого типа); результат имеет тип long.
5. Если хотя бы один из операндов имеет тип unsigned, то и другой операнд преобразуется к типу unsigned (если его тип не unsigned); результат имеет тип unsigned.
Если ни один из случаев 1-5 не имеет места, то оба операнда должны иметь тип int; такой же тип будет и у результата.
Следует отметить, что компиляторы языка C++ достаточно свободно выполняют подобные преобразования, что может в ряде случаев привести к неожиданным результатам.
Таким образом, несмотря на то, что язык C++ достаточно «снисходителен» к действиям программиста, это требует от программиста еще большей дисциплины в его действиях и четких знаний нюансов языка программирования.
Здесь было использовано явное преобразование типов данных.
Явное преобразование типов данных осуществляется с помощью соответствующей операции преобразования типов данных, которая имеет один из двух следующих форматов:
(<тип данных>) <выражение> или <тип данных> (<выражение>)
Например:
(int) 3.14 int (3.14)
(double) a или double (a)
(long) (a + 1e5f) long (a + 1e5f)
Подобные преобразования имеют своим исходом три ситуации:
• преобразование без потерь;
• с потерей точности;
• с потерей данных.
Преобразование происходит без потерь, если преобразуемое значение принадлежит множеству значений типа, к которому осуществляется преобразование. Например:
short a = 100;
cout << (int) a << endl; // На экран выведено 100
cout << (char) a << endl; // Выведена буква d (ее десятичный эквивалент - 100)
cout << (float) a << endl; // На экран выведено 100
cout << (double) a << endl; // На экран выведено 100
float b = 3.14f;
cout << (double) b << endl; // На экран выведено 3.14
double d = 3.14;
cout << (float) d << endl; // На экран выведено 3.14
Преобразование любого вещественного типа к целому осуществляется путем отбрасывания дробной части вещественного значения, поэтому практически всегда такие преобразования приводят к потере точности (осуществляются приближенно). Например:
double d = 3.74;
cout << (int) d << endl; // На экран выведено 3
А вот попытки преобразования значений выходящих за пределы диапазона типа данных, к которому осуществляется преобразование, приводят к полному искажению данных. Например:
int a = -100;
cout << (unsigned) a << endl; // На экран выведено 4294967196
int a = 50000;
cout << (short) a << endl; // На экран выведено -15536
float b = 3e+9f;
cout << (int) b << endl; // На экран выведено -2147483648
double d = 3e+9;
cout << (int) d << endl; // На экран выведено -2147483648
double d = 3e+40;
cout << (float) d << endl; // На экран выведено 1.#INF - переполнение
double d = -3e+40;
cout << (float) d << endl; // На экран выведено -1.#INF - переполнение
Рассмотренная операция преобразования типов перешла в C++ из C. В C++ имеются свои операции преобразования типов данных. Например, рассмотренные выше преобразования в C++ можно было бы выполнить с помощью операции static_cast, имеющей следующий формат:
static_cast <тип данных> (выражение)
Например:
static_cast <double> (a + 2e+40f)
Пользоваться явными преобразованиями типов следует очень аккуратно и только там, где это действительно необходимо.
При явном преобразовании типов значения преобразуемых величин на самом деле не изменяются – изменяется только представление этих значений при выполнении действий над ними.