Язык c преобразование типов

Руководство по программированию на C#. Приведение и преобразование типов Casting and type conversions (C# Programming Guide)

Неявные преобразования. Специальный синтаксис не требуется, так как преобразование всегда завершается успешно и данные не будут потеряны. Implicit conversions: No special syntax is required because the conversion always succeeds and no data will be lost. Примеры включают преобразования из меньших в большие целочисленные типы и преобразования из производных классов в базовые классы. Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.

Пользовательские преобразования. Такие преобразования выполняются специальными методами, которые можно определить для включения явных и неявных преобразований между пользовательскими типами без связи «базовый класс — производный класс». User-defined conversions: User-defined conversions are performed by special methods that you can define to enable explicit and implicit conversions between custom types that do not have a base class–derived class relationship. Дополнительные сведения см. в разделе Операторы пользовательского преобразования. For more information, see User-defined conversion operators.

Преобразования с использованием вспомогательных классов. Чтобы выполнить преобразование между несовместимыми типами, например целыми числами и объектами System.DateTime или шестнадцатеричными строками и массивами байтов, можно использовать классы System.BitConverter и System.Convert, а также методы Parse встроенных числовых типов, такие как Int32.Parse. Conversions with helper classes: To convert between non-compatible types, such as integers and System.DateTime objects, or hexadecimal strings and byte arrays, you can use the System.BitConverter class, the System.Convert class, and the Parse methods of the built-in numeric types, such as Int32.Parse. Дополнительные сведения см. в руководствах по преобразованию массива байтов в значение типа int, преобразованию строки в число и преобразованию из шестнадцатеричных строк в числовые типы. For more information, see How to convert a byte array to an int, How to convert a string to a number, and How to convert between hexadecimal strings and numeric types.

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

Полный список всех неявных числовых преобразований см. в разделе Таблица неявных числовых преобразований в статье Встроенные числовые преобразования. For a complete list of all implicit numeric conversions, see the Implicit numeric conversions section of the Built-in numeric conversions article.

Для ссылочных типов неявное преобразование всегда предусмотрено из класса в любой из его прямых или косвенных базовых классов или интерфейсов. For reference types, an implicit conversion always exists from a class to any one of its direct or indirect base classes or interfaces. Никакой специальный синтаксис не требуется, поскольку производный класс всегда содержит все члены базового класса. No special syntax is necessary because a derived class always contains all the members of a base class.

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

Тем не менее если преобразование нельзя выполнить без риска потери данных, компилятор требует выполнения явного преобразования, которое называется приведением. However, if a conversion cannot be made without a risk of losing information, the compiler requires that you perform an explicit conversion, which is called a cast. Приведение — это способ явно указать компилятору, что необходимо выполнить преобразование и что вам известно, что может произойти потеря данных или приведение может завершиться сбоем во время выполнения. A cast is a way of explicitly informing the compiler that you intend to make the conversion and that you are aware that data loss might occur, or the cast may fail at runtime. Чтобы выполнить приведение, укажите тип, в который производится приведение, в круглых скобках перед преобразуемым значением или переменной. To perform a cast, specify the type that you are casting to in parentheses in front of the value or variable to be converted. В следующей программе выполняется приведение типа double в int. Программа не будет компилироваться без приведения. The following program casts a double to an int. The program will not compile without the cast.

Полный список всех поддерживаемых явных числовых преобразований см. в разделе Таблица явных числовых преобразований в статье Встроенные числовые преобразования. For a complete list of supported explicit numeric conversions, see the Explicit numeric conversions section of the Built-in numeric conversions article.

Для ссылочных типов явное приведение является обязательным, если необходимо преобразовать базовый тип в производный тип: For reference types, an explicit cast is required if you need to convert from a base type to a derived type:

