Вы находитесь на странице: 1из 16

1

Лекция 4. Режим программирования


1. Режим программирования.
2. Создание M-файла.
3. Структура script-файла.
4. Структура function-файла.
5. Ввод/вывод данных.
6. Организация разветвлений.
7. Организация циклов.
4.1. Режим программирования
Работа в системе MATLAB возможна в двух режимах: режиме прямых вычислений
(рассмотрен на предыдущих лекциях) и режиме программирования.
Режим программирования предназначен для разработки и выполнения программ
пользователя в среде MATLAB.
Все программы пользователя, создаваемые в MATLAB, сохраняются на диске и
имеют расширение m, поэтому их называют M-файлами.
Различают две разновидности M-файлов:
□ script-файл (файл-сценарий);
□ function-файл (файл-функция).
Особенностью программирования в MATLAB является то, что переменные не
объявляются и не описываются. Система автоматически определяет тип переменной,
которая по умолчанию является матрицей типа double.
При оформлении М-файлов рекомендуется соблюдать следующие правила:
□ включать комментарии, поясняющие назначение переменных, выполняемые
действия и т. п.;
□ во избежание выводов нежелательных промежуточных результатов ставить
точку с запятой.
Вывод листинга M-файла в окне Command Window выполняется по команде:
type <имя M-файла>
4.2. Создание М-файла
Для создания M-файла и его сохранения в папке пользователя необходимо
выполнить следующую последовательность действий:
1. В окне MATLAB выбрать в главном меню пункт File | New и определить тип
создаваемого M-файла — M-file.
2. В раскрывшемся окне Editor набрать текст M-файла построчно.
3. Для сохранения M-файла выбрать в главном меню команду File | Save as.
4. В раскрывшемся окне Save as выбрать требуемую папку, присвоить имя новому
M-файлу (без расширения) и нажать кнопку Save на панели инструментов.
2

Создание новой папки выполняется с помощью контекстного меню в окне Current


Folder.
Сохранение пути к требуемой папке выполняется по команде контекстного меню
Add Path | Selected Folders или команде главного меню File | Set Path. Сохранение
пути к папке позволять в текущей сессии запускать М-файл, не открывая данную
папку.
При запуске M-файлов из текущей папки, путь к ней можно не сохранять.
Для редактирования созданного M-файла необходимо найти его в окне Current
Folder и открыть двойным щелчком левой кнопки мыши на его имени. В окне Editor
выполнить редактирование и сохранить, нажав кнопку Save. Признаком
несохраненного файла является символ " * " после имени файла в верхней строке
окна Editor.
4.3. Структура script-файла
Script-файлом называют создаваемый пользователем M-файл, представляющий собой
основную (управляющую) программу.
Термины "script-файл" и "программа" употребляют в тождественном смысле.
Программа состоит из операторов, записываемых построчно. Как и в режиме прямых
вычислений, одна строка может содержать несколько операторов присваивания.
В первой строке ставится необязательный оператор-заголовок:
script
Имя script-файла выбирается по тем же правилам, что и имя переменной и не может
совпадать именами стандартных объектов MATLAB (встроенных функций, команд и
т. п.). По правилам хорошего стиля программирования желательно, чтобы имя
программы, с одной стороны, отражало ее суть, а с другой, — было коротким.
По тем же правилам, после оператора-заголовка принято ставить команду clc для
очистки окна Command Window, а затем, во избежание конфликта переменных в
Workspace, — команду очистки его содержимого clear.
Пример простейшего script-файла demoS1:

script
clc % очистка окна Command Window
clear % очистка Workspace
close all % закрытие всех графических окон
x1 = randn(1,10000); % нормальный белый шум длины 10000
x2 = rand(1,10000); % равномерный белый шум длины 10000
% гистограмма нормального белого шума
subplot(2,1,1), hist(x1), grid
title('Histogram – Gaussian White Noise')
% гистограмма равномерного белого шума
subplot(2,1,2), hist(x2), grid
3

title('Histogram – Uniform White Noise')

Обращение к script-файлу в режиме прямых вычислений (или из другого script-файла)


осуществляется по его имени:
>> demoS1
По завершении программы будут выведены гистограммы нормального и
равномерного белых шумов (рис. 1).

Histogram – Gaussian W hite Noise


3000

2000

1000

0
-5 -4 -3 -2 -1 0 1 2 3 4

