Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Тема 3.2 (ч.1). Команды и данные. Абстракция да...docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
624.15 Кб
Скачать

3.8 Приведение типов данных

Приведением типа данного называется операция принудительного изменения типа этого данного.

Тип данного или выражения можно определить динамически (т.е. во время выполнения программы) с помощью инструкции:

динамическое определение типа данного ::=

typeid, «(», ( выражение | тип данного ), «).name ( )»;

Для выполнения такой инструкции в программу нужно включить заголовочный файл typeinfo.h инструкцией #include <typeinfo.h>. Результатом будет строка – наименование типа данного, например, результатом вызова: typeid (4.5).name ( ) будет строка «double».

Язык программирования С++ предоставляет возможности для неявного и явного приведения типов данных.

Если в одном выражении присутствуют операнды разных типов, то выполняется неявное приведение типов операндов в соответствии правилами приоритетности по следующим признакам: тип, длина и знак (таблица 3.2.5).

Таблица 3.2.5

Признак

Направления убывания приоритета

тип

float

int

char

bool

void

длина

long

(ordinal)

short

знак

unsigned

signed

Некоторые преобразования (как явные, так и неявные) могут приводить к потере зна­чности данного, если значение приводимого данного не укладывается в допустимый диапазон значений приведенного данного.

Рассмотрим пример неявного приведения типов целочисленных данных:

int Source = 300;

char Result = Source; // результат неявного приведения типа – значение 44

Неявное приведение типа выполняется так: вычисляется остаток от деления приво­димого значения 300 на максимально допустимое значение целевого типа плюс один (255 + 1), и прибавляется к нижней границе значений для этого типа (0 + 44), а результат сложения (44) становится резуль­татом приведения.

Нередко такие ошибки возникают, когда переменная типа с ограниченным диапазоном используется в качестве параметра цикла (например, пере­менная типа char многократно увеличивается, и её значение выходит из диапазона допустимых значений).

При приведении типов вещественных данных с большим диапазоном к типам с меньшим диапазоном (например, из float к double) также возмож­ны конфликты. Например:

float Target = 1е+50;

Максимально допустимое значение данного типа float составляет +3.4·1038, поэтому значение 1е+50 (т.е. 1050) не может быть корректно представлено данным типа float. При этом в переменную Target запишется условная величина (+INF или –INF), обозначающая бесконечность. Однако пользователь об этом факте не будет извещен.

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

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

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

В языке С++ предусмотрены два стиля приведения типа данного:

традиционный стиль приведения типа данного::= «(«, тип данного, «)», выражение;

функциональный стиль приведения типа данного ::= тип данного, «(», выражение, «)»;

Примеры:

  1. (double) 4 // результат: 4.0

  2. int (4.5 + 5) // результат: 9

Приведение типов данных можно выполнить и с помощью инструкции static_cast:

статическое приведение типа ::= static_cast, «<», тип данного, «>», «(», идентификатор, «)»;

Эта инструкция используется в контексте типа данного и применяется во время компиляции для стандартных типов данных и типов данных, определенных пользователем. Например:

double X = 4.5;

int Y = static_cast <int> (X); // результат приведения типа – данное X типа int со значением 4

Инструкцию static_cast можно использовать для выполнения приведения типов, обратного неявному преобразованию. Так, C++ автоматически приводит элементы перечислений к типу int, но, если нужно выполнить обратное преобразование, то следует использовать static_cast. Также static_cast можно использовать для приведения указателей к типу void * и наоборот.

Кроме того, язык С++ допускает преобразование квалификаторов типов данных, - постоянных в переменные и наоборот (без изменения базового типа) с помощью инструкции const_cast:

статическое приведение постоянных/переменных ::=

const_cast, «<», тип данного, «>», «(», идентификатор, «)»;

Пример:

int X = 1, Y = 2;

int *const Z = &X; // Z - постоянный указатель на X (т.е. *Z = 1)

const_cast <int *> (Z) = &Y; // теперь переменный указатель Z указывает на Y (т.е. *Z = 2)