Операция приведения между ссылочными типами не меняет тип времени выполнения базового объекта; изменяется только тип значения, который используется в качестве ссылки на этот объект. A cast operation between reference types does not change the run-time type of the underlying object; it only changes the type of the value that is being used as a reference to that object. Дополнительные сведения см. в разделе Полиморфизм. For more information, see Polymorphism.

Исключения преобразования типов во время выполнения Type conversion exceptions at run time

В некоторых преобразованиях ссылочных типов компилятор не может определить, будет ли приведение допустимым. In some reference type conversions, the compiler cannot determine whether a cast will be valid. Есть вероятность, что правильно скомпилированная операция приведения завершится сбоем во время выполнения. It is possible for a cast operation that compiles correctly to fail at run time. Как показано в следующем примере, приведение типа, завершившееся сбоем во время выполнения, вызывает исключение InvalidCastException. As shown in the following example, a type cast that fails at run time will cause an InvalidCastException to be thrown.

Спецификация языка C# C# language specification

Дополнительные сведения см. в разделе Преобразованияспецификация языка C#. For more information, see the Conversions section of the C# language specification.

Источник

C Урок 14. Преобразование типов

На данном уроке мы поговорим о преобразовании типов данных в процессе работы программы из одного типа в другой.

Конечно, в идеальном случае, желательно, чтобы программа была построена таким образом чтобы лишний раз избегать всякого рода преобразований и использовать везде данные нужного типа. Но не всегда так получается и преобразование типа в ряде случаев просто необходимо. Например, мы складываем значения двух переменных типа unsigned short и, по идее у нас результат тоже должен присваиваться переменной типа unsigned short. Но мы не уверены в том, что этот результат уместится в такой тип, например, мы захотим сложить числа 65535 и 65534. Поэтому здесь без преобразования не обойтись. И таких ситуаций огромное множество, поэтому мы должны знать как происходит преобразование типов автоматически, а также как мы можем этим процессом управлять. Думаю, данный урок даст хоть и не полную картину преобразований типов, но, тем не менее, внесёт некоторую ясность в данную тему.

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

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

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

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

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

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

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

Например, если мы хотим значение 8-байтового типа присвоить переменной 4-байтового типа, неважно, целого типа эти данные или нет, то при этом произойдёт неявное преобразование к 4-байтовому типу, при этом старшие 4 байта отбрасываются. Это считается небезопасным приведением типов, когда возможна потеря информации.

Может быть и наоборот, если мы хотим значение 4-байтового типа присвоить переменной 8-байтового типа. Также произойдёт неявное преобразование и, наоборот, 4 старших байта добавятся и заполнятся нулями. Это будет уже безопасное приведение типа и при этом целостность информации не страдает.

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

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

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

int i;

char c = 45;

i = ( int )c;

В данном случае значение переменной c явно преобразовывается к типу данных int, а затем уже в преобразованном виде присваивается переменной i.

Вот ещё несколько примеров явного преобразования типов данных

Давайте теперь поэкспериментируем с преобразованием типов данных на практике в реальном коде.

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

Откроем файл main.c и в функции main(), как обычно, удалим весь код тела кроме возврата нуля, останется от него вот это

int main()

return 0 ; //Return an integer from a function

Удалим также вот эти константы

#define VAR_CONST1 12345

#define HELLO_CONST «\»Hello, world. \»»

Добавим в тело функции main() следующий код

Источник

Еще раз про приведение типов в языке С++ или расстановка всех точек над cast

Язык c преобразование типов. Смотреть фото Язык c преобразование типов. Смотреть картинку Язык c преобразование типов. Картинка про Язык c преобразование типов. Фото Язык c преобразование типов

Этот пост попытка кратко оформить все, что я читал или слышал из разных источников про операторы приведения типов в языке C++. Информация ориентирована в основном на тех, кто изучает C++ относительно недолго и, как мне кажется, должна помочь понять cпецифику применения данных операторов. Старожилы и гуру С++ возможно помогут дополнить или скорректировать описанную мной картину. Всех интересующихся приглашаю под кат.

