Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

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

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

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

Добавлен: 13.12.2020

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

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

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

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

51 

3.10. Составные операторы 

присваивания 

В  языке  программирования  С  также  используются 

составные 

операторы

 

присваивания,  которые  объединяют  арифметический 

или  побитовый  оператор  с  оператором  присваивания.  В  общем 
случае составной оператор присваивания имеет следующий вид: 

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

 

Здесь 

оператор

  обозначает  один  из  арифметических  или  побито-

вых  операторов.  Далее  перечислены  все  составные  операторы 
присваивания, определенные в языке программирования С: 

 

+=

 — прибавление числа и присваивание; 

 

-=

 — вычитание числа и присваивание; 

 

*=

 — умножение на число и присваивание; 

 

/=

 — деление на число и присваивание; 

 

%=

 — деление по модулю на число и присваивание; 

 

<<=

 — сдвиг влево числа и присваивание; 

 

>>=

 — сдвиг вправо числа и присваивание; 

 

&=

 — побитовое И и присваивание; 

 

^=

 — побитовое исключающее ИЛИ и присваивание; 

 

|=

 — побитовое ИЛИ и присваивание. 

Работают  составные  операторы  присваивания  следующим  обра-
зом. Сначала выполняется операция над левым и правым операн-
дами  составного  оператора  присваивания,  а  затем  полученный 
результат присваивается левому операнду. Например: 

  int x = 1, y = 2; 
  y += x;    /* y = 3 */ 

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

  y = y + x; 

Отметим,  что  приоритет  составных  операторов  присваивания 
совпадает с приоритетом простого оператора присваивания.  


background image

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

52 

Поэтому выражение: 

  a *= b - c;

,

 

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

  a = a * (b - c);

 

Смысл введения составных операторов присваивания в язык про-

граммирования  C  заключается  в  следующем.  В  микропроцессо-

рах существуют команды, которые работают аналогично состав-

ным  операторам  присваивания.  Причем  эти  команды  работают 

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

операндами и результат этой операции заносят в третий операнд. 

Так  как  язык  программирования  C  разрабатывался  как  язык  ас-

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

ропроцессора и были введены в синтаксис языка С. 

3.11. Операторы инкремента  

и декремента 

Над  переменными  арифметических  типов  определены  также 

унарные операторы: 

 

++

 — инкремент, т. е. увеличение значения числа на единицу; 

 

--

 —  декремент,  т. е.  уменьшение  значения  числа  на  еди- 

ницу. 

Эти операторы могут быть как 

префиксными

, так и 

постфиксны-

ми

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

Операндом  как  префиксного,  так  и  постфиксного  оператора  ин-

кремента или декремента должно быть модифицируемое L-value. 

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

ляется  R-value.  При  этом  префиксные  операторы  инкремента  и 

декремента дают в результате измененное значение переменной, 

а результатом постфиксных операторов инкремента и декремента 

является старое значение переменной. 
Следующий пример демонстрирует разницу между префиксными 

и постфиксными операторами инкремента и декремента: 

  int a, b = 1; 
  a = b++;    /* a = 1, b = 2 */ 


background image

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

53 

  a = ++b;    /* a = 3, b = 3 */ 
  a = b--;    /* a = 3, b = 2 */ 
  a = --b;    /* a = 1, b = 1 */ 

Приоритет  префиксных  операторов  инкремента  и  декремента 
совпадает  с  приоритетом  унарных  операторов.  А  приоритет 
постфиксных  операторов  инкремента  и  декремента  выше  при-
оритета унарных операторов и, следовательно, выше приоритета 
префиксных  операторов  инкремента  и  декремента.  Поэтому  вы-
ражение: 

  ++x++

,

 

вызовет  ошибку  компиляции,  т. к.  результатом  постфиксного 
оператора декремента является R-value. 

 

