Kernighan, B. W. and Ritchie, D. M. "The 'C' Programming Language"; Chapter 15

15. Преобразования.

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

Содержание

15.1. Символы и целые.
15.2. Типы float и double - плавающей и двойной точности.
15.3. Плавающие и целочисленные величины.
15.4. Указатели и целые
15.5. Целое без знака.
15.6. Арифметические преобразования.


15.1. Символы и целые.

Символ или короткое целое можно использовать всюду, где можноиспользовать целое. Во всех случаях значение преобразуется к целому.Преобразование более короткого целого к более длинному всегдасопровождается знаковым расширением; целые являются величинами сознаком. Осуществляется или нет знаковое расширение для символов,зависит от используемой машины, но гарантируется, что членстандартного набора символов неотрицателен. Из всех машин,рассматриваемых в этом руководстве, только pdp-11 осуществляет знаковоерасширение. Область значений символьных переменных на pdp-11 меняетсяот -128 до 127; символы из набора ascii имеют положительные значения.Символьная константа, заданная с помощью восьмеричной условнойпоследовательности, подвергается знаковому расширению и можетоказаться отрицательной; например, '\377' имеет значение -1.

Когда более длинное целое преобразуется в более короткое или в char,оно обрезается слева; лишние биты просто отбрасываются.


15.2. Типы float и double - плавающей и двойной точности.

Вся плавающая арифметика в "C" выполняется с двойной точностьюкаждый раз, когда об'ект типа float появляется в выражении, онудлиняется до double посредством добавления нулей в его дробнуючасть. Когда об'ект типа double должен быть преобразован к типуfloat, например, при присваивании, перед усечением double округляетсядо длины float.


15.3. Плавающие и целочисленные величины.

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

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


15.4. Указатели и целые

Целое или длинное целое может быть прибавлено к указателю или вычтеноиз него; в этом случае первая величина преобразуется так, какуказывается в разделе описания операции сложения.

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


15.5. Целое без знака.

Всякий раз, когда целое без знака об'единяется с простым целым,простое целое преобразуется в целое без знака и результат оказываетсяцелым без знака. Значением является наименьшее целое без знака,соответствующее целому со знаком (по модулю 2**размер слова). Вдвоичном дополнительном представлении это преобразование являетсячисто умозрительным и не изменяет фактическую комбинацию битов.

Когда целое без знака преобразуется к типу long, значение результатасовпадает со значением целого без знака. Таким образом, этопреобразование сводится к добавлению нулей слева.


15.6. Арифметические преобразования.

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

  • Сначала любые операнды типа char или shortпреобразуются в int, а любые операнды типаfloat преобразуются в double.
  • Затем, если какой-либо операнд имеет типdouble, то другой преобразуется к типу double,и это будет типом результата.
  • В противном случае, если какой-либо операндимеет тип long, то другой операнд преобразуетсяк типу long, и это и будет типом результата.
  • В противном случае, если какой-либо операндимеет тип unsigned, то другой операндпреобразуется к типу unsigned, и это будет типомрезультата.
  • В противном случае оба операнда будут иметьтип int, и это будет типом результата.