本页对应的英文页面已更新,但尚未翻译。 若要查看最新内容,请点击此处访问英文页面。

控制流

条件控制 - if、else、switch

条件语句可用于在运行时选择要执行的代码块。最简单的条件语句为 if 语句。例如:

% Generate a random number
a = randi(100, 1);

% If it is even, divide by 2
if rem(a, 2) == 0
    disp('a is even')
    b = a/2;
end

通过使用可选关键字 elseifelseif 语句可以包含备用选项。例如:

a = randi(100, 1);

if a < 30
    disp('small')
elseif a < 80
    disp('medium')
else
    disp('large')
end

再者,当您希望针对一组已知值测试相等性时,请使用 switch 语句。例如:

[dayNum, dayString] = weekday(date, 'long', 'en_US');

switch dayString
   case 'Monday'
      disp('Start of the work week')
   case 'Tuesday'
      disp('Day 2')
   case 'Wednesday'
      disp('Day 3')
   case 'Thursday'
      disp('Day 4')
   case 'Friday'
      disp('Last day of the work week')
   otherwise
      disp('Weekend!')
end

对于 ifswitch,MATLAB® 执行与第一个 true 条件相对应的代码,然后退出该代码块。每个条件语句都需要 end 关键字。

一般而言,如果您具有多个可能的离散已知值,读取 switch 语句比读取 if 语句更容易。但是,无法测试 switchcase 值之间的不相等性。例如,无法使用 switch 实现以下类型的条件:

yourNumber = input('Enter a number: ');

if yourNumber < 0
    disp('Negative')
elseif yourNumber > 0
    disp('Positive')
else
    disp('Zero')
end

条件语句中的数组比较

了解如何将关系运算符和 if 语句用于矩阵非常重要。如果您希望检查两个变量之间的相等性,您可以使用

if A == B, ...

这是有效的 MATLAB 代码,并且当 AB 为标量时,此代码会如期运行。但是,当 AB 为矩阵时,用 A == B 不会测试二者是否相等,而会测试二者相等的位置;结果会生成另一个由 0 和 1 构成的矩阵,并显示元素与元素的相等性。

A = magic(4);
B = A;
B(1,1) = 0;

A == B

ans =

  4×4 logical array

   0   1   1   1
   1   1   1   1
   1   1   1   1
   1   1   1   1

检查两个变量之间的相等性的正确方法是使用 isequal 函数:

if isequal(A, B), ...

isequal 返回 1(表示 true)或 0(表示 false)的标量逻辑值,而不会返回矩阵,因此能被用于 if 函数计算表达式。通过使用上面的 AB 矩阵,您可以获得

isequal(A,B)

ans =

  logical

   0

下面给出另一示例来重点介绍这一点。如果 AB 为标量,下面的程序永远不会出现“意外状态”。但是对于大多数矩阵对(包括交换列的幻方矩阵),所有元素均不满足任何矩阵条件 A > BA < BA == B,因此将执行 else 子句:

if A > B
   'greater'
elseif A < B
   'less'
elseif A == B
   'equal'
else
   error('Unexpected situation')
end

有几个函数对减少标量条件的矩阵比较结果以便用于 if 非常有用,这些函数包括

isequal
isempty
all
any

循环控制 - for、while、continue、break

此部分涵盖为程序循环提供控制的 MATLAB 函数。

for

for 循环按预先确定的固定次数重复一组语句。匹配的 end 用于界定语句结尾:

for n = 3:32
   r(n) = rank(magic(n));
end
r

内部语句的终止分号禁止了循环中的重复输出,循环后的 r 显示最终结果。

最好对循环进行缩进处理以便于阅读,特别是使用嵌套循环时:

for i = 1:m
   for j = 1:n
      H(i,j) = 1/(i+j);
   end
end

while

while 在逻辑条件的控制下将一组语句重复无限次。匹配的 end 用于界定语句结尾。

下面是一个完整的程序,用于演示如何使用 whileifelseend 来寻找区间二分法求多项式的零。

a = 0; fa = -Inf;
b = 3; fb = Inf;
while b-a > eps*b
   x = (a+b)/2;
   fx = x^3-2*x-5;
   if sign(fx) == sign(fa)
      a = x; fa = fx;
   else
      b = x; fb = fx;
   end
end
x

结果生成多项式 x3 - 2x - 5 的根,即

x =
   2.09455148154233

if 语句部分中讨论的与矩阵比较相关的注意事项同样适用于 while 语句。

continue

continue 语句将控制权传递给它所在的 for 循环或 while 循环的下一迭代,并跳过循环体中的任何其余语句。此道理同样适用于嵌套循环中的 continue 语句。也就是说,执行会从遇到 continue 语句的循环开头继续。

下面的示例演示的 magic.m 循环计算文件中的代码行数目的 continue 循环,并跳过所有空行和注释。continue 语句用于前进到 magic.m 中的下一行,而不会在遇到空行或注释行时增加行计数:

fid = fopen('magic.m','r');
count = 0;
while ~feof(fid)
    line = fgetl(fid);
    if isempty(line) || strncmp(line,'%',1) || ~ischar(line)
        continue
    end
    count = count + 1;
end
fprintf('%d lines\n',count);
fclose(fid);

break

break 语句用于提前从 for 循环或 while 循环中退出。在嵌套循环中,break 仅从最里面的循环退出。

下面对前述部分中的示例进行了改进。使用此 break 的优点是什么?

a = 0; fa = -Inf;
b = 3; fb = Inf;
while b-a > eps*b
   x = (a+b)/2;
   fx = x^3-2*x-5;
   if fx == 0
      break
   elseif sign(fx) == sign(fa)
      a = x; fa = fx;
   else
      b = x; fb = fx;
   end
end
x

程序终止 - return

此部分包含用于在程序运行完成之前终止程序的 MATLAB return 函数。

return

return 终止当前命令序列,并将控制权返回给调用函数或键盘。此外,return 还用于终止 keyboard 模式。被调用的函数通常在到达函数末尾时将控制权转交给调用它的函数。您可以在被调用的函数中插入一个 return 语句,以便强制提前终止并将控制权转交给调用函数。

向量化

提高 MATLAB 程序的运行速度的一种方法是向量化构造程序时所使用的算法。其他编程语言可使用 for 循环或 DO 循环,而 MATLAB 可使用向量或矩阵运算。下面提供了一个与创建算法表相关的简单示例:

x = .01;
for k = 1:1001
   y(k) = log10(x);
   x = x + .01;
end

相同代码段的向量化版本为

x = .01:.01:10;
y = log10(x);

对于更复杂的代码,向量化选项并不总是这么明显。

预分配

如果无法向量化某段代码,可以通过预分配存储输出结果的任何向量或数组来提高 for 循环的运行速度。例如,此代码使用函数 zeros 来预分配在 for 循环中创建的向量。这显著提高了 for 循环的执行速度:

r = zeros(32,1);
for n = 1:32
    r(n) = rank(magic(n));
end

如果未经过上述示例中的预分配,MATLAB 解释器会在每次遍历循环时将 r 向量增大一个元素。向量预分配避免了此步骤,并提高了执行速度。