Приведение типов в стиле языка C (C-style cast)

Приведение типов в стиле языка C может привести выражение любого типа к любому другому типу данных (исключение это приведение пользовательских типов по значению, если не определены правила их приведения, а также приведение вещественного типа к указателю или наоборот). К примеру, unsigned int может быть преобразован к указателю на double. Данный метод приведения типов может быть использован в языке C++. Однако, метод приведения типов в стиле языка C не делает проверки типов на совместимость, как это могут сделать static_cast и dynamic_cast на этапе компиляции и на этапе выполнения соответственно. При этом все, что умеют const_cast и reinterpret_cast данный метод приведения типов делать может.

Общий вид приведения:

, где new_type – новый тип, к которому приводим, а exp – выражение, которое приводится к новому типу.

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

const_cast

Оператор приведения const_cast удаляет или добавляет квалификаторы const и volatile с исходного типа данных (простые типы, пользовательские типы, указатели, ссылки). Например, был const int, а после преобразования стал int или наоборот. Квалификаторы const и volatile называют cv-квалификаторы (cv-qualifiers). Данные квалификаторы указываются перед именами типов. Как ни трудно догадаться квалификатор const задает константность, т.е. защищает переменную от изменения. Квалификатор volatile говорит о том, что значение переменной может меняться без явного выполнения присваивания. Это обеспечивает защиту от оптимизации компилятором операций с данной переменной.

Общий вид приведения:

Дополнительный пример от пользователя 5nw

reinterpret_cast

Оператор приведения reinterpret_cast используется для приведения несовместимых типов. Может приводить целое число к указателю, указатель к целому числу, указатель к указателю (это же касается и ссылок). Является функционально усеченным аналогом приведения типов в стиле языка С. Отличие состоит в том, что reinterpret_cast не может снимать квалификаторы const и volatile, а также не может делать небезопасное приведение типов не через указатели, а напрямую по значению. Например, переменную типа int к переменной типа double привести при помощи reinterpret_cast нельзя.

Общий вид приведения:

static_cast

Оператор приведения static_cast применяется для неполиморфного приведения типов на этапе компиляции программы. Отличие static_cast от приведения типов в стиле языка C состоит в том, что данный оператор приведения может отслеживать недопустимые преобразования, такие как приведение указателя к значению или наоборот (unsigned int к указателю на double не приведет), а также приведение указателей и ссылок разных типов считается корректным только, если это приведение вверх или вниз по одной иерархии наследования классов, либо это указатель на void. В случае фиксации отклонения от данных ограничений будет выдана ошибка при компиляции программы. При множественном наследовании static_cast может вернуть указатель не на исходный объект, а на его подобъект.

Общий вид приведения:

dynamic_cast

Оператор приведения dynamic_cast применяется для полиморфного приведения типов на этапе выполнения программы (класс считается полиморфным, если в нем есть хотя бы одна виртуальная функция). Если указатель, подлежащий приведению, ссылается на объект результирующего класса или объект класса производный от результирующего то приведение считается успешным. То же самое для ссылок. Если приведение невозможно, то на этапе выполнения программы будет возвращен NULL, если приводятся указатели. Если приведение производится над ссылками, то будет сгенерировано исключение std::bad_cast. Несмотря на то, что dynamic_cast предназначен для приведения полиморфных типов по иерархии наследования, он может быть использован и для обычных неполиморфных типов вверх по иерахии. В этом случае ошибка будет получена на этапе компиляции. Оператор приведения dynamic_cast приводить к указателю на void, но не может приводить указатель на void к другому типу. Способность dynamic_cast приводить полиморфные типы обеспечивается системой RTTI (Run-Time Type Identification), которая позволяет идентифицировать тип объекта в процессе выполнения программы. При множественном наследовании dynamic_cast может вернуть указатель не на исходный объект, а на его подобъект.

Источник

Преобразования типов и безопасность типов Type conversions and type safety