В языке программирования C++ результатом префиксного опера-
тора  инкремента  или  декремента  является  L-value.  Поэтому  эти 
операторы могут встречаться слева от оператора присваивания. 

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

  int x = 2, y = 3; 
  ++y += x;    /* x = 2, y = 6 */ 

3.12. Условный оператор 

Условный  оператор

  является  тернарным,  обозначается  двумя 

символами: 

?

 и 

:

, и имеет следующий вид: 

  операнд_1 ? операнд_2 : операнд_3

 

Вычисляется  условный  оператор  следующим  образом.  Сначала 
вычисляется  логическое  значение 

операнда_1

.  Если  это  значение 

истинно, то вычисляется 

операнд_2

, значение которого и является 

значением условного оператора. В противном случае вычисляет-
ся 

операнд_3

 и его значение является значением условного опера-

тора.  Например,  в  следующем  примере  с  помощью  условного 
оператора вычисляется минимум из чисел 

x

 и 

y


background image

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

54 

  int x= 1, y = 2, min; 
  min = (x < y) ? x : y;  /* min = 1 */ 

Допускаются следующие типы второго и третьего операндов ус-
ловного оператора: 

 

оба операнда имеют арифметический тип; 

 

оба операнда имеют тип 

void

 

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

 

оба операнда являются структурами или объединениями одно-
го типа; 

 

один операнд является указателем, а второй — пустым указа- 
телем; 

 

один операнд является указателем, а второй указателем на тип 

void

Об  указателях  и  структурах  будет  рассказано  далее.  Теперь  же 
отметим, что приоритет условного оператора ниже, чем приори-
тет  бинарных  операторов,  но  выше  приоритета  оператора  при-
сваивания. 
Результатом  вычисления  условного  оператора  является  R-value. 
При  вычислении  условного  оператора  выполняются  следующие 
преобразования  типов  значений  второго  и  третьего  операндов, 
независимо от того, какой из операндов вычисляется: 

 

если  оба  операнда  имеют  арифметический  тип,  то  результат 
имеет тип операнда с наибольшим диапазоном значений; 

 

если  один  из  операндов  является  указателем  на  тип 

void

,  то 

результат также будет иметь тип указателя на тип 

void

 

если один из операндов является указателем, а другой — пус-
тым указателем, то результат имеет тип не пустого указателя. 

Ассоциативны условные операторы справа налево. Поэтому сле-
дующее выражение: 

  int x = 1, y = 2, z = 3; 
  x < y ? y < z ? --x : --y : --z;   /* x = 0, y = 2, z = 3 */ 

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

  x < y ? (y < z ? --x : --y) : --z; /* x = 0, y = 2, z = 3 */ 


background image

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

55 

 

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

операн-

да_2

,  так  и 

операнда_3

 

являются  L-value  одного  типа.  В  против-

ном случае результатом вычисления условного оператора являет-
ся R-value. 

Учитывая это замечание, в языке программирования С++ можно 
написать так: 

  int x = 1, y = 2; 
  ((x < y) ? x : y) = 0;  /* x = 0, y = 2 */ 

но: 

  int x = 1, y = 2; 
  (x < y) ? x : y = 0;    /* x = 1, y = 2 */ 

т. к.  условный  оператор  имеет  приоритет  выше,  чем  оператор 
присваивания. 

3.13. Оператор "запятая" 

Оператор  "запятая"

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

,

  и  имеет  следую-

щий вид: 

  операнд_1, операнд_2

где операнды могут быть произвольными выражениями. Работает 
оператор  "запятая"  следующим  образом.  Сначала  вычисляется 
значение 

операнда_1

,  а  затем  значение 

операнда_2

.  Значением 

оператора 

,

 является R-value, равное значению 

операнда_2

, а зна-

чение 

операнда_1

 игнорируется. Например: 

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

но: 

  z = x++, x - y;      /* z = 1 */ 

т. к.  оператор  "запятая"  имеет  наименьший  приоритет  из  всех 
операторов. Оператор 

,

 имеет ассоциативность слева направо. 


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