Histogram – Uniform W hite Noise


1500

1000

500

0
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1

Рис. 1. Гистограммы нормального и равномерного белых шумов

Все переменные script-файла являются глобальными, т. е. они сохранятся в Workspace


в процессе и после выполнения программы, и могут быть использованы, например,
для работы в режиме прямых вычислений.
4.4. Структура function-файла
Function-файлом называют создаваемый пользователем M-файл, представляющий
собой внешнюю функцию (в отличие от встроенных функций MATLAB).
Термины "function-файл" и "внешняя функция" употребляют в тождественном
смысле.
Описание function-файла начинается с оператора-заголовка function. Формат
описания при нескольких выходных параметрах имеет вид:
4

function [Y1,Y2,...] = <имя функции>(X1,X2,...)


где:
<имя функции> — имя function-файла, которое выбирается по тем же правилам, что
и имя переменной и не может совпадать с именем встроенной функции; имя function-
файла должно совпадать с именем M-файла, оно выбирается автоматически после
нажатия кнопки Save;
X1, X2,… — список формальных входных параметров;
Y1, Y2,… — список формальных выходных параметров.
После заголовка следует тело функции — записанная построчно программа
определения выходных параметров Y1, Y2,… по входным — X1, X2,…
Пример function-файла demoF1 с несколькими выходными параметрами:

function [MeanG,VarG,MeanU,VarU] = demoF1(M,N)


% вычисление среднего значения и дисперсии
% M реализаций белого шума длины N
% M, N – число строк и столбцов матрицы значений белого шума
% MeanG, VarG - среднее значение и дисперсия нормального белого шума
MeanG = mean(mean(randn(M,N)));
VarG = mean(var((randn(M,N)),1));
% MeanU, VarU - среднее значение и дисперсия равномерного белого
шума
MeanU = mean(mean(rand(M,N)));
VarU = mean(var((rand(M,N)),1));

Обращение к внешней функции с несколькими параметрами подобно обращению к


встроенной функции.
[Y1факт,Y2факт,...] = <имя функции>(X1факт,X2факт,...)
где:
X1факт, X2факт,… — список фактических входных параметров;
Y1факт, Y2факт,… — список фактических выходных параметров.
Разделение параметров function-файлов на формальные и фактические обусловлено
тем, что формальные параметры являются локальными, т. е. они загружаются в
Workspace на время вычисления внешней функции и удаляются после ее вычисления.
Фактические же параметры сохраняются в Workspace.
Фактические значения входных параметров X1факт, X2факт,…, должны быть
определены перед обращением к внешней функции.
Эти значения можно указать непосредственно в круглых скобках. Например, при
обращении к внешней функции demoF1 в режиме прямых вычислений:
>> [MeanG,VarG,MeanU,VarU] = demoF1(100,100)
5

MeanG =
-0.0013
VarG =
0.9895
MeanU =
0.4963
VarU =
0.0813
На рис. 2 представлено содержимое Workspace по завершении вычислений. В данном
случае выбраны одинаковые имена формальных и фактических выходных
параметров, которые сохранились в Workspace, при этом формальные входные
параметры M и N отсутствуют.

Рис. 2. Содержимое Workspace по завершении вычислений с помощью функции


demoF1
Фактические значения входных параметров можно предварительно задать в окне
Command Window, например:

>> M = 100; N = 100;


>> [MeanG,VarG,MeanU,VarU] = demoF1(M,N)
Очевидно, что в этом случае параметры M и N сохранятся в Workspace.
При одном выходном параметре описание function-файла имеет короткий формат:
function Y = <имя функции>(X1,X2,...)
Пример function-файла demoF2 с одним выходным параметром:
6

function VarG = demoF2(M,N)


% вычисление дисперсии M реализаций нормального белого шума длины N
% M, N – число строк и столбцов матрицы значений нормального белого
шума
% VarG - дисперсия нормального белого шума
VarG = mean(var((randn(M,N)),1));

При одном выходном параметре допускается короткий формат обращения:


<имя функции>(X1факт,X2факт,...)
В этом случае значение выходного параметра присваивается переменной ans.
Например, обращение к function-файлу demoF2 в режиме прямых вычислений:
>> demoF2(100,100)
ans =
0.9922
Подобно встроенным функциям, обращение к внешним функциям широко
используется внутри script-файлов.
Например, на основе script-файла demoS1 создадим script-файл demoS2 с
обращением к function-файлу demoF1:

