zl程序教程

您现在的位置是:首页 >  后端

当前栏目

MATLAB基础3.0

2023-09-11 14:22:32 时间

.M文件 函数 控制流程 调试

1.M文件及其使用

1.1.MATLAB工作方式

1. 交互式指令行操作方式

在命令窗口中执行命令,适合于对简单问题的数学演算、结果分析及测试

2. M文件的编辑工作方式

实现一次执行多条MATLAB语句的方式
M文件是由MATLAB语句(命令或函数)构成的ASCII码文本文件,文件以 “.m”为扩展名

1.2. .M文件及其使用

1.2.1.两种形式

1.脚本文件(Script File)

组成: 命令与函数的组合,没有输入、输出参数
适用: 自动执行一些列的命令或函数,避免在命令窗口重复输入
变量: 脚本文件结束后,其运行时所产生的变量仍然保存在workspace中,直到被clear或退出MATLAB

  1. 编译脚本文件:
clear
clc
theta = -pi:0.01:pi;               %-π到π,步长为0.01
rho(1,:) = 2*sin(5*theta).^2;
rho(2,:) = cos(10*theta).^3;
rho(3,:) = sin(theta).^2;
rho(4,:) = 5*cos(3.5*theta).^3; 
for k =1:4                         % 循环控制
    subplot(2,2,k)                 % 图形输出
    polar(theta,rho(k,:))          % 绘制极坐标图
end
  1. 保存脚本文件(自定义名字):

  2. (添加到路径)运行:

  3. 工作区变量

2.函数文件

标志: 第一句以function语句引导的M文件,可输入和返回输出参数
适用: 构造一个新的函数,存储后,可在其他脚本文件或函数文件中调用此函数
组成: 1.第一行(函数声明):function [ nargout1,nargout2,…]=name ( nargin1,nargin2,…)
           %函数名(name)必须与M文件同名
           %可以没有输入与输出参数
           %[ ] 定义函数的输出参数列表 ( ) 定义函数的输入参数列表

       2.H1行(帮助文本)%开始,函数调用方法和功能简介,lookfor查询时显示(可在其他地方适用 help name查看)
           %帮助文本内容1:简要说明( 通常只有一到两行,用来简略说明这个函数的作用,不必要包含如何使用)
           %帮助文本内容2:使用方式和语法(syntax)(比较详细,会有多行,是用来解释如何使用此函数,包括但不限于输入输出)
           %帮助文本内容3:扩展阅读 (一般一个函数文件只要前两个就可以了,但是有时这个函数会跟其他一些函数有一定关系,或者我们有更详细的帮助外部帮助文档,需要在帮助说明里面超链接展示出来)

       3.函数体(函数主体部分):包含所有函数程序代码,是函数的主体部分

       4.注释%开始,可以出现在函数文件的任何地方

       5.end:标志一个函数的结束

  1. 编译函数文件(%Vecop…%That’all部分为帮助文本,非函数必要部分):
function [dp,cp]=vecop(v,w)

%Vecop     Returns the dot product and cross product of two numeric vectors
%
%     dp = Vecop(v,w) the dot-product
%     cp = Vecop(v,w) the the cross product
%     v = [1;2;3] w = [1;2;3]
%     Both of v and w are 3-by-1 numerical vector
%     
%     That'all

dp=sum(v.*w);                 %dot-product
cp=zeros(3,1);                %creat 3-by-1 zeros

%cross-products
cp(1)=v(2)*w(3)-w(2)*v(3);
cp(2)=v(3)*w(1)-w(3)*v(1);
cp(3)=v(1)*w(2)-w(1)*v(2);

end

注意:帮助文档可以使用中文,但此处为了显得专业,就用的英文,嘿嘿,也没有强制的格式,可以自由发挥

  1. 保存(m文件与函数名一致)

  2. 调用

  3. 查看帮助文档

注意: 函数调用可以作为另一个函数调用的输入参数
如下(自定义summing函数,调用sum求和函数作为输入参数,实现求和功能)

1.2.2.局部变量与全局变量

局部变量

