Управление потоком: if, for, while

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

В MATLAB блоки управления закрываются ключевым словом end, а не фигурными скобками.

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

Синтаксис if прост: условие без скобок (хотя скобки допустимы), ветки elseif и else, закрытие end. Условие — это логическое выражение; для скалярных условий используют && и || с коротким замыканием.

x = 7;
if x > 10
    disp('большое')
elseif x > 5
    disp('среднее')
else
    disp('малое')
end

Вывод:

среднее

Цикл for

Цикл for пробегает по столбцам массива: переменная цикла принимает значения элементов. Чаще всего перебирают диапазон 1:n. Помните главный совет курса: если тело цикла можно выразить векторно — выражайте; for оставляйте для случаев, где итерации зависят друг от друга.

s = 0;
for k = 1:5
    s = s + k;        % накопление
end
disp(s)               % 15

Вывод:

    15

Цикл while

Цикл while повторяется, пока условие истинно. Он уместен, когда число итераций заранее неизвестно — например, в итерационных численных методах, где считаешь до сходимости. break досрочно выходит из цикла, continue переходит к следующей итерации.

n = 1;
while n < 100
    n = n * 2;        % удвоение
end
disp(n)               % 128 — первое число >= 100

Вывод:

   128

switch для дискретного выбора

Когда вариантов много, читабельнее switch. Он сравнивает значение с метками case; ветка otherwise ловит остальное. В отличие от C, «проваливания» между case нет — каждая ветка автономна.

Как работает под капотом

Условие if в MATLAB истинно, если все элементы массива ненулевые. То есть if v для вектора v эквивалентно if all(v(:)). Это частый источник скрытых багов: программист думает «если хоть один элемент…», а MATLAB проверяет «если все». Когда нужна логика «хотя бы один» или «все», явно пишут any(...) и all(...) — так код читается однозначно.

Стоимость итераций и предвыделение

Если цикл всё же необходим, его пишут грамотно, и главное правило — предвыделение памяти. Растущий внутри цикла массив (result(end+1) = ...) заставляет MATLAB при каждом шаге копировать весь массив в новое, большее место, превращая линейный по смыслу цикл в квадратичный по времени. Лекарство простое: заранее создать массив нужного размера через zeros, а в цикле только записывать в готовые ячейки. Редактор сам предупреждает об этой ошибке подчёркиванием. Второй приём — выносить из тела цикла всё, что не зависит от итерации: вычисленное один раз снаружи не нужно пересчитывать тысячи раз внутри. Эти две привычки делают неизбежные циклы настолько быстрыми, насколько это возможно на интерпретируемом языке.

Частые ошибки

  • Закрывать блоки скобками {} вместо end.
  • Ставить условие-вектор в if, не понимая, что проверяется all.
  • Писать while без изменения условия внутри — бесконечный цикл.
  • Использовать циклы там, где напрашивается векторизация.

Перебор не только чисел

Цикл for в MATLAB устроен гибче, чем кажется. Переменная цикла пробегает столбцы заданного массива, и это значит, что перебирать можно не только диапазон 1:n, но и столбцы матрицы, и ячейки cell-массива. Например, for c = M присвоит c по очереди каждый столбец матрицы M. Это иногда удобнее, чем индексировать по номеру. Тем не менее в большинстве учебных и инженерных задач перебирают именно диапазон индексов — это самая распространённая и понятная форма.

Короткое замыкание и защита от ошибок

Логические операторы && и || обладают коротким замыканием: второе условие вычисляется, только если первое не определило результат. Это не просто оптимизация, а способ писать безопасный код. Запись if n > 0 && v(n) > 5 сначала проверит, что индекс n положителен, и лишь затем обратится к v(n) — иначе при n = 0 произошла бы ошибка индексации. Поэлементные & и | так не умеют: они всегда вычисляют оба операнда. Поэтому в скалярных условиях if предпочитают именно сдвоенные операторы — они и безопаснее, и быстрее. А для непредвиденных сбоев существует конструкция try ... catch, перехватывающая ошибки, чтобы программа не прерывалась, а корректно их обработала.

Итоги

  • Блоки закрываются end; ветки — elseif/else.
  • for идёт по столбцам, while — до условия; break/continue управляют ходом.
  • if над массивом проверяет «все ненулевые» — используйте any/all.
Проверьте себя
1. Чем закрывается блок if в MATLAB?
AФигурной скобкой }
BКлючевым словом end
Cendif
DПустой строкой
2. Когда уместен цикл while?
AВсегда вместо for
BКогда число итераций заранее неизвестно (до сходимости)
CТолько для матриц
DНикогда
3. Что проверяет if v, если v — это вектор?
AЧто хотя бы один элемент ненулевой
BЧто ВСЕ элементы ненулевые
CПервый элемент
DДлину вектора