Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4092

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Часть I. Язык программирования С 

46 

Если выражение содержит несколько операторов, которые имеют 
одинаковый  приоритет,  то  порядок  вычисления  этих  операторов 
не определен. 
Для  того  чтобы  задать  порядок  вычисления  операторов,  в  выра-
жении используются круглые скобки. Операторы, заключенные в 
круглые скобки со своими операндами, вычисляются до операто-
ров,  которые  находятся  вне  этих  круглых  скобок.  Например,  в 
следующем выражении оператор 

+

 вычисляется до оператора 

*

  int x = 1, y =2, z; 
  z = (x + y) * y;    /* z = 6 */ 

При  программировании  выражений  лучше  расставлять  скобки, 
это значительно упрощает понимание выражения. 
Если  в  выражении  нет  круглых  скобок,  то  порядок  вычисления 
нескольких подряд идущих одинаковых операторов определяется 

ассоциативностью операторов

. Унарные операторы вычисляют-

ся справа налево, а бинарные наоборот — слева направо. Напри-
мер, выражение: 

  x + y + z,

 

эквивалентно выражению: 

  (x + y) + z

.

 

Кроме того, при разборе выражения компилятор распознает лек-
семы наибольшей длины. Например, выражение: 

  y = ++x;

,

 

интерпретируется как: 

  y = (++x);

,

 

а не как: 

  y = +(+x);

.

 

Принимая  во  внимание,  что  символы  ++  обозначают  оператор 
инкремента, который будет рассмотрен далее. 


background image

Глава 3. Операторы и выражения 

47 

3.7. Приведение типов  
в выражениях 

Приведением типов

  называется  преобразование  значения  одного 

типа  к  значению другого  типа,  при  этом  возможно  как сохране-
ние  величины  этого  значения,  так  и  изменение  этой  величины. 
Часто приведение типов также называют 

преобразованием типов

Если в выражении встречаются переменные и константы разных 
типов,  то  все  они  приводятся  к  типу  с  наибольшим  диапазоном 
значений. Такое приведение типов называется 

неявным

. Перечис-

лим типы по убыванию их диапазонов значений: 

  long double 
  double 
  float 
  unsigned long 
  long 
  unsigned int 
  int 

Как  видим,  в  этой  иерархии  отсутствуют  типы,  диапазон  значе-
ний которых не превышает диапазон значений типа 

int

. Причина 

этого заключается в том, что если выражение содержит операнды 
только  интегральных  типов,  диапазон  которых  не  превышает 
диапазон  типа 

int

,  то  перед  вычислением  это  выражение  всегда 

преобразуется  компилятором  в  эквивалентное  выражение,  все 
операнды которого имеют тип 

int

. Это делается для того, чтобы 

повысить скорость работы программы. 
Приведение типов внутри интегрального типа данных называется 

интегральным расширением

 (integral promotion). 

Приведение  типов  внутри  плавающего  типа  данных  называется 

расширением с плавающей точкой

 (float-point promotion). 

Можно сказать,  что  интегральным  расширением и  расширением  
с  плавающей  точкой  являются  такие  приведения  типов  внутри 
интегрального и плавающего типов соответственно, при которых 
не теряется числовое значение данных приводимого типа. 


background image

Часть I. Язык программирования С 

48 

Стиль программирования на языке C поощряет неявное преобра-
зование типов данных. Ниже приведен пример неявного преобра-
зования типа в выражении: 

  int x = 1; 
  double y = 1.5, z; 
  z = x + y;  /* тип переменной x приводится к типу double */ 

В  заключение  этого  раздела  отметим,  что  неявное  преобразова-
ние типов данных в выражениях определяет полиморфизм встро-
енных  операторов,  который  называется 

принудительным  поли-

морфизмом

 (coercion polymorphism). 

3.8. Оператор преобразования типов 

Для явного преобразования типа выражения используется 

опера-

тор преобразования типа

, который имеет вид: 

  (тип)выражение 

Этот оператор приводит значение 

выражения

 к типу, который ука-

зан в круглых скобках. Например, следующее выражение приво-
дится к типу 

int

  (int)(1.5 / 0.3) 

А в следующем выражении к типу 

int

 приводится только числи-

