русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Конструкции


Дата добавления: 2014-11-28; просмотров: 527; Нарушение авторских прав


[elif условие then список]

и

[else список]

не являются обязательными (в данном случае для указания на необязательность конструкций использованы квадратные скобки - не путать с квадратными скобками команды "test"!).

Самая усеченная структура этого оператора

if условие then список

fi

если выполнено условие (как правило это ком получен код завершения "0", то выполняется

"список", иначе он пропускается.

Обратите внимание, что структура обязательно завершается служебным словом "fi". Число "fi", естественно, всегда должно соответствовать числу "if".

Примеры

Пусть написан расчет "if-1"

 

if [ $1 -gt $2 ]

then pwd

else echo $0 : Hello!

Fi

Тогда вызов расчета

if-1 12 11

/home/sae/STUDY/SHELL

 

а

 

if-1 12 13

даст

if-1 : Hello!

Возможно использовать в условии то свойство shell, что команды могут выдавать различный код завершения. Это напоминает приемы программирования на Си. Пусть расчет "if-2" будет

if a=`expr "$1" : "$2"`

then echo then a=$a code=$?

else echo else a=$a code=$?

Fi

тогда вызов

if-2 by by

даст

then a=2 code=0

а

if-2 by be

даст

else a=0 code=1

Еще пример на вложенность

###

# if-3: Оценка достижений

echo -n " А какую оценку получил на экзамене?: " read z

if [ $z = 5 ]

then echo Молодец !

elif [ $z = 4 ]

then echo Все равно молодец !

elif [ $z = 3 ]

then echo Все равно !

elif [ $z = 2 ]

then echo Все !

else echo !

fi

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

6.4.4 Оператор вызова ("case")

Оператор выбора "case" имеет структуру:

case строка in



шаблон) список команд;;

шаблон) список команд;;

...

esac

Здесь "case" "in" и "esac" - служебные слова. "Строка" (это может быть и один символ) сравнивается с "шаблоном". Затем выполняется "список команд" выбранной строки. Непривычным будет служебное слово "esac", но оно необходимо для завершения структуры.

Пример

###

# case-1: Структура "case".

# Уже рассматривавшийся в связи со

# структурой "if" пример проще и

# нагляднее можно реализовать с

# помощью структуры "case".

echo -n " А какую оценку получил на экзамене?: " read z

case $z in

5) echo Молодец ! ;;

4) echo Все равно молодец ! ;;

3) echo Все равно ! ;;

2) echo Все ! ;;

*) echo ! ;;

esac

Непривычно выглядят в конце строк выбора ";;", но написать здесь ";" было бы ошибкой.

Для каждой альтернативы может быть выполнено несколько команд. Если эти команды будут записаны в одну строку, то символ ";" будет использоваться как разделитель команд.

Обычно последняя строка выбора имеет шаблон "*", что в структуре "case" означает "любое значение". Эта строка выбирается, если не произошло совпадение значения переменной (здесь $z) ни с одним из ранее записанных шаблонов, ограниченных скобкой ")". Значения просматриваются в порядке записи.

###

# case-2: Справочник.

# Для различных фирм по имени выдается

# название холдинга, в который она входит case $1 in

ONE|TWO|THREE) echo Холдинг: ZERO ;; MMM|WWW) echo Холдинг: Not-Net ;; Hi|Hello|Howdoing) echo Холдинг: Привет! ;;

*) echo Нет такой фирмы ;;

esac

При вызове "case-2 Hello" на экран будет выведено:

Холдинг: Привет!

А при вызове "case-2 HELLO" на экран будет выведено:

Нет такой фирмы

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

###

# case-3: Реализация меню с помощью команды "case" echo "Назовите файл, а затем (через пробел) наберите цифру, соответствующую требуемой обработке:

1 - отсортировать

2 - выдать на экран

3 - определить число строк"

read x y # x - имя файла, y - что сделать case $y in

1) sort < $x ;;

2) cat < $x ;;

3) wc -l < $x ;;

*) echo "

esac

Мы не знаем такой команды ! " ;;

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

Напишем команду "case-4", которая добавляет информацию к файлу, указанного первым параметром (если параметр один), со стандартного входа, либо (если 2 параметра) из файла, указанного в качестве первого параметра:

###

# case-4: Добавление в файл.

# Использование стандартной переменной.

# "$#" - число параметров при вводе расчета

# ">>" - перенаправление с добавлением в файл case $# in

1) cat >> $1 ;;

2) cat >> $2 < $1 ;;

*) echo "Формат: case-4 [откуда] куда" ;;

esac

"$1" (при "$#=1") - это имя файла, в который происходит добавление со стандартного входа.

"$1" и "$2" (при $#=2) - это имена файлов , из которого ("$1") и в который ("$2") добавлять.

Во всех других случаях (*) выдается сообщение о том, каким должен быть правильный формат команды.

Оператор цикла с перечислением ("for")

Оператор цикла "for" имеет структуру:

for имя [in список значений]

do

список команд done

где "for" - служебное слово определяющее тип цикла, "do" и "done" - служебные слова, выделяющие тело цикла. Не забывайте про "done"! Фрагмент "in список значений" может отсутствовать.

Пусть команда "lsort" представлена командным файлом

for i in f1 f2 f3 do

proc-sort $i done

В этом примере имя "i" играет роль параметра цикла. Это имя можно рассматривать как shell-переменную, которой последовательно присваиваются перечисленные значения (i=f1, i=f2, i=f3), и выполняется в цикле команда "procsort".

Часто используется форма "for i in *", означающая "для всех файлов текущего каталога". Пусть "proc-sort" в свою очередь представляется командным файлом

cat $1 | sort | tee /dev/lp > ${1}_sorted

т.е. последовательно сортируются указанные файлы, результаты сортировки выводятся на печать ("/dev/lp") и направляются в файлы f1_sorted f2_sorted и f3_sorted

Можно сделать более универсальной команду "lsort", если не фиксировать перечень файлов в команде, а передавать произвольное их число параметрами.

Тогда головная программа будет следующей:

for i do

proc-sort $i

done

Здесь отсутствие после "i" служебного слова "in" с перечислением имен говорит о том , что список поступает через параметры команды. Результат предыдущего примера можно получить, набрав

lsort f1 f2 f3

Усложним ранее рассматривавшуюся задачу (под именем "case-2") определения холдинга фирмы. Теперь можно при вызове указывать произвольное количество фирм. При отсутствии в структуре оператора "for" фрагмента "in список значений", значения берутся из параметров вызывающей команды.

###

# holding: Справочник.

# Для различных фирм по имени выдается

# название холдинга, в который она входит for i

do

case $i in

 

 

ONE|TWO|THREE) echo Холдинг: ZERO ;; MMM|WWW) echo Холдинг: Not-Net ;;

 

 

esac done

Hi|Hello|Howdoing) echo Холдинг: Привет! ;;

*) echo Нет такой фирмы ;;

При вызове "holding Hello HELLO ONE" на экране будет:

Холдинг: Привет! Нет такой фирмы Холдинг: Not-Net

Пример

###

# subdir: Выдает имена всех поддиректориев

# директория с именем $dir for i in $dir/*

do

if [ -d $i ]

then echo $i

fi done

Следующий расчет иллюстрирует полезный, хотя и с долей трюкачества, способ повторения одних и тех же действий несколько раз. Переменная "i" принимает здесь пять значений: 1, 2,

3, 4, 5, но внутри цикла эта переменная отсутствует и поэтому ее значение никакой роли не играет и ни чего не меняет. С таким же успехом переменная "i" могла принимать значения, скажем ф о к у с , а в результате точно также было бы пять раз повторено одно и то же вычисление содержимого цикла без изменений.

###

# print-5: Организации пятикратного выполнения команды

for i in 1 2 3 4 5 do

cat file-22 > /dev/lp done

Расчет "print-n" иллюстрирует еще одну полезную возможность в использовании цикла "for". Здесь, после "for i ...", отсутствуют "in ..." и перечень имен, т.е. перечнем имен для "i" становится перечень параметров, а следовательно количество печатаемых экземпляров можно менять.

###

# print-n: Задание числа копий

# через параметры

for i

do

 

done

 

cat file-22 > /dev/lp

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

for i in $*

поскольку значение "$*" - есть список значений параметров.

Отметим различие в специальных переменных "$*" и "$@", представляющих перечень параметров. Первый представляет параметры, как строку, а второй, как совокупность слов.

Пусть командный файл "cmp" имеет вид:

for i in "$*" do

done echo

echo $i

for i in "$@"

do

echo $i done

При вызове

cmp aa bb cc

 

