Чтение онлайн

на главную - закладки

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

A.5.2.1. Продвижения

Неявные преобразования, сохраняющие значения, обычно называют продвижениями (promotions). Например, перед выполнением арифметической операции для создания типа int из более коротких целочисленных типов выполняется целочисленное продвижение (integral promotion). Это отражает исходную цель продвижений: привести операнды арифметических операций к “естественным” размерам. Кроме того, преобразование значения типа

float
в значение типа
double
также считается продвижением.

Продвижения используются как часть

обычных арифметических преобразований (раздел A.5.2.2).

A.5.2.2. Преобразования

Значения фундаментальных типов можно преобразовывать друг в друга самыми разными способами. При написании программы следует избегать неопределенного поведения и непредсказуемых преобразований, которые незаметно искажают информацию (см. разделы 3.9 и 25.5.3). Компиляторы обычно способны предупредить о многих сомнительных преобразованиях.

Целочисленные преобразования. Целое число может быть преобразовано в другой целый тип. Значение перечисления может быть преобразовано в целый тип. Если результирующим типом является тип без знака (

unsigned
), то результирующее значение будет иметь столько же битов, сколько и источник, при условии, что оно может поместиться в целевой области памяти (старшие биты при необходимости могут быть отброшены). Если целевой тип имеет знак, то значение останется без изменения, при условии, что его можно представить с помощью целевого типа; в противном случае значение определяется реализацией языка. Обратите внимание на то, что типы
bool
и
char
являются целочисленными.

Преобразования значений с плавающей точкой. Значение с плавающей точкой можно преобразовать в значение с плавающей точкой другого типа. Если исходное значение можно точно представить с помощью целевого типа, то результатом будет исходное числовое значение. Если же исходное значение лежит между двумя целевыми значениями, то результатом будет одно из этих значений. Иначе говоря, результат непредсказуем. Обратите внимание на то, что преобразование значения типа float в значение типа

double
считается продвижением.

Преобразование указателей и ссылок. Любой указатель на тип объекта можно преобразовать в указатель типа

void*
(см. разделы 17.8 и 27.3.5). Указатель (ссылка) на производный класс можно неявно преобразовать в указатель (ссылку) на доступный и однозначно определенный базовый класс (см. раздел 14.3). Константное выражение (см. разделы A.5 и 4.3.1), равное нулю, можно неявно преобразовать в любой другой тип указателя. Указатель типа
T*
можно неявно преобразовать в указатель
const T*
. Аналогично ссылку
T&
можно неявно преобразовать в ссылку типа
const T&
.

Булевы преобразования. Указатели, целые числа и числа с плавающей точкой можно неявно преобразовать в значение типа

bool
. Ненулевое значение преобразовывается в значение
true
, а нуль — в значение
false
.

Преобразования чисел с плавающей точкой в целые числа. Если число с плавающей точкой преобразуется в целое число, то его дробная часть отбрасывается. Иначе говоря, преобразование из типа с плавающей точкой в целый тип является усечением. Если усеченное значение невозможно представить с помощью целевого типа, то результат становится непредсказуемым. Преобразования

целых чисел в числа с плавающей точкой являются математически корректными только в той степени, в которой это допускается аппаратным обеспечением. Если целое число невозможно точно представить как число с плавающей точкой, происходит потеря точности.

Обычные арифметические преобразования. Эти преобразования выполняются над операндами бинарных операторов, чтобы привести их к общему типу, а затем использовать этот тип для представления результата.

1. Если один из операндов имеет тип

long double
, то другой преобразовывается в тип
long double
. В противном случае, если один из операндов имеет тип
double
, другой преобразовывается в тип
double
. В противном случае, если один из операндов имеет тип
float
, другой преобразовывается в тип
float
. В противном случае над обоими операндами целочисленного типа выполняется продвижение.

2. Если один из операндов имеет тип

unsigned long
, то другой преобразовывается в тип
unsigned long
. В противном случае, если один из операндов имеет тип
long int
, а другой —
unsigned int
, значение типа
unsigned int
преобразуется в значение типа
long int
, при условии, что тип
long int
может представить все значения типа
unsigned int
. В противном случае оба операнда преобразовываются в тип
unsigned long int
. В противном случае, если один из операндов имеет тип
long
, другой преобразовывается в тип
long
. В противном случае, если другой операнд имеет тип
unsigned
, другой преобразовывается в тип
unsigned
. В противном случае оба операнда имеют тип
int
.

Очевидно, что лучше не полагаться на слишком запутанные сочетания типов и минимизировать необходимость неявных преобразований.

A.5.2.3. Преобразования, определенные пользователем

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

explicit
(см. раздел 18.3.1), то преобразование происходит, только если программист явно потребует его выполнить. В противном случае преобразование может быть неявным.

A.5.3. Константные выражения

Константное выражение (constant expression) — это выражение, которое может быть вычислено на этапе компиляции и содержит только операнды типа

int
. (Это немного упрощенное определение, но для большинства целей оно вполне подходит.) Рассмотрим пример.

const int a = 2*3;

const int b = a+3;

Константные выражения требуются в немногих случаях, например, при вычислении границ массивов, меток разделов

case
, инициализаторов перечислений и шаблонных аргументов типа
int
. Рассмотрим пример.

Поделиться:
Популярные книги

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Сумеречный стрелок 7

Карелин Сергей Витальевич
7. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 7

Жизнь под чужим солнцем

Михалкова Елена Ивановна
Детективы:
прочие детективы
9.10
рейтинг книги
Жизнь под чужим солнцем

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец