22.2. Локальные переменные


Что такое "локальная" переменная?

локальные переменные

Переменные, объявленные как локальные, имеют ограниченную область видимости, и доступны только в пределах блока, в котором они были объявлены. Для функций это означает, что локальная переменная "видна" только в теле самой функции.

Пример 22-11. Область видимости локальных переменных

  1. #!/bin/bash
  2. func ()
  3. {
  4.   local loc_var=23       # Объявление локальной переменной.
  5.   echo
  6.   echo "\"loc_var\" в функции = $loc_var"
  7.   global_var=999         # Эта переменная не была объявлена локальной.
  8.   echo "\"global_var\" в функции = $global_var"
  9. }
  10. func
  11. # Проверим, "видна" ли локальная переменная за пределами функции.
  12. echo
  13. echo "\"loc_var\" за пределами функции = $loc_var"
  14.                                       # "loc_var" за пределами функции =
  15.                                       # Итак, $loc_var не видна в глобальном контексте.
  16. echo "\"global_var\" за пределами функции = $global_var"
  17.                                       # "global_var" за пределами функции = 999
  18.                                       # $global_var имеет глобальную область видимости.
  19. echo                                  
  20. exit 0
Caution

Переменные, объявляемые в теле функции, считаются необъявленными до тех пор, пока функция не будет вызвана. Это касается всех переменных.

  1. #!/bin/bash
  2. func ()
  3. {
  4. global_var=37    #  Эта переменная будет считаться необъявленной
  5.                  #+ до тех пор, пока функция не будет вызвана.
  6. }                # КОНЕЦ ФУНКЦИИ
  7. echo "global_var = $global_var"  # global_var =
  8.                                  #  Функция "func" еще не была вызвана,
  9.                                  #+ поэтому $global_var пока еще не "видна" здесь.
  10. func
  11. echo "global_var = $global_var"  # global_var = 37
  12.                                  # Переменная была инициализирована в функции.



22.2.1. Локальные переменные делают возможной рекурсию.

Хотя локальные переменные и допускают рекурсию, [52] но она сопряжена с большими накладными расходами и не рекомендуется для использования в сценариях. [53]

Пример 22-12. Использование локальных переменных при рекурсии

  1. #!/bin/bash
  2. #               факториал
  3. #               ---------
  4. # Действительно ли bash допускает рекурсию?
  5. # Да! Но...
  6. # Нужно быть действительно дубинноголовым, чтобы использовать ее в сценариях
  7. # на языке командной оболочки.
  8. MAX_ARG=5
  9. E_WRONG_ARGS=65
  10. E_RANGE_ERR=66
  11. if [ -z "$1" ]
  12. then
  13.   echo "Порядок использования: `basename $0` число"
  14.   exit $E_WRONG_ARGS
  15. fi
  16. if [ "$1" -gt $MAX_ARG ]
  17. then
  18.   echo "Выход за верхний предел (максимально возможное число — 5)."
  19.   # Вернитесь к реальности.
  20.   # Если вам захочется поднять верхнюю границу,
  21.   # то перепишите эту программу на настоящем языке программирования.
  22.   exit $E_RANGE_ERR
  23. fi
  24. fact ()
  25. {
  26.   local number=$1
  27.   # Переменная "number" должна быть объявлена как локальная,
  28.   # иначе результат будет неверный.
  29.   if [ "$number" -eq 0 ]
  30.   then
  31.     factorial=1    # Факториал числа 0 = 1.
  32.   else
  33.     let "decrnum = number - 1"
  34.     fact $decrnum  # Рекурсивный вызов функции.
  35.     let "factorial = $number * $?"
  36.   fi
  37.   return $factorial
  38. }
  39. fact $1
  40. echo "Факториал числа $1 = $?."
  41. exit 0

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


[52]    Herbert Mayer определяет рекурсию, как "...описание алгоритма с помощью более простой версии того же самого алгоритма..." Рекурсивной называется функция, которая вызывает самого себя.

[53]    Слишком глубокая рекурсия может вызвать крах сценария.