| 
 | 
 
11.1MATLAB编程概述 
 
MATLAB是一种解释性语言,本身不能完成任何事情,只是对用户的程序进行解释执行。MATLAB语言是采用C语言编写的,因此语法和C语言非常相似。对于熟悉C语言的用户,学习MATLAB编程会非常容易。MATLAB编写的程序文件有两种:脚本M文件和函数M文件。 
在MATLAB中,M文件有两种类型:函数(Functions)和脚本(Scripts),都是以.m作为文件的扩展名。M文件为普通的ASCII文本文件,可以采用文字编辑和处理软件来建立。脚本是一系列命令、语句的简单组合。 
文件名必须是字母,数字,下划线。 
11.1.2脚本M文件 
 
脚本文件中的变量都为全局变量,程序运行后,这些变量保存在MATLAB的基本工作空间内,一般采用函数clear清楚这些变量。为了避免因为变量名相同引起冲突,一般在脚本文件的开始,都采用函数clear all,清楚所有基本空间中的变量。 
在command window输入,help + 脚本文件名,得到该脚本文件前几行的注释 
which + 脚本文件名,可以对脚本文件进行定位 
程序运行后,通过输入whos,可以查看工作空间的变量 
clear all 清楚所有的变量 
11.1.3函数M文件 
 
函数M文件在执行的过程中,所产生的变量一般都是局部变量,存放在函数自身的函数工作空间中,不会和基本工作空间中的变量产生冲突。对用户来说,函数M文件就像一个黑匣子,只有输入和输出。采用函数M文件,非常易于实现程序的模块化,可以实现程序的分工合作、共同开发,适合大型程序开发。 
在MATLAB的命令行窗口输入:edit std.m, 利用MATLAB文本编辑器打开函数M文件。 
函数M文件注释的第一行非常重要,对函数进行查找(look for)时,会自动搜索注释的第一行。 
help + 函数文件名,会显示函数的注释部分 
在命令行窗口:type + 函数文件名,则会在命令行窗口打印出函数的源程序。 
对matlab内部的函数不能查看它的源代码,如max,min函数。 
11.1.4函数的参数传递 
 
在MATLAB中,函数的参数传递是值传递,将变量或常量的值传递给函数的形式参数指定的变量,函数的计算在函数空间中进行,计算结束后,函数空间的变量被清除,函数的返回值返回到MATLAB的基本工作空间中。 
在MATLAB中,函数nargin的值为输入参数的个数,函数nargout的值为输出参数的个数。 
11.2 流程控制 
 
MATLAB编程的基本结构包括:顺序结构、分支结构和循环结构,此外还有一些其它的控制语句。本节首先介绍MATLAB中的变量,然后将详细介绍三种基本的程序结构,最后介绍了交互式输入。 
11.2.1 变量 
 
在MATLAB中,变量的类型包括:局部变量、全局变量和永久变量。MATLAB为每个变量分配一块内存空间。变量和工作空间紧密联系。 
 
- 局部变量
 
 - 全局变量。全局变量采用global进行声明,格式为:global 变量1 变量2。 中间采用空格进行分割。
 
 - 永久变量。 永久变量只能在函数M文件中进行定义,格式为:persistent 变量1 变量2。中间采用空格进行分割。
 
  11.2.2 顺序结构 
 
顺序结构是最简单的程序结构,用户在编写好程序后,按照从上到下、从左到右的顺序执行程序中的语句。由于没有控制语句,结构比较单一,但是这种程序比较容易编写。 
clear all; 
t = 0 : pi/20 : 2*pi; 
x = sin(t); 
y = cos(t); 
figure; 
plot(t,x,':r'); 
hold on 
plot(t,y); 
legend('sin(t)','cos(t)'); 
  
11.2.3 分支结构 
 
分支结构需要进行判断,只有满足一定的条件才执行某些语句。在MATLAB中,分支结构有两类:If语句和switch语句。下面分别进行介绍。 
 
