while(years < 100) {
wisdom = wisdom + 1;
printf(" %d %d\n" , years, wisdom);
}
В операторах и выражениях, вообще говоря, должны использоваться переменные и константы только одного типа. Если все же вы смешаете типы в одном выражении, то компилятор с языка Си не считает программу неправильной, как это произошло бы при программировании на Паскале. Вместо этого компилятор использует набор правил для автоматического преобразования типов. Это очень удобно, но может оказаться и опасным, особенно если вы допустили смешение типов нечаянно. (Например, программа lint, работающая в операционной системе UNIX, проверяет несоответствие типов.) Нам представляется разумным привести несколько основных правил, касающихся преобразования типов:
1. Если операция выполняется над данными двух различных типов, обе величины приводятся к "высшему" из двух типов. Этот процесс называется "повышением" типа.
2. Последовательность имен типов, упорядоченных от "высшего" к "низшему", выглядит так: double, float, long, int, shortи char. Применение ключевого слова unsignedповышает ранг соответствующего типа данных со знаком.
3. В операторе присваивания конечный результат вычисления выражения в правой части приводится к типу переменной, которой должно быть присвоено это значение. Данный процесс может привести к "повышению" типа, как описано выше, или к "понижению, при котором величина приводится к типу данных, имеющему более низкий приоритет.
Повышение" типа обычно происходит гладко, в то время как понижение" может привести к затруднениям. Причина этого проста: все число целиком может не поместиться в элементе данных низшего типа. Переменная типа charможет иметь целое значение 101, но не 22334. Пример, приведенный ниже, иллюстрирует применение этих правил.
/* Преобразования*/
main()
{
char ch;
int i;
float fl;
fl = i = ch = 'А'; /* строка8 */
printf(" ch = %c, i = %d, fl = %2.2f\n", ch, i, fl);
ch = ch + 1; /* строка10 */
i = fl + 2*ch; /* строка11 */
fl = 2.0*ch + 1; /* строка12*/
printf(" ch = %c, i = %d, fl = %2.2f\n", ch, i, fl);ch = 2.0e30; /* строка 14 */
printf(" Теперь ch = %с \n" , ch);
}
Выполнив программу "преобразования", получим следующие результаты:
ch =A, i = 65, fl = 65.00
ch =B, i = 197, fl = 329.00
Теперь ch =
Вот что происходит в программе.
Строки 8 и 9: Величина ' А'присваивается символьной переменной ch. Переменная iполучает целое значение, являющееся преобразованием символа ' А'в целое число, т. е ' 65'. И наконец, перемен ная flполучает значение 65.00, являющееся преобразованием числа 65в число с плавающей точкой.
Строки 10 и 13: Значение символьной переменной 'А'преобразуется в целое число 65, к которому затем добавляется 1. После этого получившееся в результате число 66преобразуется в код символа Ви помещается в переменную ch.
Строки 11 и 13. При умножении на 2значение переменной chпреобразуется в целое число (66). При сложении с величиной переменной flполучившееся в результате число (132)преобразуется в число с плавающей точкой. Результат (197.00)преобразуется в число целого типа и присваивается переменной i.
Строки 12 и 13. Перед умножением на 2.0значение переменной ch(' В')преобразуется в число с плавающей точкой. Перед выполнением сложения величина переменной i(197)преобразуется в число с плавающей точкой, а результат операции (329.00)присваивается переменной fl.
Строки 14 и 15: Здесь производится попытка осуществить преобразование типов в порядке убывания старшинства - переменная chполагается равной сравнительно большому числу. Результаты оказываются неутешительными. Независимо от переполнения и усечения, которые имеют место, в итоге на нашей системе мы пoлучили код, соответствующий какому-то непечатаемому знаку.
На самом деле существует еще один вид преобразования типов. Для, сохранения точности вычислений при арифметических операциях все величины типа floatпреобразуются в данные типа double. Это существенно уменьшает ошибку округления. Конечный результат, естественно, преобразуется обратно в число типа float, если это диктуется соответствующим оператором описания. Вам нет необходимости заботиться о выполнении подобных преобразований, но должно быть приятно сознавать, что компилятор стоит на страже ваших интересов.
Читать дальше