Какие аргументы и код возврата имеет оператор преобразования типа? В каких случаях неизбежно его использование?
Какие аргументы и код возврата имеет оператор преобразования типа?
В каких случаях неизбежно его использование?
char
без проблем может быть преобразован в int
и поэтому в ф-цию void f(int x)
можно передать значение так: f('a');
. При этом если существует версия ф-ции void f(char x)
, то компилятор должен будет выбрать именно ее.'a'
оттрактовать именно как целое, то нам придется использовать оператор преобразования типа: f(static_cast<int>('a'))
.Хочу обратить внимание, что хотя C++ и позволяет пользоваться приведением типа как в С (напр., double x = 10; int a = (int)x;
), но лучше им не пользоваться, а пользоваться соответствующими операторами преобразования типа С++. Среди них есть и весьма интересные операторы (const_cast
, dynamic_cast
), работающие исключительно с указателями на классы и позволяющие, например, снять константность с указателя (может быть опасно, но нужно) и приводящие друг к другу базовые и производные классы. Второе может быть нужно для реализации полиморфизма на практике - работает с указателем на базовый класс, хотя на самом деле за ним скрывается объект производного класса.
Хорошую статью, а не мои путаные объяснения :-), про приведения типов можно посмотреть на ресурсе Алёна CPP
Я хотел бы заострить внимание на разнице между приведением (cast) и преобразованием (conversion).
При преобразовании меняется машинное (битовое) представление переменой, а при приведении (cast) нет, меняются правила манипулирования этой переменной.
Пример преобразований
int a = 100;
printf ("int a = %d sizeof(a): %ld (double)a = %e sizeof(double): %ld\n",
a, (long)sizeof(a), (double)a, (long)sizeof((double)a));
printf ("sizeof(sizeof(a)) = %d\n", (int)sizeof(sizeof(a)));
результат
int a = 100 sizeof(a): 4 (double)a = 1.000000e+02 sizeof(double): 8
sizeof(sizeof(a)) = 8
Это пример с 64-бит машины. Преобразование в размере и битовом представлении между int
и double
очевидны.
Подробнее о sizeof
. Тип оператора sizeof
это 'long unsigned int'
, поэтому для переносимости между 32-бит (там 'long unsigned int'
занимает 4 байта) и 64-бит
в плане проверки компилятором формата в printf
требуется явное преобразование типа.
В принципе, преобразование (int)sizeof(...)
идет с усечением значения (старших разрядов), в данном случае это несущественно (т.к. числа маленькие). Но, правильным будет
использовать "%ld"
в формате и (long)sizeof
для переносимости при компиляции.
На практике приведение типа чаще всего необходимо при работе с указателями.
Например, если есть переменная типа int, а мы хотим посмотреть на "текст в ней", то без cast-а не обойтись. Или наоборот:
const char *p = "cast";
int *ip = (int *)p;
printf ("%s = %d\n", (char *)ip, *ip);
int b = 1414742339;
printf ("А это десятичное число %d = ", b);
for (p = (const char *)&b; (int *)p < &b + 1; p++)
putchar(*p);
long long bye = 0xa216579420a;
// long long для переносимости с 32-bit
// нам тут нужно 5 байт для string terminated 0
puts((char *)&bye);
результат
cast = 1953718627
А это десятичное число 1414742339 = CAST
Bye!
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
По результатам опроса прошлого года известен список 10 политических деятелей в порядке убывания их популярностиПроведен новый опрос
Здравствуйте:) Вот такой вопрос возник, почему вот этот после выполнения
ЗдравствуйтеЕсть программа, которая ищет ромбы в множестве заданных точек и выводит на экран координаты и площадь самого большого из них