结构化编程

流程控制语句和逻辑运算符

与大多数编程语言相同,MATLAB有以下流程控制语句:

流程控制语句 作用
if, elseif, else 若if语句为真,则执行子句
switch, case, otherwise 根据switch语句内容判断执行哪个子句
while 重复执行子句直到while中的条件为假
for 执行子句固定次数
try, catch 执行子句并捕获执行过程中的异常


break 跳出循环
continue 直接进入下一次循环
end 结束子句
pause 暂停程序
return 返回到调用函数处

上述所有循环和条件语句都要在末尾以end闭合.
MATLAB还有以下逻辑运算符:

运算符 意义
< 小于
<= 小于或等于
> 大于
>= 大于或等于
== 等于
~= 不等于
&&
||

&&和||运算符支持逻辑短路功能.

流程控制语句示例

下面演示各流程控制语句:

1. if 语句:
image.png

  1. if rem(a, 2) == 0
  2. disp('a is even');
  3. else
  4. disp('a is odd');
  5. end

remainder 余数
rem(a , b )=a%b(取余)
两个正负不同的数相除rem和mod不一样的,rem结果正负和被除数一致,mod和除数一致

2. switch 语句:

expression 表达式
image.png

input_num=1;        %如果不加入';',在程序里会有num值的输出,加入是只计算不输出
switch input_num
case -1
    disp('negative 1');        % negative    负
case 0
    disp('zero');
case 1
    disp('positive 1');
otherwise
    disp('other value');
end

3. while 语句:

image.png

n = 1;
while prod(1:n) < 1e100        
%prod product 数组元素的乘积(在本题中意思就为阶乘);factorial(n)阶乘
    n = n + 1;
end

4.for语句

image.png

for n=1:10
    a(n)=2^n;
end
disp(a)

5. break 语句

  • 在不能保证收敛的迭代中使用
  • 终止 for 或 while 循环的执行 ```matlab x = 2; k = 0; error = inf; error_threshold = 1e-32; while error > error_threshold if k > 100
      break
    
    end x = x - sin(x)/cos(x); error = abs(x - pi); k = k + 1; end
<a name="qqI2E"></a>
### 使用循环语句应尽量预先分配内存空间   
Pre-allcating Space to Variables 为变量预分配空间                                     <br />若一个变量所需要的内存空间是一个可预测的定值,我们应尽量提前为其分配内存空间.<br />以下面两段程序为例,演示这一点:<br />tic toc  用来计时
<a name="htslh"></a>
#### 没有预先分配
```matlab
tic
for ii = 1:2000
    for jj = 1:2000
        A(ii,jj) = ii + jj;
    end
end
toc
%     程序输出‘历时 2.432008 秒。’

程序输出

预先分配

tic
A = zeros(2000, 2000);     % 预先为变量分配内存空间
for ii = 1:size(A,1)
    for jj = 1:size(A,2)
        A(ii,jj) = ii + jj;
    end
end
toc
% 程序输出‘历时 0.036943 秒。’

可以看到,程序一比程序二所用的时间更长.这是因为: 对于程序一,没有预先为变量A分配内存,因此每当A的形状发生改变时,都需要重新为A分配内存地址,这花费了更多的时间.

  • 练习

1.将A矩阵元素复制到矩阵B
2.在B矩阵中,将负数值更改为 0
image.png

A = [0 -1  4; 9 -14  25 ; -34 49 64];
B = A;
for i=1:3
    for j=1:3
        if B(i,j)<0
            B(i,j)=0;
        end
    end
end
disp(B)
%    或者将i,j赋值为i=1:size(A,1)    j=1:size(A,2)
%分别为一维二维的大小

编写脚本时应注意的问题

在脚本开头应添加语句清空工作区

在每个脚本的开头,应添加下述语句,清空工作区缓存以及之前程序运行的痕迹:

clear all     % 清空工作区内存中的变量
close all         % 关闭之前程序绘制的图像
clc                 % 清空之前程序在终端的输出

在运算和赋值语句后应添加分号;抑制输出

在所有运算和赋值语句都应该添加分号;抑制输出,若需要向终端输出一个变量,应对其调用disp方法.

使用省略号… 拼接多行语句

在MATLAB中,省略号 … 可以将多行语句拼接为一行,灵活使用该语句可以提高代码可读性.

