Приведение типа

Приведение типа

Приведе́ние ти́па (type conversion) — преобразование значения переменной одного типа в значение другого типа. Выделяют явное и неявное приведения типов.

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

Содержание

Неявное приведение

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

В языке C:

 double  d;  // вещественный тип
 long    l;  // целый тип
 int     i;  // целый тип
 
 if (d > i)      d = i;
 if (i > l)      l = i;
 if (d == l)     d *= 2;

Каждый раз при выполнени операции сравнения или присваивания переменные разных типов будут приведены к единому типу. Следует с осторожностью использовать неявное приведение типа. При переводе числа из вещественного типа в целочисленный, дробная часть отсекается. Обратное приведение из целочисленного типа к вещественному также может привести к понижению точности, что связано с различным представлением вещественных и целочисленных чисел на машинном уровне. К примеру, вещественный тип single стандарта IEEE 754 не может точно представить число 16777217, в то время как 32-битный целочисленный тип может. Это может привести к ситуациям, когда сравнение на равенство одного и того же числа, представленного типами (int и single) будет выдавать ложный результат (числа не равны друг другу).

Явное приведение типа

В языке C

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

 int X;
 int Y = 200;
 char C = 30;
 X = (int)C * 10 + Y;    //переменная С приведена к типу int.

Грубых ошибок в данном примере от автоматического приведения типов не произойдет, так как переменная C, которая имеет тип char будет приведена к типу int, так как здесь идет речь о «повышении» типа переменной к старшему в выражении(переменная С перед присваиванием неявно приводится к типу переменной Y). Но возможен один нюанс - в зависимости от машинной реализации типа char при преобразовании char в int может получиться отрицательное число, потому рекомендуется использовать явное преобразование, а если все-таки есть преобразования типа char в int, char объявлять как беззнаковый(unsigned char).

В языке C++

В языке C++ существует четыре разновидности приведения типа. Все четыре типа записываются в виде

 xxx_cast<type_to>(expression_from)

Например:

 y = static_cast<signed short>(65534);    // будет присвоено -2

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

static_cast

  • Назначение: Приведение типа по обычным правилам, когда компилятор отказывается привести его автоматически (отличается от применяемого в Си (type_to)expression_from только тем, что с указателями на произвольные типа не работает, может применяться только для преобразования void * к другому указателю и для преобразования вниз по иерархии классов; для произвольных указателей применяется reinterpret_cast). Применяется:
    • для вычислений в более широком числовом типе (например, для дробных вычислений с целыми числами);
    • чтобы избавиться от предупреждения «Возможная потеря точности» при переводе в более узкий числовой тип;
    • для указателей и ссылок при конвертации в родительский тип;
    • для типов с конструкторами или операциями конвертации наподобие operator type_to;
    • в шаблонах — компилятор уже при специализации шаблона решает, какие операции использовать;
    • в операции ?:, у которой then- и else-части должны иметь один тип.
  • Ограничения на expression_from: нет.
  • Ограничения на type_to: должен найтись способ преобразования в type_to.
  • Производит ли код: в общем случае да.
  • Возможные ошибки: относительно безопасно. Логические ошибки возможны, если привести в неправильный тип или вообще пропустить приведение, когда оно требуется. Не исключено, что после преобразования появится временный объект, который будет благополучно уничтожен вместе со всеми изменениями (большинство компиляторов на это выдают предупреждение).
// Возвращает процент попаданий.
double hitpercent(const int aHitCount, const int aShotCount)
{
    if (aShotCount==0) return 0.0;
    // Нам нужно дробное деление, а не целочисленное - поэтому переведём делимое и делитель в double
    return static_cast<double>(aHitCount*100) / static_cast<double>(aShotCount);
}
 
string s = static_cast<string>("Hello!"); // аналогично string s = string("Hello!");
string s = (string)"Hello!"; // синтаксис Си тоже работает
string s = static_cast<string>(5); // не компилируется - нет подходящего конструктора

dynamic_cast

  • Назначение: Проводит преобразование типа, предварительно убедившись (с помощью RTTI), что объект expression_from в действительности является объектом типа type_to. Если нет: для указателей возвращает NULL, для ссылок устанавливает аварийную ситуацию std::bad_cast.
  • Ограничения на expression_from: выражение должно быть ссылкой или указателем на объект с хотя бы одной виртуальной функцией.
  • Ограничения на type_to: ссылка или указатель на дочерний по отношению к expression_from тип.
  • Производит ли код: да.
  • Возможные ошибки: относительно безопасно. Логические ошибки возможны, если подать аргумент, не имеющий тип type_to, в то время как код не приспособлен к этому.