тель, а тип всего выражения равен 

double

  (int)1.5 / 0.3 

Заметим,  что  приоритет  оператора  преобразования  типа  ниже 
приоритета  унарных  операторов,  но  выше  приоритета  бинарных 
мультипликативных  арифметических  операторов.  Результатом 
оператора преобразования типа является R-value. 

 

В  языке  программирования  С++  результат  оператора  преобразо-
вания типа может дать в результате L-value, если тип, к которому 
приводится выражение, является ссылкой. 

Учитывая замечание, в языке программирования С++ можно на-
писать следующее выражение: 


background image

Глава 3. Операторы и выражения 

49 

  char* p; 
  (int&)p = 10; 

Оператор преобразования типа позволяет выполнить любое пре-
образование  арифметических  типов  данных.  С  помощью  этого 
оператора  также  возможно  преобразовать  любой  тип  данных  в 
тип  данных 

void

.  Однако  при  помощи  этого  оператора  нельзя 

преобразовать тип 

void

 ни в какой другой тип данных. 

3.9. Оператор присваивания 

Оператор  присваивания

  обозначается  символом 

=

  и  имеет  сле-

дующий вид: 

  операнд_1 = операнд_2;

 

В  результате  выполнения  оператора  присваивания 

операнду_1

 

присваивается  значение 

операнда_2

.  При  этом 

операнд_1

  должен 

быть модифицируемым L-value, а 

операнд_2

 представлять R-value. 

 

В связи с этим фактом часто полагают, что L-value является крат-
ким обозначением для left value т. е. значение, которое может ис-

пользоваться  слева  от  оператора  присваивания,  а  R_value — 
кратким обозначением для right value, т. е. значение, которое мо-
жет  использоваться  только  справа  от  оператора  присваивания. 
Это не совсем корректно, но такая трактовка наглядно показывает, 
что собой представляют L

и R

-

value

.

 

Результатом  оператора  присваивания  является  R-value,  значение 
которого  равно  значению 

операнда_2

.  Приоритет  оператора  при-

сваивания ниже приоритета всех бинарных операторов. Поэтому 

операнд_2

 в операторе присваивания может быть выражением. 

При  присваивании  допускаются  разные  типы  операндов.  В  этом 
случае полученное значение выражения, которое находится спра-
ва  от  оператора  присваивания,  неявно  приводится  к  типу  пере-
менной, которая находится слева от оператора присваивания. До-
пускаются  любые  преобразования  между  арифметическими  ти-
пами  данных.  Но  если  диапазон  типа  левого  операнда  меньше 
диапазона  типа  значения  выражения,  то  компилятор  может  вы-
дать предупреждение. Например: 


background image

Часть I. Язык программирования С 

50 

  int x = 1; 
  double d; 
  d = x + 2;  /* d = 3.0 */ 

Но  в  этих  случаях  нужно  быть  внимательным,  т. к.  возможны 

ошибки следующего типа: 

  int x = 1; 
  double d; 
  d = x / 2;  /* d = 0 */ 

В  последнем  примере  не  учитывается,  что  выражение  сначала 

вычисляется, а потом преобразуется к типу левого операнда опе-

ратора  присваивания.  Чтобы  избежать  этой  ошибки,  нужно  ис-

пользовать  плавающий  тип  в  выражении  справа  от  оператора 

равно. Например: 

  int  x = 1; 
  double  d; 
  d = x / 2.0;  /* d = 0.5 */ 

Так как оператор присваивания возвращает R-value, то возможно 

последовательное  использование  операторов  присваивания.  На-

пример,  в  языке  программирования  C  возможна  запись  следую-

щего выражения: 

  int x, y, z; 
  x = y = z = 1;    /* x = 1, y = 1, z =1 */ 

Оно эквивалентно выражению: 

  x = (y = (z = 1));    /* x=1, y = 1, z =1 */ 

То есть последовательные операторы присваивания вычисляются 

справа налево. 

 

В  языке  программирования  С++  оператор  присваивания  возвра-

щает L-value. 

Учитывая  это  замечание,  в  языке  программирования  можно  на-

писать следующее выражение: 

  int n; 
  ++(n = 10);  // n = 11 


Смотрите также файлы