- Получить ссылку
- Электронная почта
- Другие приложения
Выражения
Выражения состоят из операторов, констант, функций и
переменных. В языке С выражением является любая правильная
последовательность этих элементов. Большинство выражений в языке С по
форме очень похожи на алгебраические, часто их и пишут, руководствуясь
правилами алгебры. Однако здесь необходимо быть внимательным и учитывать
специфику выражений в языке С.
Порядок вычислений
Порядок вычисления подвыражений в выражениях языка С не
определен. Компилятор может самостоятельно перестроить выражение с целью
создания оптимального объектного кода. Это значит, что программист не
может полагаться на определенную последовательность вычисления
подвыражений. Например, при вычислении выражения
х = f1() + f2();
нет никаких гарантий того, что функция f1() будет вызвана перед вызовом f2().
Преобразования типов в выражениях
Если в выражении встречаются переменные и константы разных
типов, они преобразуются к одному типу. Компилятор преобразует
"меньший" тип в "больший". Этот процесс называется продвижением типов (type promotion). Сначала все переменные типов char и short int автоматически продвигаются в int. Это называется целочисленным расширением. (В С99 целочисленное расширение может также завершиться преобразованием в unsigned int.) После этого все остальные операции выполняются одна за другой, как описано в приведенном ниже алгоритме преобразования типов:
IF операнд имеет тип long double THEN второй операнд преобразуется в long double ELSE IF операнд имеет тип double THEN второй операнд преобразуется в double ELSE IF операнд имеет тип float THEN второй операнд преобразуется в float ELSE IF операнд имеет тип unsigned long THEN второй операнд преобразуется в unsigned long ELSE IF операнд имеет тип long THEN второй операнд преобразуется в long ELSE IF операнд имеет тип unsigned int THEN второй операнд преобразуется в unsigned int
Для тех, кто еще не знаком с общей формой оператора IF, приводим более русифицированную запись алгоритма:
ЕСЛИ операнд имеет тип long double ТО второй операнд преобразуется в long double ИНАЧЕ ЕСЛИ операнд имеет тип double ТО второй операнд преобразуется в double ИНАЧЕ ЕСЛИ операнд имеет тип float ТО второй операнд преобразуется в float ИНАЧЕ ЕСЛИ операнд имеет тип unsigned long ТО второй операнд преобразуется в unsigned long ИНАЧЕ ЕСЛИ операнд имеет тип long ТО второй операнд преобразуется в long ИНАЧЕ ЕСЛИ операнд имеет тип unsigned int ТО второй операнд преобразуется в unsigned int
Кроме того, действует следующее правило: если один из операндов имеет тип long, а второй — unsigned int, притом значение unsigned int не может быть представлено типом long, то оба операнда преобразуются в unsigned long.
На заметку | Описание правил целочисленного расширения в С99 см. в части II. |
После выполнения приведенных выше преобразований оба
операнда относятся к одному и тому же типу, к этому типу относится и
результат операции.
Рассмотрим пример преобразования типов, приведенный на рис. 2.2. Сначала символ ch преобразуется в целое число. Результат операции ch/i преобразуется в double, потому что результат f*d имеет тип double. Результат операции f+i имеет тип float, потому что f имеет тип float. Окончательный результат имеет тип double.
char ch; int i; float f; double d; r e s u l t = ( ch / i ) + ( f * d ) - ( f + i ) ; | | | | | | int | double | | float |_____| |_____| |_____| | | | int double float |_________________| | |__________________________| | double |
Явное преоразование типов: операция приведения типов
Программист может "принудительно" преобразовать значение
выражения к нужному ему типу, используя операцию приведения типов. Общая
форма оператора явного приведения типа:
(тип) выражение
Здесь тип — это любой поддерживаемый тип данных. Например, следующая запись преобразует значение выражения х/2 к типу float:
(float) х/2
Явное преобразование типа — это операция. Оператор
приведения типа является унарным и имеет тот же приоритет, что и
остальные унарные операторы.
Иногда приведение типов может быть весьма полезным.
Допустим, целую переменную нужно использовать как параметр цикла, притом
в вычислении участвует и дробная часть числа. В следующем примере
показано, как с помощью приведения можно сохранить точность:
#include <stdio.h> int main(void) /* печать i и i/2 с дробной частью */ { int i; for(i=1; i<=100; ++i) printf("%d / 2 is: %f\n", i, (float) i /2); return 0; }
Без операции приведения (float) выполнялось бы целочисленное деление. Дробная часть результата выводится благодаря приведению типа переменной i.
Пробелы и круглые скобки
Для повышения удобочитаемости программы при записи
выражений можно использовать пробелы и символы табуляции. Например,
следующие два оператора эквивалентны:
x=10/y~(127/x); x = 10 / y ~(127/x);
Лишние скобки, если они не изменяют приоритет операций, не
приводят к ошибке и не замедляют вычисление выражения. Дополнительные
скобки часто используют для прояснения порядка вычислений. В следующем
примере 2-я строка читается значительно легче:
x = y/3-34*temp+127; x = (y/3) - (34*temp) + 127;
Комментарии
Отправить комментарий