Большие символьные типы (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;