annPoints_sampled = annPoints(annPoints(:,1)>x1 & ...
    annPoints(:,1) < x2 & ...
    annPoints(:,2) > y1 & ...
    annPoints(:,2) < y2);

暂停运行

Ctrl+F5

函数

与其他语言相似,MATLAB也可以定义函数.与脚本类似,函数可以被存入函数名.m文件中,也可以以函数句柄的形式定义在内存中.

查看内置函数

我们可以使用which命令查看内置函数源代码文件的位置,与edit命令结合可以查看内置函数的源代
运行下面语句可以打开MATLAB内置的 mean 函数的源文件:

edit(which('mean.m'))

可以在编辑器中看到 mean 函数的源代码如下:
image.png

以函数名.m文件形式定义函数

scripts(脚本)和function(函数)都是包含MATLAB命令的.m文件
当我们需要执行时编写函数程序的时候用的就是function

Scripts Functions
没有输入参数
没有输出参数
有输入参数
有输出参数
对数据库中的数据进行操作
全局工作区
对数据库中的数据进行操作
本地工作区

在MATLAB文件中定义函数的格式如下:

function [输出变量名] = 函数名(输入变量名)
% 函数的文档

函数代码
  • function 是一个关键字,声明该文件中保存的是一个函数.
  • 输入变量 和 输出变量 是非必须的,函数既可以没有输入变量,也可以没有输出变量.
  • 函数名 应与 .m 文件名相同,且不包含特殊字符(最好不要有中文).

    MATLAB内置的函数参数

    在MATLAB中,内置了一些函数参数如下:
函数参数 意义
imputname 输入变量名列表
mfilename 函数源代码文件名
nargin 输入变量数
nargout 输出变量个数
varargin 可变长输入参数列表
varargout 可变长输出参数列表

MATLAB不提供其他高级语言的指定默认参数值以及函数重载等语法,但灵活使用上述内置的函数参数,可以在一定程度上实现指定默认参数值以及方法重载:

function [volume]=pillar(Do,Di,height)
if nargin==2,    %如果输入变量数为两个height=1
    height=1;
end
volume=abs(Do.^2-Di.^2).*height*pi/4;

函数定义示例

1.自由落体

  • 下面程序用来计算自由落体运动中位移量:

image.png
新建脚本script(或者新建函数)→输入函数→保存(save)→使用
注意:文件名和函数名一致,否则会显示未定义

function x = freebody(x0,v0,t)
% calculation of free falling            自由落体计算
% x0: initial displacement in m        初始位移,单位为 m
% v0: initial velocity in m/sec        初始速度,单位为 m/sec
% t: the elapsed time in sec            经过的时间,以秒为单位
% x: the depth of falling in m        下落深度,单位为m
x = x0 + v0.*t + 1/2*9.8*t.*t;
   该函数演示了一个MATLAB编程技巧: 计算乘法时应尽量使用 .* 而非 * ,因为前者不仅对参数 t 为标量的 情况可用,也对变量 t 为向量或矩阵的情况可用.                                       
freebody(0, 0, 2)           % 得到 19.6000
freebody(0, 0, [0123])           % 得到 [0 4.9000 19.6000 44.1000]
freebody(0, 0, [01; 23])          % 得到 [0 4.9000; 19.6000 44.1000]

2.加速度

image.png

function [a F] = acc(v2,v1,t2,t1,m)
a = (v2-v1)./(t2-t1);
F = m.*a;
end

3.温度转换

• 编写一个函数,要求输入温度华氏度
• 实现从华氏温度到摄氏温度的转换
• 以度数输出转换后的温度摄氏度
• 脚本应该一直运行,直到输入的待转换样例个数为0或不输入直接按enter时,退出函数

function F2C()
while 1
    F_degree = input('tempreature in Fahrenheit: ', 's');
    F_degree = str2num(F_degree);
    if isempty(F_degree)
        return
    end
    C_degree = (F_degree-32)*5/9;
    disp(['tempreature in Celsius: ' num2str(C_degree)])
end

image.png


以函数句柄形式定义函数:函数指针

我们也可以使用函数句柄的形式定义函数,这更接近数学上的函数定义,其语法如下:
可以直接通过函数句柄调用该方法.
其实就是函数指针

 函数句柄 = @(输入变量) 输出变量

可以直接通过函数句柄调用该方法.

f = @(x) exp(-2*x);
x = 0:0.1:2;
plot(x, f(x));