Выражение – это комбинация операндов и операций, задающая порядок вычисления некоторого значения и принимающая это значение. Операции – это инструкции, определяющие действия над операндами. В качестве операнда могут выступать:
- идентификатор – тип определяется объявлением идентификатора, значение идентификатора определяется типом (для целых и вещественных переменных – значение этого типа; для переменных перечислимого типа – значение одной из констант из соответствующего этому перечислению списка, тип значения - int; для структуры или объединения – совокупность всех значений структуры или объединения; для указателя – адрес некоторого объекта; для массива – массив значений специфицированного в его объявлении типа, либо константный адрес первого элемента массива; для функции – константный адрес точки входа в функцию и список её аргументов, которая возвращает значение определённого типа);
- константа – целочисленное значение, вещественное значение, символ (в выражениях всегда имеет тип int, значение – код символа) или строка (в выражении – константный адрес первого элемента строки);
- другое выражение.
Чтобы значение выражения было определено, значения всех операндов в выражении должны быть определены.
Скобочные выражения.
Круглые скобки применяются для изменения порядка вычисления выражений по сравнению с предусмотренным по умолчанию в зависимости от приоритета операций. Вначале всегда выполняются внутрискобочные операции.
Для случаев использования скобок при группировании выражений с операциями сложения (вычитания) и умножения (деления), а также поразрядными логическими операциями применение скобок не гарантирует именно такой порядок вычислений, который задан скобками, если в выражении используются операции с одинаковым приоритетом. Порядок вычисления может меняться компилятором даже при наличии скобок.
Пример 1.
Компилятор может вычислить выражение a*b/c для целочисленных операндов различными способами. Существует операция «унарный плюс», применение которой гарантирует, что сначала будут вычислены операции в скобках.
Для целочисленных a=30, b=4, c=3 возможные порядки вычислений:
(a*b)/c=(120)/3=40
(a*b)/c=30*(1)=30
(a*b)/c=4*(10)=40
+(a*b)/c=(30*4)/3=40
Константное выражение – это выражение, результатом которого является константа и которое вычисляется на этапе трансляции программы, то есть до её выполнения. Следовательно, операндами константного выражения могут быть только константы.
Пример 2
#define MAXLINE 1000
char line[MAXLINE+1];
int seconds = 60 * 60 ;
Неявное преобразование типов при вычислении выражений.
В выражениях языка C возможно смешение переменных разного типа. При этом происходит преобразование типов, то есть приведение переменной одного типа к другому типу. Это может происходить явно (операция преобразования типа задаётся программистом) и неявно (преобразование типа производится в процессе выполнения программы самой программой). При неявном преобразовании типа все операнды выражения преобразуются к типу операнда, имеющему максимальный диапазон значений.
char
unsigned char
short int
unsigned short int
int Повышение диапазона значений
unsigned int
long int
unsigned long int
float
double
long double
В языке C действуют следующие правила преобразования:
- операнды типа float преобразуются к типу double;
- если один операнд имеет тип long double, то второй преобразуется к типу long double;
- если один операнд имеет тип double, то второй преобразуется к типу double;
- любые операнды типа char или short преобразуются к типу int;
- любые операнды типа unsigned char или unsigned short преобразуются к типу unsigned int;
- если один операнд имеет тип unsigned long, то второй преобразуется к типу unsigned long;
- если один операнд имеет тип long, то второй преобразуется к типу long;
- если один операнд имеет тип unsigned int, то второй преобразуется к типу unsigned int.
В операции присваивания конечный результат приводится к типу переменной в левой части операции присваивания, при этом диапазон значений может как повышаться, так и понижаться. Если идёт понижение диапазона значений, то результат может искажаться из-за того, что исходное число не помещается в новый диапазон, причём характер искажения зависит от соотношения диапазонов значений обоих операндов (например, при преобразовании вещественного числа к целому теряется дробная часть).
Операция явного преобразования типа будет рассмотрена позднее.