В этом документе описаны распространенные проблемы преобразования типов и описывается, как избежать их использования в коде C++. This document identifies common type conversion problems and describes how you can avoid them in your C++ code.

Когда компилятор обнаруживает ненадежное преобразование, он выдает ошибку или предупреждение. When the compiler detects an unsafe conversion, it issues either an error or a warning. Произошла ошибка при остановке компиляции. Предупреждение позволяет продолжить компиляцию, но указывает на возможную ошибку в коде. An error stops compilation; a warning allows compilation to continue but indicates a possible error in the code. Однако даже если программа компилируется без предупреждений, она по-прежнему может содержать код, который вызывает неявные преобразования типов, приводящие к неправильным результатам. However, even if your program compiles without warnings, it still may contain code that leads to implicit type conversions that produce incorrect results. Ошибки типов также могут вводиться явными преобразованиями или приведениями в коде. Type errors can also be introduced by explicit conversions, or casts, in the code.

Неявные преобразования типов Implicit type conversions

Если выражение содержит операнды различных встроенных типов и явные приведения отсутствуют, компилятор использует встроенные стандартные преобразования для преобразования одного из операндов, чтобы типы совпадали. When an expression contains operands of different built-in types, and no explicit casts are present, the compiler uses built-in standard conversions to convert one of the operands so that the types match. Компилятор пытается выполнить преобразования в четко определенной последовательности, пока она не завершится успешно. The compiler tries the conversions in a well-defined sequence until one succeeds. Если выбранное преобразование является повышением, компилятор не выдает предупреждение. If the selected conversion is a promotion, the compiler doesn’t issue a warning. Если преобразование является узким, компилятор выдает предупреждение о возможной утрате данных. If the conversion is a narrowing, the compiler issues a warning about possible data loss. Происходит ли фактическая потери данных, зависит от фактических значений, но рекомендуется считать это предупреждение как ошибку. Whether actual data loss occurs depends on the actual values involved, but we recommend that you treat this warning as an error. Если включен определяемый пользователем тип, компилятор пытается использовать преобразования, указанные в определении класса. If a user-defined type is involved, then the compiler tries to use the conversions that you have specified in the class definition. Если не удается найти допустимое преобразование, компилятор выдает ошибку и не компилирует программу. If it can’t find an acceptable conversion, the compiler issues an error and doesn’t compile the program. Дополнительные сведения о правилах, регулирующих стандартные преобразования, см. в разделе стандартные преобразования. For more information about the rules that govern the standard conversions, see Standard Conversions. Дополнительные сведения о пользовательских преобразованиях см. в разделе пользовательские преобразования (C++/CLI). For more information about user-defined conversions, see User-Defined Conversions (C++/CLI).

Расширяющие преобразования (продвижение) Widening conversions (promotion)

В расширяющем преобразовании значение меньшей переменной присваивается более крупной переменной без потери данных. In a widening conversion, a value in a smaller variable is assigned to a larger variable with no loss of data. Поскольку расширяющие преобразования всегда являются надежными, компилятор выполняет их автоматически и не выдает предупреждения. Because widening conversions are always safe, the compiler performs them silently and doesn’t issue warnings. Следующие преобразования являются расширяющими преобразованиями. The following conversions are widening conversions.

Сужающие преобразования (приведение) Narrowing conversions (coercion)

Компилятор выполняет сужающие преобразования неявным образом, но предупреждает о возможной потере данных. The compiler performs narrowing conversions implicitly, but it warns you about potential data loss. Выведите эти предупреждения очень серьезно. Take these warnings very seriously. Если вы уверены, что не произойдет потери данных, так как значения в переменной большего размера всегда помещаются в меньшую переменную, добавьте явное приведение, чтобы компилятор больше не выдавал предупреждение. If you are certain that no data loss will occur because the values in the larger variable will always fit in the smaller variable, then add an explicit cast so that the compiler will no longer issue a warning. Если вы не уверены, что преобразование является надежным, добавьте в код какую-либо проверку среды выполнения для обработки возможной потери данных, чтобы она не вызывала неправильные результаты. If you aren’t sure that the conversion is safe, add to your code some kind of runtime check to handle possible data loss so that it doesn’t cause your program to produce incorrect results.