- if...end语句
 
 -  if...else...end语句
 
 -  if...elseif...else...end语句
 
 -  switch...case...end语句
 
  clear all; 
a = 12345; 
if rem(a,2) == 0 
    disp('偶数'); 
else 
    disp('奇数'); 
endif...elseif...else...end语句,举例 
clear all; 
x = 87; 
if x >= 90 
    disp('优秀'); 
elseif x >= 80 
    disp('良好'); 
elseif x >= 70 
    disp('中等'); 
elseif x >= 60 
    disp('及格'); 
else 
    disp('不及格'); 
endswitch...case...end语句,举例 
clear all; 
x = 5; 
switch x 
    case 1 
        disp('x=1'); 
    case 2 
        disp('x=2'); 
    case {3, 4, 5} 
        disp('x=3,4,5'); 
    otherwise 
        disp('x'); 
end11.2.4 循环结构 
 
循环结构能够重复执行某一段相同的语句。MATLAB中,提供了两种循环语句,分别为for循环和while循环。如果已知循环次数,通常用for循环语句;如果未知循环次数,但有循环条件,则用while循环语句。 
 
- for循环语句
 
 -  while循环语句
 
 - break语句和continue语句
 
  clear all 
for i = 1:1:10 
    x(i) = i^10; 
end 
% 或者 
for i = [1, 2, 3, 4, 5, 6,7,8, 9,10] 
    y(i) = i^10; 
end 
% 或者用向量的形式,执行效率高 
i = 1: 10; 
z = i.^ 10for循环进行了嵌套 
clear all; 
x = zeros(5,5); 
for i = 1 : 5; 
    for j = 1 : 5 
        x(i,j) = i^j; 
    end 
end 
xwhile循环的例子 
clear all; 
x = zeros(1,10); 
i = 1; 
while i <= length(x) 
    x(i) = 1/i; 
    i = i + 1; 
end 
xwhile循环和其它while循环,for循环可以嵌套 
break语句的例子 
clear all; 
x = magic(6) 
for i = 1: size(x,1) 
    for j = 1: size(x,2) 
        if x(i,j) == 5 
            break; % break语句终止循环,退出一层循环 
        else 
            x(i,j) = 0; 
        end 
    end 
end 
xcontinue语句的例子 
clear all; 
x = magic(6) 
for i = 1: size(x,1) 
    if rem(i,2) == 0 
        continue; 
    end 
    x(i,:) = 0; 
end 
x 
% 运行结果:奇数行变为0,偶数行不变11.2.5 try...catch语句 
 