在函数文件中定义及使用的变量都是局部变量,只在本函数工作区内有效,函数运行结束后,这些局部变量被释放,不再占内存空间

全局变量

常用于大型编程
global定义全局变量
    %指定全局变量后,该变量能够分开在子函数、主函数中使用
    %使用global在主函数和子函数中分别进行定义即可

function ysw4_4
clc
clear
close all
global a 
a=2;
x=3;
y=ysw(x)


function y=ysw(x)
global a
y=a*(x^2);

1.2.3.函数调用与变量传递

1.命令式调用

函数名 参数列表 %参数之间使用空格隔开
name nargin1 nargin2 …

2.函数式调用

[输出参数列表] = 函数名(输入参数列表) %参数之间使用逗号隔开,可返回多于一个的参数,调用时参数被赋值
[out1,out2,…] = name(in1,in2,…)

3.检查参数个数

nargin:输入参数个数

function y = computetest(a,b)
%计算输入变量的平方和,没有输入,默认两变量为0,一个输入,另一个默认为0
if nargin == 0
    a = 0;
    b = 0;
elseif nargin == 1
    b = 0;
end

y = a^2 + b^2;
end

nargout:输出参数个数

4.可变参数个数

varargin:调用者调用该函数时根据需要来改变输入参数的个数。以元胞数组保存

function acceptVariableNumInputs(varargin)
%接受个数不定的输入项,并显示每个输入项的值
    fprintf('Number of arguments: %d\n',nargin)
    celldisp(varargin)
end

varargout:调用者调用该函数时根据需要来改变输出参数的个数
    function varargout=myfunc(vin1,vin2,…)
    function[vout1vout2…varargout]=myfunc(vin1,vin2,…)

1.2.4.数据的输入与输出

在这里插入图片描述

cell与structure

Name={'Jack','Marry','Peter','Rose','Tom'};
Mark={72,83,56,94,100};
Rank=cell(1,5);
S=struct('Name',Name,'Marks',Mark,'Rank',Rank);

1.数据文件

后缀名说明
.mat二进制文件
.txt
.dat
ascll码数据文件,使用save存储load读入
.bmp
.jpg
.tif
图像文件,使用imread(读入)和imwrite(存储)
.wav声音文件,使用wavread(读入)和wavwrite(存储)
新版MATLAB使用audioread(读入)和audiowrite(存储)

2.数据的输入向导

工具栏’导入数据’

选择需要的文件,完成数据导入

mat 数据文件:导入到工作空间中的变量名与M文件中的变量名及变量类型相同
声音数据文件:导入到工作空间的数据变量包括数据和采样频率两部分

3.数据的存储save

指令说明
save将matlab工作空间中所有变量二进制格式存储(此时默认文件名为matlab .mat)
save dfile将matlab工作空间中所有变量二进制格式存入名为dfile.mat文件
save dfile x变量x二进制形式存入dfile.mat文件
save dfile.dat x -asciix8位ASCII码数据文件形式存入dfile.dat
save dfile.dat x –ascii –doublex16位ASCII码数据文件形式存入dfile.dat
save(‘fname’,‘a’,’-ascii’)aASCII码数据文件形式存入fname定义的文件中

4.数据的导入load

指令说明
load将磁盘文件matlab.mat的内容读入内存
load dfile将磁盘文件dfile.mat的内容读入内存
load dfile.dat –mat将磁盘文件dfile.dat的内容读入内存.这是一个ASCII码文件
S=load(‘fname’)将由fname.mat定义文件名的数据文件调入结构变量S

2.程序结构与流程控制

2.1.流程控制

2.1.1.for

格式一

for 循环变量=m:s:n
    循环体语句
end


m:初值 s:步长(不写时,默认为1) n:终值
当初值=终值时,不管步长为何值,均执行一次循环体

水仙花数
    一个三位整数各位数字的立方和等于该数本身则称该数为水仙花数。输出全部水仙花数

function narcissisticNumber
for m=100:999
m1=fix(m/100);              %求m的百位数字
m2=rem(fix(m/10),10);       %对m除以10取整,然后对10取余数,求m的十位数字
m3=rem(m,10);               %求m的个位数字
if m==m1*m1*m1+m2*m2*m2+m3*m3*m3
	disp(m)
