Понятие об управляющих структурах.
Как известно, в любом языке программирования, и MATLAB здесь не является исключением, имеются специальные управляющие конструкции, позволяющие задать последовательность выполнения команд в программах. Таким конструкции называют операторами управления и задают с помощью зарезервированных ключевых слов.
Прежде рассматривались лишь достаточно простые программы, в которых все действия выполнялись последовательно. Вместе с тем, для реализации более сложных алгоритмов требуется составлять такие программы, где определенные команды выполняются в зависимости от определенных условий, либо выполняются в цикле, который запускается указанное число раз, либо завершается при выполнении заданного условия.
Очевидно, что в таких ситуациях не обойтись без использования специальных операторов управления, таких как, в частности, операторы цикла for и while, условный оператор if, переключатель switch…case, конструкции try…catch, а также операторы break, continue и return. Указанные операторы можно использовать как в файл-программах, так и в файл-функциях.
Операторы цикла.
Цикл – это процесс повторного выполнения группы инструкций, составляющих тело цикла. Количество выполнений команд можно либо задать заранее, либо определить в процессе выполнения программы. В зависимости от способа определения условия останова (окончания циклических повторений) различают два вида операторов цикла в M-языке: если число выполнений инструкций известно, то используется цикл for (своеобразный аналог цикла do в языке программирования FORTRAN), если же известно лишь условие продолжения цикла, но неизвестно количество его повторений, то применяется цикл while. Операторы цикла можно вводить как в интерактивном режиме (режиме калькулятора), вводя операторы непосредственно с клавиатуры, так и в текстах программ на M-языке.
Синтаксис цикла for имеет вид:
for var=выражение
Инструкции
end
где var – выбираемое программистом имя переменной (параметра, счетчика) цикла; выражение определяет набор возможных значений переменной var и, как правило, имеет вид a1:a2:a3, т.е. переменная цикла при каждом повторении цикла изменяется от начального значения a1 до конечного значения a3 с шагом a2 (если шаг a2 не задан, то по умолчанию он принимается равным 1 – по аналогии с языками программирования FORTRAN и Basic единичное приращение переменной цикла можно опускать), причем цикл завершается как только значение var превысит a3; если инструкций в теле цикла несколько, то они разделяются запятой (,) или точкой с запятой (;), их набор завершается оператором end.
Ниже представлен простейший пример использования цикла for. В результате выполнения программы
for x=1:3:10
y=x/4
end
будем иметь:
y =
0.2500
y =
y =
1.7500
y =
2.5000
В следующем фрагменте программы осуществляется вычисление частичной суммы ряда
.
т.е. складывается 57 членов ряда
s=0
for k=1:1:57
s=s+1./k^2;
end;
В заголовке цикла (управляющем выражении) можно явно указать весь набор значений переменной цикла в виде вектор-строки, например:
for k=[2 5 7 8 11 15 25]
В данном случае цикл будет выполняться семь раз, при этом переменная k будет последовательно принимать значения 2, 5, 7, 8, 11, 15 и 25.
Весьма необычным, хотя и возможным является использование матриц в заголовке цикла:
A=[1 2; 3 4];
for k=A
Количество повторений такого цикла совпадает с количеством столбцов матрицы A, т.е. в рассматриваемом примере цикл повторится два раза. На каждом шаге цикла переменная цикла принимает значение очередного столбца матрицы, т.е. переменная цикла является вектор-столбцом. Так, например, приведенный ниже фрагмент программы вычисляет сумму длин векторов, являющихся столбцами матрицы A:
S=0; A=[1 2; 3 4];
for k=A
s=s+sqrt(k(1)^2+k(2)^2);
end;
Синтаксис цикла while имеет вид:
while Условие
Инструкции
end
где цикл выполняется до тех пор, пока истинно указанное Условие; набор выполняемых в цикле while инструкций, как и в цикле for должен завершаться оператором end; Условие – это любое распознанное MATLAB выражение, которое может включать операции сравнения и логические операции.
Ниже представлен простейший пример программы вычисления синуса 12 значений от 0 до 11 с помощью цикла while:
i=1; t=0;
while t
y(i)=sin(t)
i=i+1;
t=t+1;
end
Рассмотрим более сложный пример вычисления частичной суммы ряда
.
Будем иметь следующий фрагмент реализующей программы:
s=0; k=1; u=1;
while u1.e-8
s=s+u;
k=k+1;
u=1./k^2;
end
Условием останова в данном случае является требование к складываемым элементам ряда быть больше некоторого заранее заданного числа (в данном случае это
): как только очередное слагаемое станет меньше этого числа, условие, стоящее после ключевого слова while, становится ложным и суммирование прекращается.
Отметим, что в соответствии с указанным выше, представленный фрагмент кода, в котором тело цикла занимает несколько строк, также можно вводить с клавиатуры последовательно строка за строкой, при этом необходимо нажимать клавишу Enter каждый раз после ввода очередной строки. После ввода заголовка оператора цикла и нажатия клавиши Enter текстовый курсор перемещается на следующую физическую строку, однако знак строки при вводе () не появляется. По сути, это означает, что MATLAB ожидает дальнейшего ввода с клавиатуры последовательности команд, составляющих тело цикла (эти инструкции могут занимать несколько физических строк командного окна). Текстовый курсор перемещается на следующую строку после нажатия клавиши Enter. После ввода ключевого слова end система MATLAB приступает к циклически повторяющемуся выполнению инструкций из тела цикла. По завершении этого процесса, длительность выполнения которого определяется объемом вычислительной работы, на следующей за циклом строке появляется знак .
Для досрочного прерывания циклов for и while используется команда break, размещаемая внутри тела цикла. Это позволяет размещать фактическое условие останова внутри тела цикла, а не в его заголовке. В таком случае в заголовке цикла можно писать всегда истинное выражение while 1. Если оператор break применяется во вложенном цикле, то он осуществляет выход только лишь из внутреннего цикла.
Оператор continue прерывает выполнение текущего шага цикла, т.е. позволяет перейти к следующей итерации в операторах циклов for и while, игнорируя все операторы, которые следуют за ним в теле цикла. Если оператор continue встречается во вложенном цикле, то осуществляется переход к следующей итерации основного цикла.
В системе MATLAB всюду, где это возможно, вместо операторов цикла следует применять соответствующие команды M-языка, предназначенные для обработки массивов, ввиду того, что при этом существенно сокращается время вычислений. Так, например, вместо фрагмента программы
k=0;
for x=0:0.1:100
k=k+1;
y(k)=sin(x);
end;
целесообразнее использовать операции с массивами
x=0:0.1:100;
y=sin(x);
Замену операторов цикла эквивалентными им по результату функциями M-языка принято называть векторизация кода [7,69-71,109,132,177].
Операторы ветвления.
К операторам ветвления относятся условный оператор if и оператор переключения switch, которые позволяют создать такие алгоритмы, в ко-
торых при заданных условиях выполняются те или иные блоки команд.
Рассмотрим условный оператор if, использующий ключевые слова if (если), else (иначе), elseif (иначе если), end (конец всей конструкции).
Наиболее простой синтаксис применения оператора if имеет вид:
if условие
Инструкции
end
где условие – произвольное выражение (чаще всего включающее в себя операции сравнения и логические операции), истинность или ложность которого понимается как отличие от нуля или равенство нулю (заметим, что в логических выражениях в системе MATLAB допускается использование массивов, причем в тех случаях, когда значением таких выражений является массив истинность условия наступает, когда истинны (не равны нулю) все элементы массива, ну а если хотя бы один элемент такого массива отличен от нуля, то условие считается ложным, ложным условие считается и при использовании пустого массива).
При выполнении простейшего фрагмента программы
A=[1 2; 3 0];
if A
b=1;
else
b=2;
получим, что переменная b примет значение 2, в силу того, что матрица A содержит один нулевой элемент, в результате чего все условие считается ложным. Отметим, что запись типа if A по своему действию полностью эквивалентна записи if A~=0 и записи if all(A(:)).
Если заданное условие является истинным, то Инструкции выполняются, если же условие является ложным, то Инструкции не выполняются, и программа переходит к выполнению команд, расположенных после слова end. Набор выполняемых инструкций всегда должен завершиться оператором end. В более общем случае синтаксис оператора if следующий:
if условие_1
Инструкции_1
elseif условие_2
Инструкции_2
elseif условие_3
Инструкции_3
…
else
Инструкции
end
Поясним, что в такой конструкции может быть много ветвей с ключевым словом elseif, при этом если справедливо условие условие_1, то выполняется набор команд Инструкции_1, если справедливо условие условие_2, то выполняется набор команд Инструкции_2 и т.д. Если же все эти условия оказываются ложными, то выполняются команды, расположенные после слова else. Отметим, что с одной стороны число ветвей elseif неограниченно, с другой – ветви elseif могут отсутствовать вовсе. Рассмотренный условный оператор завершается ключевым словом end.
Покажем, как используется конструкция if…else…elseif…end на примере простейшей файл-программы temperature (сохраненной в файле temperature.m):
function temperature(t)
if(t
disp(‘Морозная погода’)
elseif and(t0, t
disp(‘Холодная погода’)
elseif and(t10, t
disp(‘Прохладная погода’)
elseif and(t18, t
disp(‘Теплая погода’)
else
disp(‘Жаркая погода’)
end
Работоспособность приведенной файл-функции несложно проверить, задавая произвольные значения температуры в качестве аргумента функции temperature. Так, например, будем иметь:
temperature(-30)
Морозная погода
temperature(5)
Холодная погода
temperature(11)
Прохладная погода
temperature(21)
Теплая погода
temperature(27)
Жаркая погода
Рассмотренный оператор break не работает вне циклов for и while. В соответствующих случаях нужно использовать оператор return. Так, например, последний применяется совместно с условными операторами в теле файл-функций для реализации досрочного завершения функции и выхода из нее. В качестве характерного примера приведем файл-функцию factorial вычисления факториала целого положительного числа (сохраненную в файле factorial.m):
function res=factorial(n)
res=1;
if n==1
return
else
for i=2:n
res=res.*i;
end
end
Если входной параметр данной функции равен единице, то оператор return осуществляет досрочный выход из функции ввиду того, что правильный результат (res=1;) уже сформирован.
Если оператор return не используется, нормальное завершение функции наступает по исчерпании всех инструкций, размещенных в теле функции.
Нередко условные операторы совместно с оператором break, размещаемые внутри цикла, используются для досрочного выхода из цикла. Более того, иногда такое условие и вовсе является единственным, например:
prod=1; i=1;
while 1
prod=prod.*i
i=i+1;
if i9
break
end
end
Очевидно, что в данном примере цикл без команды break, работающей совместно с условным оператором if, был бы бесконечным. Таким образом, цикл оказывается конечным, в результате выполнения фрагмента программы будет возвращено значение произведения целых чисел от единицы до девяти (факториал девяти).
Алгоритмы, в которых должен осуществляться множественный выбор, можно реализовать посредством оператора переключения switch, который является эффективной альтернативой использованию оператора if. Ниже представлен синтаксис переключателя switch (аналогом последнего в языке программирования FORTRAN является конструкция SELECT CASE):
switch выражение
case значение_1
Инструкции
case значение_2
Инструкции
case {значение_3, значение_4,…}
Инструкции
…
otherwise
Инструкции
end
В данной конструкции, прежде всего, вычисляется значение выражения выражение (это может быть скалярное числовое значение либо строка символов). Далее это значение сравнивается со значениями значение_1, значение_2, значение_3, значение_4 и т.д. (которые могут быть числовыми либо строковыми). Если найдено совпадение, то выполняются Инструкции, стоящие после соответствующего ключевого слова case. В противном случае выполняются Инструкции, расположенные между ключевыми словами otherwise и end. Строк со словом case может быть сколько угодно, но строка с ключевым словом otherwise должна быть одна. Конструкция {значение_3, значение_4,…} означает, что в строке с ключевым словом case может находиться массив ячеек (в таком случае оператор case будет истинным, если значение выражения выражение совпадает с любым из значений этого массива ячеек).
Заметим, что в случае, когда выражение представляет собой строку символов, соответствующий оператор case будет истинным, если функция вида strcmp(выражение,значение) возвращает значение 1 (истина).
Следует указать на важную особенность переключателя switch в языке программирования MATLAB: если в переключателе switch выполнена одна из ветвей, то остальные ветви этого переключателя выполняться не будут, поэтому никакие дополнительные операторы, позволяющие избежать выполнения других ветвей в данном случае не требуются (в отличие, например, от языков программирования C/C++).
Приведенная ниже файл-программа seasons (сохраненная в файле seasons.m) демонстрирует работу переключателя switch:
switch lower(s)
case{‘декабрь’,’январь’,’февраль’}
disp(‘Время года — зима’)
case{‘март’,’апрель’,’май’}
disp(‘Время года — весна’)
case{‘июнь’,’июль’,’август’}
disp(‘Время года — лето’)
case{‘сентябрь’,’октябрь’,’ноябрь’}
disp(‘Время года — осень’)
otherwise
disp(‘Неизвестное время года’)
end
Представленная программа позволяет определить, к какому времени года относится месяц, заданный в качестве значения переменной s (поясним, что функция lower(s) преобразовывает все символы заданной текстовой строки s к строчным). Если переменной s присвоить число либо строковое значение, которое не является названием месяца, то программа распознает его как неизвестное время года. Например, имеем:
s=’август’;
seasons
Время года — лето
s=’ОктЯбрЬ’;
seasons
Время года — осень
s=’апрель’;
seasons
Время года — весна
s=’январь’;
seasons
Время года — зима
s=’125′;
seasons
Неизвестное время года
Прочие операторы.
Помимо рассмотренных, в системе MATLAB, разумеется, предусмотрены также прочие специальные операторы, позволяющие, в частности, избежать оши