在程序设计时,如果不能确定某段程序代码是否会出错,可以采用try...catch语句。在MATLAB中,使用try...catch语句能够捕获和处理错误,其调用格式为: 
try 
程序代码1 
catch 
程序代码2 
end如果执行程序代码1,没有错误,就不再执行程序代码2,直接执行后面的程序。如果在执行程序代码1的时候出现错误,则会立即转到执行程序代码2,程序代码2执行结束后会执行end后的语句。 
例子: 
clear all; 
a = [1, 2, 3; 2, 3, 4] 
b = [3, 4 ,5; 1, 6, 7] 
try 
    c = a * b; 
    disp(&#39;c=a*b&#39;); 
catch 
    disp(lasterr); 
end11.2.6 人机交互函数 
在MATLAB中提供了一些人机交互的函数,用户可以从键盘输入数据或字符串,可以暂停程序的运行等。下面分别进行介绍。 
 
- 函数input()
 
 - 函数keyboard
 
 - 函数pause
 
 - 函数echo
 
 - 函数return
 
  例子: 
clear all; 
r1 = input(&#39;Do you like apple? Y/N:&#39;, &#39;s&#39;); %提示用户从键盘输入 
while isempty(r1) 
    r1 = input(&#39;Do you like apple? Y/N:&#39;,&#39;s&#39;); 
end 
disp(r1); 
disp(&#39;input matrix, for example: eye(5)&#39;); 
r2 = input(&#39;&#39;, &#39;s&#39;);  
f = eval(r2) % 对输入的语句进行执行例子:keyboard函数可以对程序进行调试,可以在程序运行中修改变量的值。 
clear all; 
a = [1 2 3; 2 3 4] 
b = [4 5 3; 7 8 9] 
keyboard     %要终止调试模式并继续执行,请使用dbcont命令 
c = a + bpause可以暂时终止程序的运行,等待用户按任意键后继续执行后面的程序。另外也可以对暂停的时间进行设置。 
clear all; 
t = 0: pi/20 : 2*pi; 
x = sin(t); 
figure; 
plot(t,x) 
xlabel(&#39;t&#39;); 
ylabel(&#39;x&#39;); 
hold on 
for i = 1:7 
    pause; 
    plot(t,sin(t + i/5)); 
    hold on; 
end 
  
函数echo,在命令行显示程序执行的语句。 
clear all; 
a = [ 1 2 3; 2 3 4]; 
b = [ 1 2 3; 7 8 9]; 
echo on; 
c = a +  b 
d = a - b 
echo off; 
e = a.* b函数return可以终止程序的运行,也可以当函数的返回值。 
11.3  函数类型 
 
在MATLAB中,函数M文件可以分为:主函数、子函数、嵌套函数、私有函数、重载函数和匿名函数。下面分别进行介绍。 
11.3.1 主函数 
 
每个函数M文件中第一行定义的函数是主函数,一个函数M文件只有一个主函数。主函数的名字通常和函数的名字相同。除了主函数,在函数M文件中,还有嵌套函数或子函数。主函数对嵌套函数或子函数进行调用。 
11.3.2 子函数 
 
在主函数之后编写的函数为子函数。在函数M文件中,只有一个主函数,但可以有多个子函数。所有的子函数也采用function进行定义。如果主函数中包含子函数,则每个采用function定义的函数必须采用end结束。各个子函数的先后顺序和调用的先后顺序无关。 
在主函数进行函数调用时,首先检查该函数文件中的子函数,如果有同名的子函数,则调用该子函数。因此,可以编写同名的子函数实现函数重载。子函数只能被同一文件的主函数或其它子函数调用。 
function [a, b] = mymain(x,y) 
% 主函数 
a = mysub1(x,y); 
b = mysub2(x,y); 
end 
 
function z = mysub1(x,y) 
% 子函数1 
z = x - y; 
end 
 
function z = mysub2(x,y) 
% 子函数2 
z = x + y; 
end 
 
%%% 在命令行窗口调用 
clear all; 
[a,b] = mymain(3,4) 
[x,y] = mymain(5,6) 
help mymain 
help mymain>mysub1  % 显示子函数的帮助信息 
help mymain>mysub211.3.3 嵌套函数 
 
在函数的内部,还可以定义一个或多个函数,称为函数的嵌套。在函数内部定义的函数称为嵌套函数。MATLAB中,可以进行多层嵌套,一个函数的内部可以嵌套多个函数,这些嵌套函数的内部又可以嵌套其它函数。 
function a = A(x,y) 
    % B(x,y); 
    % D(x,y); 
    a = 1 
    function b = B(x,y) 
        C(x); 
        D(y); 
        b = 2 
        function c = C(x) 
            B(x); 
            D(x); 
            c = 3 
        end 
    end 
    function d = D(x,y) 
        B(x,y); 
        E(y); 
        d = 4 
        function e = E(y) 
            B(x); 
            D(x); 
            e = 5 
        end 
    end 
end这里函数可以调用函数B和函数D,不能调用函数C和函数D。函数B可以调用函数C和和函数D。函数D可以调用函数B和函数E。函数C可以调用函数B和函数D。函数E可以调用函数B和函数D。函数C和函数E不能互相调用。 
11.3.4 私有函数 
私有函数要保存在该目录的private文件夹下,具有有限的访问权限。私有函数的编写和普通函数的编写没有什么区别,可以是一个主函数和多个子函数,以及嵌套函数等。 
函数M文件可以直接调用私有函数。该函数M文件所在的目录下直接有一个private目录,私有函数就保存在该目录下。私有函数只能被其父目录内的脚本或函数调用。 
脚本M文件不能直接调用私有函数,必须通过调用一个在私有函数的父目录中的函数来间接调用私有函数。 
对于私有函数,也可以通过help获取该函数的帮助信息。例如要获取私有函数myfun()的帮助信息,需要通过如下的命令:help myfun。 
function z = myprivatefun(x,y) 
% 这是私有函数myprivatefun() 
 
disp(&#39;这是私有函数&#39;); 
if nargin == 2 
    z = x + y; 
elseif nargin == 1 
    z = x; 
else  
    warning(&#39;没有输入参数!&#39;); 
    return; 
end查询私有函数myprivatefun()的帮助信息 
help myprivatefun调用私有函数 
clear all 
myprivatefun(3,5) 
输出结果 811.3.5 重载函数 
 
在MATLAB中很多函数都有重载函数,重载函数具有相同的函数名,但是参数类型或个数不同。当用户在调用函数时,MATLAB会根据实际的参数类型和个数来选择其中的一个。在MATLAB中,重载函数保存在不同的目录下,通常目录的名字以符号@开头,然后跟一个代表MATLAB数据类型的字符。例如@int8目录下存放的重载函数的输入参数类型为int8,即8位有符号整数。 
例如,查询max 
help max 
  
function m = max (x,y,x,w,varargin) 
% 新建的重载函数 max() 
% 该函数求四个标量的最大值 
% author,copyright 
if nargin ~= 4 
    return; 
end 
temp = x; 
if x<y 
    temp = y; 
end 
if temp < z 
    temp = z; 
end 
if temp < w 
    temp = w; 
end  
m = temp;调用 
clear all; 
help int8/max.m 
a = int8(1); 
b = int8(2); 
c = int8(4); 
d = int8(8); 
max(a,b,c,d) 
输出结果 811.3.6 匿名函数 
匿名函数的定义格式如下: 
fhandle=@(arglist)expr 
其中arglist是匿名函数的输入参数列表,采用逗号分割。expr为是具体的函数表达式,执行该匿名函数要完成的功能。@是MATLAB的操作符,用来建立函数句柄,可以采用函数句柄来调用该函数。 
clear all; 
f = @(x) 2*x^2 + 3*x + 4   % 一个输入参数 
a1 = f(2) 
a2 = f(3) 
a3 = f(4)再看一个例子,有三个输入参数 
clear all; 
f = @(x,a,b) a*x.^2 + x.*b  % 三个输入参数 
f(1,2,3) 
f(2,2,3) 
f(1:3,2,3)再看一个例子, 没有输入参数 
clear all; 
f1 = @()disp(&#39;This is an anonymous function&#39;)  % 没有输入参数,但是圆括号不能省略 
f1()  % 调用匿名函数f1 
functions(f1)  % 获取f1的一些信息再看一个例子, 有多个输出参数 
clear all; 
a = [1,2,3; 2,3,4] 
f1 = @(x)size(x) 
f1(a) 
[b,c] = f1(a) % 有两个输出参数例子,建立多重匿名函数 
clear all; 
f1 = @(a,b,c)@(x)a*x.^2 + x.*b + c 
f1_info = functions(f1) 
f2 = f1(1,2,3) 
f2_info = functions(f2) 
f3 = f2(3)匿名函数的数组 
clear all; 
F1 = {@(x) 3*x + 4, @(y) 8*y + 9, @(a) 6*a + 2}  %用大括号括起来 
F2 = {@(x) 3*x + 4; @(a) 5*a + 10} 
F1{1}(2) 
F2{2,1}(3)匿名函数的应用 
clear all; 
f1 = @(x)fzero(@(y)sin(x)*cos(y) + x*exp(y) - 3*x^2*y^2,1)  
% 建立了由隐函数sin(x)*cos(y) + x*exp(y) - 3*x^2*y^2=0 确定的函数y=f(x) 
f1(3) % 求x=3时函数的值 
f1(5) 
  
 
运行结果 
 
再看一个例子,采用quad在0-1上积分 
clear all; 
f1 = @(a)quad(@(x)3*x.^2 + a*x + 5,0,1) %采用quad在0-1上积分,a取不同值时,积分是多少 
f1(1) 
f1(3)再看一个例子 
clear all; 
close all; 
figure; 
ezmesh(@(x,y)3*x^2 + 4*y^2 - sin(x)*sin(y),[-1,1],[-1,1]); %绘制三维网格图11.3.7 函数句柄 
 
创建函数句柄使用@或者srt2func命令。可以使用函数句柄来调用其它函数,也可以将函数句柄存储在数据结构中,方便以后使用。当使用函数句柄调用该函数时,MATLAB会立刻执行,不进行文件搜索。当多次调用一个函数文件时,可以节省大量的搜索时间,从而提高函数的执行效率。 
clear all; 
A = {@sin,@cos,@(x)x.^2-2} % 多个函数句柄,第三个是采用匿名函数建立的函数句柄 
figure; 
t = -pi:pi/20:pi; 
for i = 1:length(A) 
    plot(t,A{i}(t)); 
    hold on; 
end 
xlabel(&#39;x&#39;); 
ylabel(&#39;y&#39;); 
  
再看一个例子, 建立了元素值为函数句柄的结构体变量A 
clear all; % 建立了元素值为函数句柄的结构体变量A 
A.x = @sin; 
A.y = @cos; 
A.z = @(x)sin(x).*cos(x); 
t = 0 : pi/10 : 4*pi; 
figure; 
plot3(A.x(t), A.y(t), A.z(t));  % 绘制了一个三维的曲线 
grid on; 
  
11.4 P码文件和ASV文件 
 
在MATLAB中,可以将M文件转换为P码文件。P码文件可以直接执行,速度比M文件要快。此外,在MATLAB的编程过程中,还会产生临时保存的ASV文件。下面分别进行详细介绍。 
11.4.1 P码文件 
 
P码文件是对应M文件的源代码不可见,但是可以执行的版本。P码文件的后缀为.p,采用函数pcode()生成脚本M文件或函数M文件的P码文件。第一次执行M文件时,MATLAB需要将其解析(parse)一次(第一次执行后的已解析内容会放入内存作为第二次执行时使用,即第二次执行时无需再解析),这增加了程序的执行时间。 
产生P码文件之后,如果再调用M文件时,便会直接执行其P码文件。MATLAB的解析速度非常快,一般不用产生P码文件。只有当一些程序要调用到非常多的M文件时,如GUI应用程序,才会作预解析,以增加以后的调用速度。 
clear all; 
X = [1 2 3; 3 4 5] 
Y = [4 5 6; 7 8 9] 
A = X - Y 
  
11.4.2 ASV文件 
 
在该目录内有很多的.asv文件。可以采用dir进行查询,也可以采用ls进行查询。可以用记事本打开看一下,为正在编写的MATLAB源程序自动保存。如果matlab正常关闭的话,删除这些.asv文件没有任何影响。 
在M文本编辑器中,单击菜单File|Preferences..., 会弹出一个窗口,选择Editor/debugger下的Autosave, 可以修改asv文件的设置,可以选择是否自动保存。如果选择自动保存,几分钟后进行自动保存,保存的临时文件的后缀是什么等等。 
11.5 本章小结 
 
本章详细的介绍了MATLAB的编程,包括脚本M文件和函数M文件。详细的介绍了MATLAB编程时,程序的流程,包括顺序结构、分支结构和循环结构。然后重点介绍了MATLAB的函数类型和函数编程,以及函数句柄等。最后介绍了P码文件、ASV文件和MAT文件。 
11.11 MATLAB基本编程(Av43064815,P11)_哔哩哔哩_bilibili  |   
 
 
 
 |