const_cast

  • Назначение: Снятие/установка модификатора const или volatile.
  • Ограничения на expression_from: ссылка или указатель.
  • Ограничения на type_to: должен совпадать с типом expression_from с точностью до модификаторов const или volatile.
  • Производит ли код: нет.
  • Возможные ошибки: чревато попыткой изменить неизменный объект.
namespace
{
   // Каждая загрузка DLL создаёт новый сегмент данных.
   // Так что с такими глобальными переменными одна программа не будет
   // мешать другой.
   string s = "Wikipedia";
}
 
typedef char* PChar;
 
// Функция экспортируется DLL'ем и возвращает какую-то строку
// в виде char*. Проблема в том, что std::string::c_str() возвращает
// const char*.
void __declspec(dllexport) WINAPI SomeDllFunction(PChar& rMessage)
{
    rMessage = const_cast<char*>(s.c_str());
}

reinterpret_cast

  • Назначение: Участок памяти рассматривается как объект другого типа.
  • Ограничения на expression_from: порядковый тип (логический, символьный, целый, перечисляемый), указатель, ссылка.
  • Ограничения на type_to: для порядкового типа или указателя — порядковый тип или указатель. Для ссылки — ссылка.
  • Производит ли код: нет.
  • Возможные ошибки: Участок в реальности может и не иметь этого типа. Нет никакой возможности проверить это, всю ответственность за корректность преобразования программист берёт на себя.
// Возвращает true, если число конечное, и false - если бесконечное или NaN.
// Работает на 32- и 64-битном IBM PC.
bool isfinite(const double x)
{
    const long long& y = reinterpret_cast<const long long&>(x);
    return ((y & 0x7FF0000000000000LL) != 0x7FF0000000000000LL);
}
 
// Ошибка - выражение x+5.0 не является ссылкой.
const long long& y = reinterpret_cast<const long long&>(x+5.0);

См. также



Wikimedia Foundation. 2010.

Игры ⚽ Поможем написать курсовую

Полезное


Смотреть что такое "Приведение типа" в других словарях:

  • Приведение типов — Приведение типа (type conversion) весьма важная часть многих языков программирования, в особенности функциональных. Означает этот термин следующее: если в какой то момент тип переменной в составе выражения не задан, он просчитывается (выводится)… …   Википедия

  • Понижающее приведение — В объектно ориентированном программировании, понижающее приведение (англ.  downcasting) или «уточнение типа» (англ. type refinement)  акт приведения типа, ссылающегося на базовый класс, к одному из его производных классов. В… …   Википедия

  • Санкт-Петербургская психиатрическая больница специализированного типа с интенсивным наблюдением — Санкт Петербургская психиатрическая больница (стационар) специализированного типа с интенсивным наблюдением …   Википедия

  • Динамическая идентификация типа данных — Не следует путать с динамической типизацией. Динамическая идентификация типа данных (англ. Run time type information, Run time type identification, RTTI)  механизм в некоторых языках программирования, который позволяет определить тип… …   Википедия

  • Динамическая идентификация типа — данных (англ. Run time Type Information, Run time Type Identification, RTTI)  механизм, реализованный в языках программирования, который позволяет определить тип данных переменной или объекта во время выполнения программы. Содержание 1 Реализация …   Википедия

  • ГОСТ 22615-77: Система "человек-машина". Выключатели и переключатели типа "Тумблер". Общие эргономические требования — Терминология ГОСТ 22615 77: Система "человек машина". Выключатели и переключатели типа "Тумблер". Общие эргономические требования оригинал документа: 1. Выключатель (переключатель) типа «Тумблер» выключатель (переключатель),… …   Словарь-справочник терминов нормативно-технической документации

  • Сравнение C Sharp и Java — Правильный заголовок этой статьи  Сравнение C# и Java. Он показан некорректно из за технических ограничений. Сравнения языков программирования Общее сравнение Основной синтаксис Основные инструкции Массивы Ассоциативные массивы Операции со… …   Википедия

  • Тип данных — (встречается также термин вид данных)  фундаментальное понятие теории программирования. Тип данных определяет множество значений, набор операций, которые можно применять к таким значениям и, возможно, способ реализации хранения значений и… …   Википедия

  • Валютный тип — Тип данных Содержание 1 История 2 Определение 3 Необходимость использования типов данных …   Википедия

  • Типизация данных — Тип данных  фундаментальное понятие теории программирования. Тип данных определяет множество значений, набор операций, которые можно применять к таким значениям, и, возможно, способ реализации хранения значений и выполнения операций. Любые… …   Википедия


Поделиться ссылкой на выделенное

Прямая ссылка:
Нажмите правой клавишей мыши и выберите «Копировать ссылку»