Присваивание

We use cookies. Read the Privacy and Cookie Policy

Хотя на данном этапе это не очевидно, тем не менее арифметические выражения могут выполнять операцию присваивания. Мы уже выполняли присваивание много раз, хотя и в других контекстах. Каждый раз, передавая переменной число, мы выполняем присваивание. То же самое можно делать в арифметических выражениях:

[me@linuxbox ~]$ foo=

[me@linuxbox ~]$ echo $foo

[me@linuxbox ~]$ if (( foo = 5 ));then echo "It is true."; fi

It is true.

[me@linuxbox ~]$ echo $foo

5

В примере выше мы сначала присвоили переменной foo пустое значение и проверили, что она действительно получила пустое значение. Далее выполнили коман­ду if с составной командой (( foo = 5 )). Эта команда имеет два интересных аспекта: (1) она присваивает значение 5 переменной foo и (2) оценивает ее значение как истинное, потому что присваивание прошло успешно.

ПРИМЕЧАНИЕ

Важно запомнить значение оператора = в примере выше. Одиночный знак = выполняет присваивание: выражение foo = 5 говорит: «Сделать значение переменной foo равным 5». Двойной знак == определяет эквивалентность: выражение foo == 5 говорит: «Переменная foo равна 5?» Это обстоятельство может вызывать путаницу, потому что команда test интерпретирует одиночный знак = как оператор сравнения строк. Это еще одна причина предпочесть более современные составные команды [[ ]] и (( )) вместо test.

В дополнение к оператору = командная оболочка поддерживает еще несколько очень полезных операторов присваивания, перечисленных в табл. 34.3.

Таблица 34.3. Операторы присваивания

Форма записи

Описание

параметр = значение

Простое присваивание. Присваивает указанное значение указанному параметру

параметр += значение

Присваивание со сложением. Эквивалентно выражению параметр = параметр + значение

параметр -= значение

Присваивание с вычитанием. Эквивалентно выражению параметр = параметр - значение

параметр *= значение

Присваивание с умножением. Эквивалентно выражению параметр = параметр ? значение

параметр /= значение

Присваивание с целочисленным делением. Эквивалентно выражению параметр = параметр ? значение

параметр %= значение

Присваивание с делением по модулю. Эквивалентно выражению параметр = параметр % значение

параметр++

Постинкремент переменной. Эквивалентно выражению параметр = параметр + 1. (Но см. обсуждение ниже.)

параметр--

Постдекремент переменной. Эквивалентно выражению параметр = параметр - 1

++параметр

Преинкремент переменной. Эквивалентно выражению параметр = параметр + 1

--параметр

Предекремент переменной. Эквивалентно выражению параметр = параметр - 1

Эти операторы присваивания обеспечивают удобный и компактный способ записи многих арифметических вычислений. Особый интерес представляют операторы инкремента (++) и декремента (--), они увеличивают или уменьшают значение своего параметра на 1. Эти операторы заимствованы из языка программирования C и внедрены в несколько других языков программирования, включая bash.

Операторы инкремента и декремента могут находиться перед параметром или после него. Хотя в обоих случаях они увеличивают или уменьшают значение параметра на 1, тем не менее их местоположение играет важную роль. Если оператор помещается перед параметром, сначала выполняется операция инкремента (или декремента) и только потом возвращается измененное значение параметра. Если оператор помещается за параметром, операция выполняется после возврата значения. Такое поведение может показаться странным, но оно реализовано с умыслом. Взгляните на следующий пример:

[me@linuxbox ~]$ foo=1

[me@linuxbox ~]$ echo $((foo++))

1

[me@linuxbox ~]$ echo $foo

2

Если присвоить переменной foo значение 1 и затем увеличить ее значение с помощью оператора ++, следующего за именем переменной, выражение вернет прежнее значение 1 переменной foo. Однако если вывести значение переменной второй раз, мы увидим увеличенное значение. Если поместить оператор ++ перед параметром, мы получим более ожидаемый результат:

[me@linuxbox ~]$ foo=1

[me@linuxbox ~]$ echo $((++foo))

2

[me@linuxbox ~]$ echo $foo

2

Для большинства приложений на языке командной оболочки более полезным будет префиксный оператор.

Операторы ++ и -- часто используются совместно с циклами. Внесем некоторые улучшения в сценарий, демонстрирующий применение оператора деления по модулю, чтобы немного сократить его:

#!/bin/bash

# modulo2 : демонстрация оператора деления по модулю

for ((i = 0; i <= 20; ++i )); do

if (((i % 5) == 0 )); then

printf "<%d> " $i

else

printf "%d " $i

fi

done

printf " "