end
end

fix(x)%向0取整
rem(x,y)%求余x/y
mod(x,y)%取模x/y

格式二

for 循环变量=矩阵表达式
    循环体语句
end


执行过程是依次将矩阵的各列元素赋给循环变量,然后执行循环体语句,直至各列元素处理完毕
s=0;
a=[12,13,14;15,16,17;18,19,20;21,22,23]; %三列
for k=a 
s=s+k; %执行三次
end
disp(s); %矩阵的列之和, s是列向量

2.1.2.while

while 表达式(循环条件)
    循环体语句
end


表达式的结果非零,就重复执行

从键盘输入数字,当输入为0时停止输入,求和与平均值
    输入一个非0数,执行一次while循环,当输入为0时,结束while循环,执行if语句

sum=0;                %和
cnt=0;                %输入个数
val=input('Enter a number (end in 0):');
while (val~=0)        %~= 不等于
     sum=sum+val;
     cnt=cnt+1;
     val=input('Enter a number (end in 0):');
end
if (cnt > 0)
    sum
    mean=sum/cnt      %求平均值
end

2.1.3.if

单分支语句

if 条件
    语句体
end


当条件成立时,则执行语句体,否则跳过if语句

双分支语句

if 条件
    语句体1
else
    语句体2
end

计算分段函数的值

x=input('请输入x的值:');
if x<=0
   y= (x+sqrt(pi))/exp(2);
else
   y=log(x+sqrt(1+x*x))/2;
end
y

多分支语句

if 条件1
    语句体1
elseif 条件2
    语句体2

elseif 条件m
    语句体m
else
    语句体n
end

输入大写字母,转换为小写输出;输入小写字母,转换为大写输出;输入其他,不变

function exchC(c)
if c>='A' && c<='Z'     %判断是否为大写
	lower(c)            %转换为小写
elseif c>='a'&& c<='z'  %判断是否为小写
    upper(c)            %转换为大写
elseif c>='0'&& c<='9'  %判断是否为数字
    disp(c)
else
    disp(c)
end
end

2.1.4.switch

switch 表达式
case 对照表1
    语句体1
case 对照表2
    语句体2

otherwise
    语句体n
end


switch 后的表达式的值与case后的表达式相比较,如相同就执行相应的语句

switch 表达式必须为标量字符向量

case 对照表必须为标量字符向量或者标量或字符向量的元胞数组

MATLAB中只完成第一个满足条件的case,不再继续比较,因此不需要break语句

商场优惠
    输入所售商品的价格,求其实际销售价格

price=input('请输入商品价格');
switch fix(price/100) 
   case {0,1}           %价格小于200 %不能用[]替换{}
      rate=0;
   case {2,3,4}         %价格大于等于200但小于500
      rate=3/100;
   case num2cell(5:9)   %价格大于等于500但小于1000
      rate=5/100;
   case num2cell(10:25) %价格大于等于1000但小于2500
      rate=8/100;
   otherwise            %价格大于等于2500
      rate=10/100;
end
price=price*(1-rate)    %输出商品实际销售价格

2.1.5.try-catch

try
    语句1_1 语句1_2 …
catch
    语句2_1 语句2_2 …
end


如果语句1_i在执行过程中出现错误,则将错误信息赋给保留的lasterr变量,并转去执行catch和end间的语句
若try和catch之间的语句没有错误,则不执行catch和end间的语句

A=[1,2,3;4,5,6]; B=[7,8,9;10,11,12];
try
   C=A+B   
   D=A*B               %此语句有错
catch
   E=A.*B
end
lasterr                %显示出错原因

2.2.其它流程控制语句

2.2.1.continue

continue:在for和while循环中,如果遇到continue语句,则跳过本次循环中的剩余语句,继续下次循环

a=3;b=6;
     for i=1:3
            b=b+1
          if i< 2
           continue
          end           %if语句结束
          a=a+2
      end               %for语句结束

2.2.2.break

break:在for循环和while循环中遇到break语句,退出循环,执行下一行语句。在循环嵌套中,break只存在于最内层的循环体中