на экран будет выведено

 

aa bb cc aa

bb cc

Оператор цикла с истинным условием ("while")

Структура "while", также обеспечивающая выполнение расчетов, предпочтительнее тогда, когда неизвестен заранее точный список значений параметров или этот список должен быть получен в результате вычислений в цикле.

Оператор цикла "while" имеет структуру:

while условие do

список команд done

где "while" - служебное слово определяющее тип цикла с истинным условием. Список команд в теле цикла (между "do" и "done") повторяется до тех пор, пока сохраняется истинность условия (т.е. код завершения последней команды в теле цикла равен "0") или

цикл не будет прерван изнутри специальными командами ("break", "continue" или "exit"). При первом входе в цикл условие должно выполняться.

###

# print-50: Структура "while"

# Расчет позволяет напечатать 50

# экземпляров файла "file-22" n=0

while [ $n -lt 50 ] # пока n < 50 do

n=`expr $n + 1`

cat file-22 > /dev/lp

done

Обратим внимание на то, что переменной "n" вначале присваивается значение 0, а не пустая строка, так как команда "expr" работает с shell-переменными как с целыми числами, а не как со строками.

n=`expr $n + 1`

т.е. при каждом выполнении значение "n" увеличивается на 1.

Как и вообще в жизни, можно реализовать то же самое и сложнее. Расчет "рr-br" приведен

для иллюстрации бесконечного цикла и использования команды "break", которая обеспечивает прекращение цикла.

###

# рr-br: Структура "while" c "break"

# Расчет позволяет напечатать 50

# экземпляров файла "file-22"

n=0

while true

do

if [ $n -lt 50 ] # если n < 50 then n=`expr $n + 1`

else break

fi

 

done

 

cat file-22 > /dev/lp

Команда "break [n]" позволяет выходить из цикла. Если "n" отсутствует, то это эквивалентно

"break 1". "n" указывает число вложенных циклов, из которых надо выйти, например, "break

3" - выход из трех вложенных циклов.

В отличие от команды "break" команда "continue [n]" лишь прекращает выполнение текущего цикла и возвращает на НАЧАЛО цикла. Она также может быть с параметром. Например, "continue 2" означает выход на начало второго (если считать из глубины) вложенного цикла.

Команда "exit [n]" позволяет выйти вообще из процедуры с кодом возврата "0" или "n" (если параметр "n" указан). Эта команда может использоваться не только в циклах. Даже в линейной последовательности команд она может быть полезна при отладке, чтобы прекратит выполнение (текущего) расчета в заданной точке.

Оператор цикла с ложным условием ("until")

Оператор цикла "until" имеет структуру:

until условие do

список команд

done

где "until" - служебное слово определяющее тип цикла с ложным условием. Список команд в теле цикла (между "do" и "done") повторяется до тех пор, пока сохраняется ложность условия или цикл не будет прерван изнутри специальными командами ("break", "continue" или "exit"). При первом входе в цикл условие не должно выполняться.

Отличие от оператора "while" состоит в том, что условие цикла проверяется на ложность (на ненулевой код завершения последней команды тела цикла) проверяется ПОСЛЕ каждого (в том числе и первого!) выполнения команд тела цикла.

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

Примеры:

until false do

read x

if [ $x = 5 ]

then echo enough ; break else echo some more

fi

done

Здесь программа с бесконечным циклом ждет ввода слов (повторяя на экране фразу "some more"), пока не будет введено "5". После этого выдается "enough" и команда "break" прекращает выполнение цикла.

Другой пример ("Ожидание полдня") иллюстрирует возможность использовать в условии вычисления.

until date | grep 12:00:

do

 

done

sleep 30

Здесь каждые 30 секунд выполняется командная строка условия. Команда "date" выдает текущую дату и время. Команда "grep" получает эту информацию через конвейер и пытается совместить заданный шаблон "12:00:" с временем, выдаваемым командой "date". При несовпадении "grep" выдает код возврата "1", что соответствует значению "ложь", и цикл "выполняет ожидание" в течение 30 секунд, после чего повторяется выполнение условия. В полдень (возможно с несколькими секундами) произойдет сравнение, условие станет истинным, "grep" выдаст на экран соответствующую строку и работа цикла закончится.



<== предыдущая лекция | следующая лекция ==>
Условия проверки строк | Функции в shell


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 2.856 сек.