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, и это будет типом результата.

a