Russian Belarusian English German Japanese Ukrainian

В арифметических выражениях, содержащих элементы различных арифметических типов, C++ Builder в процессе вычислений автоматически осуществляет преобразование типов. Это стандартное преобразование всегда осуществляется по принципу: если операция имеет операнды разных типов, то тип операнда «младшего» типа приводится к типу операнда «старшего» типа. Иначе говоря, менее точный тип приводится к более точному. Например, если в операции участвует короткое целое и длинное целое, то короткое приводится к длинному; если участвует целый и действительный операнды, то целый приводится к действительному и т.д. Таким образом, после подобного приведения типов оба операнда оказываются одного типа. И результат применения операции имеет тот же тип.

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

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

double а = 5.4, b = 2;

int с = а*b;

переменная c получит значение 10, хотя истинное значение должно быть равно 10.8. Это значение действительно будет вычислено в результате умножения а*b, но затем дробная часть будет отброшена, поскольку c целая переменная. Результатом выполнения операторов:

int m = 1, n = 2;

double A = m/n;

будет значение А = 0. Поскольку m и n целые переменные, то деление m/n сведется к целочисленному делению с отбрасыванием дробной части, результат которого равен нулю.

Результат выполнения похожих на предыдущие операторов:

int m = 1;

double n = 2;

double А = m/n;

даст правильный результат А = 0.5. Поскольку в данном случае один из операндов операции деления имеет тип double, то тип другого, целого операнда будет тоже приведен к double и результат деления будет иметь тип double. Еще один пример, который дает совершенно неверный результат:

double а = 300, b = 200;

short с = а*b;

Если реализовать этот пример, то можно заметить, что переменная с получит значение -5536, вместо ожидаемого 60 000. Дело в том, что переменная типа short может хранить значение не больше, чем 32 767. Поскольку выражение в правой части приведенного оператора дает результат 60 000, то его присваивание переменной типа short дает совершенно неверное значение.

Как было видно из некоторых приведенных примеров, неявное автоматическое приведение типов не всегда дает желаемый результат. Это можно исправить, применив операцию явного приведение типов. Она записывается в виде (тип) перед той величиной, которую можно привести к указанному типу. Вернемся к уже рассмотренному примеру:

int m = 1, n = 2;

double A = m/n;

который давал неверное значение переменной A. Этот результат можно исправить, применим во втором операторе явное приведение типа:

double A = (double)m/n;

В этом случае переменная m, к которой применяется операция приведения типа, рассматривается как действительная величина типа double. Тогда и переменная n неявно приводится к типу double, так что деление осуществляется уже не с целыми, а с действительными числами. Результат получается правильным 0.5.

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

TPoint Р;

Р.х = 5;

Р.у = 1;

Label1->Caption = "Координата х = " + IntToStr(Р.х);

то получите сообщение компилятора об ошибке: «Ambiguity between __fastcall Sysutils::IntToStr(int64)' and '__fastcall Sysutils::IntToStr(int)'» (Неоднозначность применения функции IntToStr к параметрам типов __int64 и int). Компилятор,

как Буриданов осел, остановился между двумя (в данном случае идентичными) возможностями и отказывается производить выбор. Помочь компилятору легко, применив в последнем из приведенных операторов явное указание типа int:

Labell->Caption = "Координата х = " + IntToStr((int)Р.х); Подобный текст компилятор обработает без проблем.

Уже в C++ Builder 5 компилятор более «интеллектуальный» и в приведенном примере в подобной помощи не нуждается. Но в некоторых других сложных случаях подобное явное приведение типов может потребоваться.

Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter

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


Поиск по сайту