script
clc % очистка окна Command Window
clear % очистка Workspace
close all % закрытие всех графических окон
x1 = randn(1,10000); % нормальный белый шум длины 10000
x2 = rand(1,10000); % равномерный белый шум длины 10000
% гистограмма нормального белого шума
subplot(2,1,1), hist(x1), grid
title('Histogram – Gaussian White Noise')
% гистограмма равномерного белого шума
subplot(2,1,2), hist(x2), grid
title('Histogram – Uniform White Noise')
[MeanG,VarG,MeanU,VarU] = demoF1(1,10000)

При обращении к script-файлу demoS2 будут выведены гистограммы одной


реализации нормального и равномерного белых шумов длины 10000 (рис.1), а также
их средние значения и дисперсии:
>> demoS2
MeanG =
0.0072
7

VarG =
1.0037
MeanU =
0.5024
VarU =
0.0841
4.5. Ввод/вывод данных
Под вводом данных подразумевают присваивание значений переменным.
В режиме программирования это может выполняться как обычно с помощью
оператора присваивания или вручную с клавиатуры с помощью функции:
<имя переменной> = input('<текст>');
где <текст> – пояснение о вводимых данных; точка с запятой блокирует их
автоматический вывод в командную строку.
Функция input приостанавливает выполнение программы и выводит <текст> в
окно Command Window. Пользователь вводит значение переменной и нажимает
<Enter>, после чего продолжается выполнение программы.
Например, если в программе есть строка
а = input(' Введите а = ');
то в окно Command Window будет выведено:
>> Введите а =
С клавиатуры следует ввести значение а и нажать <Enter>:
>> Введите а = 123
Вывод данных в окно Command Window выполняется автоматически, если они не
блокируется точкой с запятой.
Для компактного вывода (в одной строке) имен переменных (одного или нескольких)
одновременно с их значениями удобно воспользоваться функцией:
disp(['<имя переменной 1>' num2str(<имя переменной 1>) ...])
где:
− имена переменных в апострофах и функции num2str вводятся в квадратных
скобках через пробел, подобно элементам численного вектора;
− функция num2str преобразует значение переменной числового типа в
переменную символьного типа (Лекция 3);
− во избежание вывода слитного текста, пользователь должен предусмотреть
пробелы при имени переменной в апострофах.
Примеры вывода значений переменных
>> N = 5; Fs = 1000;
без пробелов:
>> disp(['N =' num2str(N) 'Fs =' num2str(Fs)])
8