Преобразование из типа с плавающей запятой в целочисленный тип является узким преобразованием, так как дробная часть значения с плавающей запятой отбрасывается и теряется. Any conversion from a floating point type to an integral type is a narrowing conversion because the fractional portion of the floating point value is discarded and lost.

В следующем примере кода показаны некоторые неявные сужающие преобразования и предупреждения, которые возникают компилятором. The following code example shows some implicit narrowing conversions, and the warnings that the compiler issues for them.

Компилятор не предупреждает о неявных преобразованиях между целыми типами со знаком и без знака. The compiler doesn’t warn about implicit conversions between signed and unsigned integral types. Поэтому рекомендуется полностью избегать беззнаковых преобразований. So, we recommend that you avoid signed-to-unsigned conversions altogether. Если вы не можете избежать их, добавьте проверку среды выполнения, чтобы определить, является ли преобразуемое значение большим или равным нулю и меньше или равно максимальному значению типа со знаком. If you can’t avoid them, then add a runtime check to detect whether the value being converted is greater than or equal to zero and less than or equal to the maximum value of the signed type. Значения в этом диапазоне будут передаваться из входных файлов в неподписанный или из неподписанных в подписывание без переинтерпретации. Values in this range will transfer from signed to unsigned or from unsigned to signed without being reinterpreted.

Преобразования указателей Pointer conversions

Явные преобразования (приведения) Explicit conversions (casts)

С помощью операции приведения можно указать компилятору преобразовать значение одного типа в другой тип. By using a cast operation, you can instruct the compiler to convert a value of one type to another type. В некоторых случаях компилятор вызовет ошибку, если эти два типа полностью не связаны, но в других случаях не вызывает ошибку, даже если операция не является строго типизированной. The compiler will raise an error in some cases if the two types are completely unrelated, but in other cases it won’t raise an error even if the operation isn’t type-safe. Используйте приведение с осторожностью, так как любое преобразование из одного типа в другой является потенциальным источником ошибок программы. Use casts sparingly because any conversion from one type to another is a potential source of program error. Однако иногда требуется выполнить приведения, а не все приведения являются опасными. However, casts are sometimes required, and not all casts are equally dangerous. Одно эффективное использование приведения заключается в том, что в коде выполняется понижающие преобразования и известно, что преобразование не приводит к созданию неверных результатов в программе. One effective use of a cast is when your code performs a narrowing conversion and you know that the conversion doesn’t cause your program to produce incorrect results. Фактически, это говорит компилятору о том, что вы делаете, а также о том, что вы выполняете предупреждения. In effect, this tells the compiler that you know what you are doing and to stop bothering you with warnings about it. Другой способ заключается в приведении из класса указателя на класс, производный от указатель на базовый. Another use is to cast from a pointer-to-derived class to a pointer-to-base class. Другой способ — приведение к переменной постоянной, чтобы передать ее в функцию, для которой требуется аргумент, не являющийся константой. Another use is to cast away the constness of a variable to pass it to a function that requires a non-const argument. Большинство этих операций приведения к некоторым рискам требует определенного риска. Most of these cast operations involve some risk.

В программировании в стиле C для всех типов приведений используется один и тот же оператор приведения в стиле C. In C-style programming, the same C-style cast operator is used for all kinds of casts.

Этот оператор приведения не используется так часто, как другие, и не гарантирует перенос в другие компиляторы. This cast operator isn’t used as often as the others, and it’s not guaranteed to be portable to other compilers.

Дополнительные сведения см. в разделе reinterpret_cast оператор. For more information, see reinterpret_cast Operator.

Источник

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

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