a=3;b=6;
     for i=1:3
            b=b+1
          if  i > 2
           break
          end           %if语句结束
          a=a+2
      end               %for语句结束

2.2.3.return

return: 用于终止当前的函数,并返回到调用的函数。程序终止控制语句

function nummax(a,b)
%比较两个正数的大小

%当a、b都小于0时,结束函数
if(a<=0|b<=0)
    disp('input error')
    return; 
	a 
elseif a>b
    fprintf('the large number is %f',a)
elseif a<b
    fprintf('the large number is %f',b)
else
    fprintf(' %f equals%f',a,b)
end
end

3.函数类型

3.1.主函数

  1. 结构上与其他函数没有区别
  2. 其他函数均排在其后面
  3. 惯例其与m文件同名
  4. 若不与文件同名,只能用文件名引用该函数

3.2.子函数

  1. 函数文件中可以含有一个或多个子函数
  2. 子函数由 function 语句引导
  3. 主函数必须位于最前面,子函数出现的次序任意
  4. 子函数只能被主函数和位于同一个函数文件中的其它子函数调用
  5. 除了用 global 定义的全局变量外,子函数中的变量都是局部变量,子函数与主函数及其它子函数之间通过输入、输出参数进行数据传递

3.3.私有函数

  1. 其作用是限定某一些函数(private文件夹内)只能被另一些函数使用,其他函数不能使用
  2. private函数是那些放在以private子文件夹下的函数。这些函数被称为private是因为它们只对满足如下条件的函数或脚本可见
    2.1. 调用私有函数的函数和private文件夹处于同一目录
    2.2. 调用私有函数的脚本,它应该被满足上一条件的函数调用

3.4.嵌套函数

  1. 在任意一个函数体内部定义的函数称为其外部函数的嵌套函数
  2. 嵌套函数不能在程序控制语句中定义,即不能在if判断语句、while循环语句中定义。
  3. 嵌套函数跟其它M文件函数一样,包含M文件的基本元素,当嵌套函数结束时必须用end表示结束
    可以进行多重嵌套
function x=nestFun(p1,p2) 
% 嵌套函数实现 x=p1+2*p2
x1=nestFunIn(p2);              %调用嵌套函数
function y=nestFunIn(p3)       %调用嵌套函数
y=2*p3;
end
x=x1+p1;
end

1.调用嵌套函数原则:

function A(x,y)
B(x,y);
D(y);
	function B(x,y)        %函数A(x,y)的嵌套函数,一级嵌套
	C(x);
	D(y);
        function C(x)       %函数B(x,y)的嵌套函数,二级嵌套
        D(x); 
        end
	end

	function D(x)          %函数A(x,y)的嵌套函数,一级嵌套
	…..
	end

end

1.一个函数可以调用自己函数体中的嵌套函数,如A可以调用B和D,但不能调用C
2.同一级的嵌套函数也可以相互调用,如B和D
3.可以调用比自己级别高的嵌套函数,如C可以调用D

2.嵌套函数变量调用规则:

1.被主函数赋值的变量可以被主函数中任意一个嵌套函数访问
2.一个嵌套函数的变量值可以被任何包含它的函数访问

3.嵌套函数中使用函数句柄

function h=getcubehandle
h=@findcube;

	function cube=findcube(x) %嵌套函数
	cube=x.^3;
	end
end

3.4.重载函数

  1. 函数重载允许多个函数使用相同的函数名不同的输入参数类型
  2. 在函数调用时,系统根据输入参数的情况自动选择相应的函数执行
  3. 函数重载为程序编写和用户调用都提供了很大的方便

4.程序调试

程序调试的常用方法:

  1. 去掉分号,此语句运行的中间结果在命令窗口中显示
  2. 加入显示感兴趣变量语句,如disp(变量x)
  3. keyboard命令放在函数中,当函数运行keyboard命令,可给键盘暂时控制权
  4. 函数第一行function语句前加上%,变为脚本文件,然后执行此脚本文件。发生错误时,可以查看Matlab工作空间
  5. MATLAB自带代码编辑调试器