N =5Fs =1000
и с пробелами:
>> disp([' N = ' num2str(N) ' Fs = ' num2str(Fs)])
N = 5 Fs = 1000
Если в процессе выполнения программы требуется вывести в окно Command
Window поясняющий комментарий о выполняемом действии, используемых
переменных, полученных результатах и проч., то для этого используют функцию
disp следующего формата:
disp('% <комментарий>')
Например:
>> disp('% Значение Fs равно частоте дискретизации')
% Значение Fs равно частоте дискретизации
Для вывода в заголовке графика текста одновременно с численными значениями
переменных используется функция title с форматом, подобным функции disp.
Например (рис. 3):
>> N = 1000; Fs = 2000;
>> x = randn(1,1000);
>> stem(x), grid
>> title(['Частота дискретизации Fs = ' num2str(Fs) ' Длина шума N
= ' num2str(N)])
9

Частота дискретизации Fs = 2000 Длина ш ума N = 1000


4

-1

-2

-3

-4
0 100 200 300 400 500 600 700 800 900 1000

Рис. 3. График нормального белого шума с выводом заголовка

На основе script-файла demoS2 (разд. 4.4) создадим script-файл demoS3 без вывода
гистограмм с использованием функции disp для вывода поясняющих комментариев:

script
clc % очистка окна Command Window
clear % очистка Workspace
x1 = randn(1,10000); % нормальный белый шум длины 10000
x2 = rand(1,10000); % равномерный белый шум длины 10000
[MeanG,VarG,MeanU,VarU] = demoF1(1,10000);
disp('% Среднее значение и дисперсия нормального белого шума')
disp([' MeanG = ' num2str(MeanG) ' VarG = ' num2str(VarG)])
disp('% Среднее значение и дисперсия равномерного белого шума')
disp([' MeanU = ' num2str(MeanU) ' VarU = ' num2str(VarU)])

При обращении к script-файлу demoS3 будет выведено:


% Среднее значение и дисперсия нормального белого шума
10

MeanG = 0.0014038 VarG = 0.99765


% Среднее значение и дисперсия равномерного белого шума
MeanU = 0.49612 VarU = 0.083891
4.6. Организация разветвлений
В MATLAB предусмотрены две разновидности разветвлений:
• разветвление по условию;
• разветвление в зависимости от значения выражения.
Разветвление по условию организуется с помощью оператора if с форматом:
if <условие1>
<фрагмент1>
elseif <условие2>
<фрагмент2>
...
elseif <условиеN-1>
<фрагментN-1>
...
else
<фрагментN>
end
Действие оператора: если значение <условия1> "истинно", то управление
передается <фрагменту1>, если значение <условия2> "истинно", то управление
передается <фрагменту2> и т. д. вплоть до <условияN-1>; если значения всех
условий "ложно", то управление передается <фрагментуN>; после этого оно
передается части программы, следующей за end.
При одном условии оператор if имеет короткий формат, два варианта которого
представлены в табл. 1.

Таблица 1. Варианты короткого формата оператора if при одном условии

Первый вариант формата Второй вариант формата


if <условие1> if <условие1>
<фрагмент1> <фрагмент1>
end else
<фрагмент2>
еnd

Пример фрагмента программы с первым вариантом формата оператора if (табл. 1):

B = input('Введите B = ');
11

C = input('Введите C = ');
A = C<B;
if (A == false)
disp('% Результат неправильный!')
end

Выполним этот фрагмент программы:


Введите B = 7
Введите C = 10
Результат неправильный!
Пример фрагмента программы со вторым вариантом формата оператора if (табл. 1):
вывести график функции, в зависимости от выполнения условия:

ax + b, если a ≠ 0, b ≠ 0;

x ,
2
иначе.

x = 0:0.01:100;
a = input('Введите a = ');
b = input('Введите b = ');
if ( and ( a~=0, b~=0 ) )
plot( x, a*x+b ), grid, xlabel('x')
title(['a = ' num2str(a) ' b = ' num2str(b) ' a*x+b'])
else
plot( x, x.^2), grid, xlabel('x')
title(['a = ' num2str(a) ' b = ' num2str(b) ' x^2'])
end

Выполнив этот фрагмент программы с данными:


Введите a = 5
Введите b = 17
будет выведен левый график на рис. 4, а с данными:
Введите a = 0
Введите b = 0
правый график.
12

a = 5 b = 17 a*x+b a = 0 b = 0 x. 2
600 10000

9000
500
8000

7000
400
6000

300 5000

4000
200
3000

2000
100
1000

0 0
0 10 20 30 40 50 60 70 80 90 100 0 10 20 30 40 50 60 70 80 90 100
Ось x Ось x

Рис. 4. Вывод графика функции в зависимости от выполнения условия


Разветвление в зависимости от значения выражения (арифметического,
символьного или логического) организуется с помощью оператора switch с
форматом:
switch <выражение>
case <значение1>
<фрагмент1>
case <значение2>
<фрагмент2>
...
otherwise
<фрагментN>
end
Действие оператора: в зависимости от значения <выражения> управление
передается соответствующему <фрагменту>; если значение выражения не равно ни
одному из указанных, то управление передается <фрагментуN> (который может
отсутствовать); после этого управление передается части программы, следующей за
end.
Приведем пример фрагмента программы с оператором switch для решения
предыдущей задачи, в зависимости от значения логического выражения:

x = 0:0.01:100;
a = input('Введите a = ');
b = input('Введите b = ');
switch (and ( a~=0, b~=0 ))
case true
plot( x, a*x+b ), grid, xlabel('x')
13

title(['a = ' num2str(a) ' b = ' num2str(b) ' a*x+b'])


case false
plot( x, x.^2), grid, xlabel('x')
title(['a = ' num2str(a) ' b = ' num2str(b) ' x.^2'])
end

Выполним этот фрагмент программы с данными:


Введите a = 5
Введите b = 17
Значение логического выражения будет равно true и выведен левый график на
рис. 4.
Выполним этот фрагмент программы с данными:
Введите a = 0
Введите b = 0
Значение логического выражения будет равно false и выведен правый график.
4.7. Организация циклов
В MATLAB предусмотрены две разновидности циклов:
• арифметический цикл — с заранее известным (фиксированным) числом
повторений;
• итерационный цикл — с заранее неизвестным (не фиксированным) числом
повторений.
Арифметический цикл организуется с помощью оператора for с форматом:
for <переменная> = <матрица>
<тело цикла>
end
где <переменная> — имя матрицы; <матрица> — матрица, как правило, числовая.
Действие оператора: при изменении значений <переменной>, которой
последовательно присваиваются значения столбцов <матрицы>, повторяется <тело
цикла>, каждый раз с новым значением <переменной>; после этого управление
передается части программы, следующей за end.
Пример фрагмента программы с арифметическим циклом с переменной, заданной
матрицей:

j = 1; % номер столбца матрицы A


B = [0;0]; % длина нулевого вектора равна длине столбца матрицы A
for A = [1 2;3 4]
disp(['% ' num2str(j) '-й вектор-столбец C'])
C = 2.*A+1
14

j = j+1;
B = B + C;
end
B

Выполним этот фрагмент программы:


% 1-й вектор-столбец C
C =
3
7
% 2-й вектор-столбец C
C =
5
9
B =
8
16
В частном случае <переменная> в операторе for может быть вектором, и в теле
цикла будут выполняться операции с его элементами.
Наиболее широко распространен формат оператора for с переменной, заданной
регулярной сеткой:
for <переменная> = <нач.значение>:[<шаг>:]<кон.значение>
<тело цикла>
end
Пример фрагмента программы с арифметическим циклом для вычисления среднего
значения и дисперсии нормального белого шума различных длин N, заданных
регулярной сеткой:
disp('Ср. значение M и дисперсия V норм. БШ длины N')
for N = 1000:1000:4000
x = randn(1,N);
M = mean(x);
V = var(x,1);
disp([' N = ' num2str(N) ' M = ' num2str(M) ' V = '
num2str(V)])
end

Выполним этот фрагмент программы:


Ср. значение M и дисперсия V норм. БШ длины N
N = 1000 M = 0.023616 V = 0.9919
15

N = 2000 M = -0.0028111 V = 0.98273


N = 3000 M = 0.0016785 V = 1.0101
N = 4000 M = 0.0036963 V = 1.0228
Итерационный цикл организуется с помощью оператора while с форматом:
while <условие>
<тело цикла>
end

где <условие> — логическое выражение.


Действие оператора: <тело цикла> повторяется до тех пор, пока <условие>
"истинно", после чего управление передается части программы, следующей за end.
Пример фрагмента программы с итерационным циклом для решения предыдущей
задачи при заранее неизвестной (не фиксированной) конечной длине шума N:

disp('Ср. значение M и дисперсия V норм. БШ длины N')


N = 1000; % начальная длина шума
while N < 5000
x = randn(1,N);
M = mean(x);
V = var(x,1);
disp([' N = ' num2str(N) ' M = ' num2str(M) ' V = '
num2str(V)])
N = N+1000; % увеличение длины шума
end

При выполнении этого фрагмента программы будет выведен тот же результат.


Пример фрагмента программы с итерационным циклом для вычисления суммы с
заранее неизвестным (не фиксированным) числом слагаемых:

S = 0; % сумма для первой итерации


x = 1; % слагаемое для первой итерации
while S <= 10000
S = S + x;
x = x+1;
end
disp(' % Последнее слагаемое x и сумма S')
disp([' x = ' num2str(x) ' S = ' num2str(S)])

Выполним этот фрагмент программы:


% Последнее слагаемое x и сумма S
x = 142 S = 10011
16

Обращаем внимание на то, что выведенное значение суммы превышает пороговое


10000, значит, ее предыдущее значение было меньше порогового, и цикл
продолжился.
Принудительный выход из цикла реализуется оператором:
break
после которого управление передается части программы, следующей за end.
Пример фрагмента программы с итерационным циклом для решения предыдущей
задачи, но с принудительным выходом из цикла:

S = 0; % сумма для первой итерации


x = 1; % слагаемое для первой итерации
while S <= 10000
S = S + x;
x = x+1;
if x>=100
break
end
end
disp(' % Последнее слагаемое x и сумма S')
disp([' x = ' num2str(x) ' S = ' num2str(S)])

Выполним этот фрагмент программы:


% Последнее слагаемое x и сумма S
x = 100 S = 4950
Как только значение слагаемого оказалось равным 100, цикл был прерван.