что такое static cast в c

Урок №56. Явное преобразование (приведение) типов данных

Обновл. 27 Окт 2021 |

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

Зачем использовать явную конвертацию данных?

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

В случае, когда вы используете литералы (такие как 11 или 3 ), замена одного или обоих целочисленных литералов значением типа с плавающей точкой ( 11.0 или 3.0 ) приведет к конвертации обоих операндов в значения типа с плавающей точкой и выполнится деление типа с плавающей точкой.

Но что будет, если использовать переменные? Например:

Операторы явного преобразования типов данных

В языке C++ есть 5 видов операций явного преобразования типов:

конвертация C-style;

применение оператора static_cast;

применение оператора const_cast;

применение оператора dynamic_cast;

применение оператора reinterpret_cast.

На этом уроке мы рассмотрим конвертацию C-style и оператор static_cast. Оператор dynamic_cast мы будем рассматривать, когда дойдем до указателей и наследования. Применения операторов const_cast и reinterpret_cast следует избегать, так как они полезны только в редких случаях и могут создать немало проблем, если их использовать неправильно.

Правило: Избегайте использования операторов const_cast и reinterpret_cast, если у вас нет на это веских причин.

Конвертация C-style

В программе, приведенной выше, мы используем круглые скобки, чтобы сообщить компилятору о необходимости преобразования переменной i1 (типа int) в тип float. Поскольку переменная i1 станет типа float, то i2 также затем автоматически преобразуется в тип float, и выполнится деление типа с плавающей точкой!

Язык C++ также позволяет использовать этот оператор следующим образом:

Конвертация C-style не проверяется компилятором во время компиляции, поэтому она может быть неправильно использована, например, при конвертации типов const или изменении типов данных, без учета их диапазонов (что может привести к переполнению).

Следовательно, конвертацию C-style лучше не использовать.

Правило: Не используйте конвертацию C-style.

Оператор static_cast

В языке C++ есть еще один оператор явного преобразования типов данных — оператор static_cast. Ранее, на уроке о символьном типе данных char, мы уже использовали оператор static_cast для конвертации переменной типа char в тип int, выводя вместо символа целое число:

Оператор static_cast лучше всего использовать для конвертации одного фундаментального типа данных в другой:

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

Использование операторов явного преобразования в неявном преобразовании

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

Конвертация переменной типа int (4 байта) в тип char (1 байт) потенциально опасна — компилятор выдаст предупреждение. Чтобы сообщить ему, что вы намеренно делаете что-то, что потенциально опасно (но хотите сделать это в любом случае), используйте оператор static_cast:

В следующем случае компилятор будет жаловаться, что конвертация из типа double в тип int может привести к потере данных:

Чтобы сообщить компилятору, что мы сознательно хотим сделать это:

Заключение

Преобразования типов данных следует избегать, если это вообще возможно, поскольку всякий раз, когда выполняется подобное изменение, есть вероятность возникновения непредвиденных проблем. Но очень часто случаются ситуации, когда этого не избежать. Поэтому в таких случаях лучше использовать оператор static_cast вместо конвертации C-style.

В чём разница между явным и неявным преобразованием типов данных?

Ответ

Неявное преобразование происходит, когда компилятор ожидает значение одного типа, но получает значение другого типа.

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

Поделиться в социальных сетях:

Урок №55. Неявное преобразование типов данных

Комментариев: 14

Вот так нужно использовать конвертацию C-style

Правило: Не используйте конвертацию C-style.
)))))

Вон там лежит граната… Но ты её не трогай))

В VS 2019 static_cast == C-style. Компілятором не провіряється я пробував.

Решил просто попробовать, а оно работает.Код ниже выведет 8-битное число в двоичной системе. Не совсем понимаю, bitset о котором говорилось в уроке 46 — это тоже тип данных? Если же нет, то было бы интересно узнать как и почему это работает и что еще можно использовать с оператором static_cast.

Эдуард, это же аутентичная (для ПК) форма хранения данных!

прошло без всяких проблем.

Смотря что Вы подразумеваете под проблемой)
Если под проблемой Вы подразумеваете ошибку компиляции или рантайма, то да, код корректен и должен отработать, так что не удивительно, что оно «прошло без всяких проблем», однако, в действительности, проблема есть. Вам повезло со значениями и 90 делится на 3.6 без остатка, потому имеем 25, но подели Вы 90 на 3.7 (24.32…) или 3.5 (25.71…), или ещё на какое число, данный код выдаст Вам, для 3.7 (24), а для 3.5 (25), хотя остаток есть.

