Большие символьные типы (wchar_t
, char16_t
и char32_t
) преобразуются в наименьший целочисленный тип int
, unsigned int
, long
, unsigned long
, long long
или unsigned long long
, которому соответствуют все возможные значения этого символьного типа.
Если операнды оператора имеют разные типы, они обычно преобразуются в общий тип. Если любой из операндов имеет беззнаковый тип, то тип, в который преобразуются операнды, зависит от относительных размеров целочисленных типов на машине.
Как обычно, сначала осуществляются целочисленные преобразования. Если полученные в результате типы совпадают, то никаких дальнейших преобразований не нужно. Если оба (возможно преобразованных) операнда имеют одинаковый знак, то операнд с меньшим типом преобразуется в больший тип.
При разных знаках, если тип беззнакового операнда больший, чем у знакового операнда, знаковый операнд преобразуется в беззнаковый. Например, при операторах типа unsigned int
и int
, int
преобразуется в unsigned int
. Следует заметить, что если значение типа int отрицательное, результат преобразуется так, как описано в разделе 2.1.2.
Остается случай, когда тип знакового операнда больше, чем беззнакового. В данном случае результат зависит от конкретной машины. Если все значения беззнакового типа соответствуют большему типу, то операнд беззнакового типа преобразуется в знаковый. Если значения не соответствуют, то знаковый операнд преобразуется в беззнаковый. Например, если операнды имеют типы long
и unsigned int
и размер у них одинаковый, операнд типа long
будет преобразован в unsigned int
. Если тип long
окажется больше, то unsigned int
будет преобразован в long
.
Арифметические преобразования проще всего изучить на примерах.
bool flag; char cval;
short sval; unsigned short usval;
int ival; unsigned int uival;
long lval; unsigned long ulval;
float fval; double dval;
3.14159L + 'a'; //
dval + ival; //
dval + fval; //
ival = dval; //
flag = dval; //
cval + fval; //
sval + cval; //
cval + lval; //
ival + ulval; //
usval + ival; //
//
uival + lval; //
//
В первом выражении суммы символьная константа 'a'
имеет тип char
, являющийся числовым (см. раздел 2.1.1). Какое именно это значение, зависит от используемого машиной набора символов. На машине авторов, где установлен набор символов ASCII, символу 'a'
соответствует число 97
. При добавлении символа 'a'
к значению типа long double
значение типа char
преобразуется в тип int
, а затем в тип long double
. Это преобразованное значение добавляется к литералу. Интересны также два последних случая, где происходит преобразование беззнаковых значений. Тип результата этих выражений зависит от конкретной машины.
Упражнение 4.34. С учетом определений переменных данного раздела объясните, какие преобразования имеют место в следующих выражениях:
(a) if (fval) (b) dval = fval + ival; (c) dval + ival * cval;
Помните, что возможно придется учитывать порядок операторов.
Упражнение 4.35. С учетом определений
char cval; int ival; unsigned int ui;
float fval; double dval;
укажите неявные преобразования типов, если таковые вообще имеются.
(a) cval = 'a' + 3; (b) fval = ui - ival * 1.0;
(с) dval = ui * fval; (d) cval = ival + fval + dval;