Во второй строке Вы неявно приводите i к типу double при делении, за счёт дробного знаменателя, получаете вещественный результат (по сути, временный rvalue объект, с типом double), который, затем, пытаетесь присвоить переменной, тип которой как был int, так и остался, а, значит, будет произведено приведение вещественного результата к типу int.
Если Вы так и хотели — работать с целочисленным значением, то всё хорошо, в противном же случае стоит сменить тип i, либо, если по какой то причине этого делать не хочется, создать буфер, который будет хранить вещественный результат.
Также, Вашу вторую строчку можно сократить до i /= 3.6;

пользоваться фокусом с числовыми литералами (11.0 / 3.0 или a / 2.0) также крайне не желательно. При некоторых настройках оптимизации такое деление все равно будет произведено в целых числах

В статье же все есть :)))

Часто пользуются фокусом для вещественного деления:

Источник

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

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

Содержание

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

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

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

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

В языке C

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

В языке C++

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

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

static_cast

dynamic_cast

const_cast

reinterpret_cast

См. также

что такое static cast в c. Смотреть фото что такое static cast в c. Смотреть картинку что такое static cast в c. Картинка про что такое static cast в c. Фото что такое static cast в c

Полезное

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

Приведение типов — Приведение типа (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 Необходимость использования типов данных … Википедия

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

Источник

Руководство по программированию на C#. Приведение и преобразование типов

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

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

Преобразования с использованием вспомогательных классов. Чтобы выполнить преобразование между несовместимыми типами, например целыми числами и объектами System.DateTime или шестнадцатеричными строками и массивами байтов, можно использовать классы System.BitConverter и System.Convert, а также методы Parse встроенных числовых типов, такие как Int32.Parse. Дополнительные сведения см. в руководствах по преобразованию массива байтов в значение типа int, преобразованию строки в число и преобразованию из шестнадцатеричных строк в числовые типы.

Неявные преобразования

Полный список всех неявных числовых преобразований см. в разделе Таблица неявных числовых преобразований в статье Встроенные числовые преобразования.

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

Явные преобразования

Тем не менее если преобразование нельзя выполнить без риска потери данных, компилятор требует выполнения явного преобразования, которое называется приведением. Приведение — это способ явно указать компилятору, что необходимо выполнить преобразование и что вам известно, что может произойти потеря данных или приведение может завершиться сбоем во время выполнения. Чтобы выполнить приведение, укажите тип, в который производится приведение, в круглых скобках перед преобразуемым значением или переменной. В следующей программе выполняется приведение типа double в int. Программа не будет компилироваться без приведения.

Полный список всех поддерживаемых явных числовых преобразований см. в разделе Таблица явных числовых преобразований в статье Встроенные числовые преобразования.

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

Операция приведения между ссылочными типами не меняет тип времени выполнения базового объекта; изменяется только тип значения, который используется в качестве ссылки на этот объект. Дополнительные сведения см. в разделе Полиморфизм.

Исключения преобразования типов во время выполнения

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

Источник

static_cast в C ++ | Операторы типа Cast

Оператор Cast — это унарный оператор, который заставляет один тип данных преобразовываться в другой тип данных.
C ++ поддерживает четыре типа приведения:

Статическое приведение: это самый простой тип приведений, который можно использовать. Это приведение времени компиляции. Он выполняет такие вещи, как неявное преобразование между типами (например, int в float или указатель на void *), и может также вызывать явные функции преобразования (или неявные).
Например,

using namespace std;

int a = f; // это то, как вы делаете в C

int b = static_cast int >(f);

Выход:

Теперь давайте внесем несколько изменений в код.

using namespace std;

// пройти во время компиляции, может произойти сбой во время выполнения

int * p = static_cast int *>(&c);

Если вы скомпилируете код, вы получите ошибку:

Давайте возьмем другой пример преобразования объекта в класс и из него.

using namespace std;

cout «Conversion Ctor called»

cout «Conversion Operator»

string str2 = static_cast (obj);

obj = static_cast (30);

Запустите приведенный выше код:

Давайте попробуем понять вышеприведенный вывод:

Давайте возьмем пример, который включает в себя наследование.

using namespace std;

class Derived : public Base <

Base* b1 = (Base*)(&d1); // позволил

Base* b2 = static_cast (&d1);

Приведенный выше код скомпилируется без ошибок.

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

using namespace std;

Base* b1 = (Base*)(&d1); // позволил

Base* b2 = static_cast (&d1);

Используйте static_cast для приведения «к и от» пустого указателя.

Источник

Deep C++. Operation: static_cast


Автор: Robert Schmidt
Microsoft Corporation
Перевод: Igor Sukharev
Источник: MSDN

Опубликовано: 30.09.2002
Исправлено: 13.03.2005
Версия текста: 1.0

Обзор

Как подсказывает название, static_cast преобразует выражения одного статического типа в объекты и значения другого статического типа. В соответствии со стандартом C++ (пункт 5.2.9/1-3):

В противном случае static_cast должен выполнить одно из преобразований, указанных ниже. Никаких других преобразований не должно производиться явно при использовании static_cast.»

Это означает, что static_cast допускается, если:

Примеры

Если даны объявления

то следующие два преобразования

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

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

В заключение, два выражения

Первое из них выполнится успешно, тогда как второе – нет. В обоих выражениях осуществляется попытка преобразовать указатель на переменную типа float в указатель на переменную типа int. Однако второе выражение также убирает спецификатор const, что не допускается стандартом. Второе преобразование можно осуществить более обычным способом

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

Пункт 5.2.9/1 допускает преобразование

также является допустимой – т.е. если прямая инициализация возможна без приведения типа. Следовательно, объявления

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

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

Кто-то предлагал комитету стандартизации C++ добавить пятый оператор приведения типов ( implicit_cast ) для выделения преобразований, которые язык допускает и без этого. Комитет отклонил это предложение, возможно потому, что шаблон

Если вам не нравится писать static_cast там, где не требуется явного приведения типа, подумайте над добавлением implicit_cast в вашу библиотеку и используйте его там, где возможно.

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


К типу void

В соответствии со стандартом, любой тип выражения может быть преобразован к типу void с cv- квалификацией.

Это правило допускает все следующие выражения:

Для начала рассмотрим шаблон

Если вы инстанциируете шаблон функцией

в результате будет создана специализация

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

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

то другие программисты смогут быть более уверенными в ваших намерениях.

Базовый тип к ссылке производного типа

Если даны следующие типы

то стандарт позволяет явное преобразование

Хотя это приведение является допустимым, оно может привести к неприятностям. Рассмотрим похожий пример

Стандарт перечисляет другие ограничения времени компиляции на это преобразование:

Инверсия стандартных преобразований

Статья 4 стандарта перечисляет множество неявных стандартных преобразований:

Большинство этих преобразований адаптированы из C,и должны быть хорошо вам знакомы. Поскольку преобразования неявные, то они могут осуществляться без какого-либо явного указания о приведении типа. Например

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

использование static_cast «подавляет» стандартные правила преобразований, вызывая преобразование, иначе невозможное.

static_cast также позволяет проводить обратные преобразования из:

Эти преобразования приводят к неопределенному поведению, если:

Заметьте, что static_cast не обращает все неявные преобразования. В частности, static_cast не может преобразовать из:

Вы можете принудительно выполнить некоторые из этих преобразований с помощью других способов приведения типа. Остальные обращенные преобразования — такие как преобразование указателя обратно в массив — не могут быть выполнены никаким видом приведения типа.

Альтернатива нисходящему приведению типа

Хотя я и не рассматриваю dynamic_cast в этой статье, я хотел бы упомянуть его в качестве альтернативы static_cast для нисходящего приведения типа. Принципиальным преимуществом dynamic_cast является то, что ваша программа проверяет ваше предположение во время исполнения. Если (предположительно) производная сущность в действительности не является объектом производного типа, то dynamic_cast либо вернет NULL (при преобразовании указателей), либо выбросит исключение (при преобразовании ссылок).

Я собираюсь подробно рассмотреть оператор dynamic_cast и ассоциированную с ним идентификацию типов во время выполнения (RTTI — Run-Time Type Identification) в будущих статьях.

Далее

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *