第2章 MATLAB程序设计 编者
Outline 2.1 基本程序元素 2.2 数据类型 2.3 程序控制流 2.4 M文件概述 2.5 MATLAB编程进阶
2.1 基本程序元素 1 变量与常量 变量是任何程序设计语言的基本元素之一,它是指其数值在数据处理的过程中可能会发生变化的一些数据量名称。而常量则是指在计算过程中数值不发生变化的量。 MATLAB语言的变量具有如下特点: 不要求对所使用的变量进行事先声明,也不需要指定变量类型,MATLAB会自动根据所赋予变量的值或对变量所进行的操作来确定变量的类型; 在赋值过程中,如果变量已经存在,MATLAB会用新值代替旧值,并以新的变量类型代替旧的变量类型。 变量的命名应遵循如下原则: 变量名区分大小写; 变量名长度不超过 个, 与硬件有关,由函数namelengthmax返回; 变量名必须以字母开头,可包含字母(大小写)、数字和下划线; 关键字不能作为变量名,尽量避免使用函数名作为变量名。 2 关键字 MATLAB中的关键字共有20个:break、case、catch、classdef、continue、else、elseif、end、for、function、global、if、otherwise、parfor、persistent、return、spmd、switch、try、while。
3 运算符 算术运算符 算术运算符分为两类:矩阵运算和数组运算。矩阵运算是按线性代数的规则进行运算,而数组运算是数组对应元素间的运算。表1列出了常用的算术运算符。 表1 常用的算术运算符
2.关系运算符 系运算是用来判断两个操作数关系的运算,参与关系运算的操作数可以使用各种数据类型的变量或者常数,运算的结果是逻辑类型的数据。标量也可以和矩阵或者数组进行比较,比较的时候先进行标量扩展,返回的结果是和数组同维的逻辑类型数组。如果进行比较的是两个数组,则数组必须是同维的,且每一维的尺寸也必须一致。MATLAB中的关系运算符和C语言的关系运算基本一致,主要有六种,见表2。 表2 关系运算符 3. 逻辑运算符 MATLAB提供了两种类型的逻辑运算:元素运算和短路运算,如表3所示。 表3 逻辑运算符
在包含前面介绍的运算符的表达式中,运算顺序按优先级进行。优先级高的先执行,优先级低的后执行。运算符按优先级从高到低排列见表4。 4.运算符优先级 在包含前面介绍的运算符的表达式中,运算顺序按优先级进行。优先级高的先执行,优先级低的后执行。运算符按优先级从高到低排列见表4。 表4 运算符优先级
2.2 数据类型 MATLAB的早期版本只有非常简单的二维数组和字符类型的数据,目前的MATLAB版本中不仅有多达十几种的基本数据类型,在不同的专业工具箱中还有特殊的数据类型,并且MATLAB还支持面向对象的编程技术,支持用户自定义的数据类型。 MATLAB支持的基本数据类型见图所示。 图 MATLAB的数据类型
1.数值型数据 2.字符串 3.元胞数组 整型数据 数值型数据包括无符号和带符号整数、单精度和双精度浮点数。 整型数据 数值型数据包括无符号和带符号整数、单精度和双精度浮点数。 浮点型数据 浮点型数据包括单精度(single)和双精度(double)两种格式,默认是double格式。 复数 MATLAB中常用的构造复数的方法主要有两种:直接生成和用函数complex生成。 2.字符串 字符串的定义 字符串的操作 3.元胞数组 元胞数组示意图 元胞数组的创建 用户通常可以使用两种方法创建元胞数组:第一个办法是用赋值语句直接定义;第二个办法是先由cell函数预先分配存储空间,然后对元胞的每个元素逐一赋值。 元胞数组的操作 用户可以采用“()”和“{}”两种方式来访问元胞数组中的元素,两种方法返回的结果是不同的,以元胞数组C为例,C(m,n)返回的是元胞数组C在(m,n)位置上的元胞,而C{m,n}返回的是元胞数组C在(m,n)位置上的元胞中的数据。
结构数组的创建 使用点号(.)运算符创建 和 利用struct函数创建结构数组 4.结构数组 结构数组是MATLAB中的一种重要的数据类型。同元胞数组类似,结构数组也可以存放不同类型的数据,但结构数组的内容更加丰富、应用更加广泛,很多复杂的问题是用结构数组表示时则显得简单方便。图所示是一个简单的结构体的基本组成。 结构数组的创建 使用点号(.)运算符创建 和 利用struct函数创建结构数组 结构数组的操作 由于结构数组比较特殊,如果用户希望在其他应用程序或者模块中使用结构数组,则需要访问结构数组中的数据,访问结构数组中的字段由点运算符(.)实现。 5.函数句柄 创建函数句柄需要用到操作符@,其一般语法格式为:fhandle=@functionname 6.不同数据类型之间的转换 图 数据类型间的转换关系
2.3 程序控制流 1.顺序结构 顺序结构是指按照程序中语句排列顺序一次执行,直到程序的最后一个语句。 程序的输入 程序的暂停 程序的输出 2.3 程序控制流 1.顺序结构 顺序结构是指按照程序中语句排列顺序一次执行,直到程序的最后一个语句。 程序的输入 从键盘上输入数据,可以使用input函数,该函数的调用格式为: 程序的暂停 当程序运行时,为了查看程序的中间结果或者观看输出的图形,有时需要暂停程序的执行,这可以使用pause函数,该函数的调用格式为: 程序的输出 MATLAB提供的命令窗口输出函数主要是disp和fprintf,disp函数的调用格式为: 程序的终止 程序代码一般按流程执行完毕后正常退出,但当遇到某些特殊情况,程序需要立即退出时,可以用return函数提前终止程序运行。 程序的报错和警告 MATLAB中,编写程序时经常需要给出一些警告或错误信息,为此,MATLAB提供了函数warning和error来实现这一功能,这两个函数的调用格式基本一致,常见的调用格式为:
2.选择结构 选择结构是根据给定的条件成立或不成立,分别执行不同的语句。 2.选择结构 选择结构是根据给定的条件成立或不成立,分别执行不同的语句。 MATLAB用于实现选择结构的语句有if语句和switch语句。 if语句 if语句根据逻辑表达式的值选择执行一组语句,主要有三种使用形式:单分支if语句、双分支if语句和多分支if语句。 MATLAB中,单分支if语句的使用形式如下: 当条件成立时,则执行语句组,执行完之后继续执行if语句的后继语句,若某条件不成立,则直接执行if语句的后继语句,其执行过程如图1所示。 图1 单分支if语句执行流程
当条件成立时,执行语句组1,否则执行语句组2,语句组1或语句组2执行完后再执行if语句的后继语句,其执行过程如图2所示。
多分支if语句是最常用的一种条件语句,其一般使用形式如下:
switch语句根据表达式的取值不同,分别执行不同的语句,其语句格式为:
3.循环结构 MATLAB用于循环结构的语句有for语句、while语句,与循环结构相关的语句还有continue语句和break语句。 其中,V是一个矩阵,循环变量每次从矩阵V中取一列,执行一次循环体语句,如此下去,直至执行完V矩阵中的所有列。图2-2是for语句的执行流程。 图2-2 for语句执行流程
其中,条件为真时,执行循环体语句。while语句的执行过程如图2-3所示。 break语句 MATLAB中,break语句可以使包含break语句的最内层for或while循环强制终止,立即跳出该结构,并执行end后的语句。break语句一般和if语句结合使用。 continue语句 MATLAB中,continue语句用于结束本次for或while循环,与break语句不同的是,continue语句只结束本次循环而继续进行下次循环。
4.试探结构 试探结构是MATLAB独有的一种语句结构,它主要用来对异常情况进行处理,其一般语句格式为: 在执行程序时,该语句结构首先试探性地执行语句段1,如果语句段1出现错误时,控制语句catch就会捕获它,并执行相应的语句段2。 上述程序代码中,在try语句段首先提示输入一个索引值,若索引值满足要求,则使用disp函数输出相应的内容,否则输出相应的违法信息,并将错误信息赋给变量A。上述程序的两次运行结果如下:
2.4 M文件概述 1.脚本文件 “脚本”本身反映这样一个事实:MATLAB只是按文件所写的指令执行。这种文件的构成比较简单,其主要特点如下: 它只是一串按用户意图排列而成的(包括控制流指令在内的)MATLAB指令集合; 脚本文件运行后所产生的所有变量都驻留在MATLAB基本工作空间中,只要用户不适用clear。 2.函数文件 从外界只看到传给它的输入量和送出来的计算结果,而内部运作是藏而不见的。相对于脚本文件,函数文件的主要特点如下: 从形式上看,函数文件的第一行总是以function引导的“函数声明行”; 从运行上看,每当函数文件运行时,MATLAB就会专门为它开辟一个临时工作空间,该空间称为函数工作空间。 3.脚本文件与函数文件的比较 函数文件与脚本文件的主要区别在于:函数文件一般都要带输入输出宗量;对于程序的调试工作而言,脚本文件要比函数文件方便些。
2.5 MATLAB编程进阶 1 函数基本类型 MATLAB中的函数可以分为:M文件主函数、子函数、匿名函数、嵌套函数、私有函数和重载函数。 1 函数基本类型 MATLAB中的函数可以分为:M文件主函数、子函数、匿名函数、嵌套函数、私有函数和重载函数。 M文件主函数 每一个函数M文件第一行定义的函数就是M文件主函数,一个M文件只能包含一个主函数,并通常习惯上将M文件名和M文件主函数名设为一致。 M文件主函数的说法是针对其内部嵌套函数和子函数而言的。一个M文件中除了一个主函数外,还可以编写多个嵌套函数或子函数,以便在主函数功能实现中进行调用。 子函数 一个M文件只能包含一个主函数,但一个M文件中可以包含多个函数,那些编写在主函数后的函数都称为子函数。所有子函数只能被其所在M文件中的主函数或其他子函数调用。所有子函数都有自己独立的函数声明、帮助和注释等结构,各个子函数的前后顺序没有任何限制。 M文件内部发生函数调用时,遵循函数调用的优先原则。函数调用的优先级从高到低排列如下:子函数私有函数类构造函数重载函数当前目录中的同名函数路径中其他目录中的函数。 查询子函数的帮助信息也可以通过help命令显示,但使用格式稍有差别。如果myfun.m文件中含有名为myfun的主函数和名为mysubfun的子函数,那么可以通过语句help myfun>mysubfun来获取子函数mysubfun的帮助信息。 匿名函数 匿名函数是自MATLAB 7.0版起给出的一种全新的函数描述形式,其一般使用格式为:
嵌套函数 在一个函数内部,可以定义一个或多个函数,这种定义在其他函数内部的函数就被称为嵌套函数。一个函数内部可以嵌套多个函数,这些嵌套函数内部又可以继续嵌套其他函数。 嵌套函数的书写语法格式如下: 私有函数 私有函数是具有限制性访问权限的函数,它们对应的M文件需要保存在名为private的文件夹下,这些私有函数代码编写上和普通的函数没有什么区别,但私有函数只能被private目录的直接父目录下的函数调用。因此,用户可以开发自己的函数库,函数的名称可以与系统标准M函数库名称相同,而不必担心在函数调用时发生冲突,因为 MATLAB首先查找私有函数,再查找标准函数。 同样的,我们也可以通过help命令获取私有函数的帮助信息,但需要声明其私有特点,例如要获取私有函数myprifun.m的帮助信息,可以使用语句help private/myprifun。 重载函数 MATLAB中重载函数通常放置在不同的文件夹下,通常文件夹名称以符号@开头,然后跟一个代表MATLAB数据类型的字符,如@double目录下的重载函数的输入参数应该是双精度浮点型,而@int32目录下的重载函数的输入参数应该是32位整型。
2 串演算函数 利用字符串可以构成函数,可以在运行中改变所执行的命令,可以被泛函命令调用,实现比较复杂的运算。如:eval函数、内联函数、feval函数。 eval函数 函数eval可以用来执行用字符串表示的表达式,该函数的调用格式如下: 内联函数 内联函数(Inline function)是MATLAB提供的一个对象(Object)。它的性状表现和函数文件一样,而内联函数的创建则比较容易。内联函数由inline函数创建,该函数的调用格式如下: feval函数 MATLAB提供的feval函数是用来执行函数操作的函数,故有“函数的函数”之称,其一般调用格式为:
3 变量的传递与检测 MATLAB中,提供了多种函数来实现变量检测、传递,同时也提供了“变长度”输入输出变量。灵活使用这些命令可以完成多种复杂的功能。 输入输出变量检测 在MATLAB中,提供了多个变量检测命令,它们用于实现判断输入和输出变量的个数的功能,见表1。 表1 输入输出变量检测命令 “变长度”输入输出变量 MATLAB中提供了一些函数具有接受“任意多输入”,返回“任意多输出”的能力,同时,MATLAB也为用户自行编写“变长度”变量函数提供了两个函数:varargin和varargout,它们是一个元胞数组,必须处于输入或输出参数列表中的最后一个位置。varargin的工作机理是当函数文件被调用时,函数输入变量的分配规则是:首先,输入变量依先后次序逐个对应分配给函数文件输入变量列表中那些被明确定义的“普通”输入变量;然后,把剩余的输入变量依次逐个分配到varargin元胞数组中。因此,varargin元胞数组的长度取决于分配到的输入变量数。varargout的工作机理、规则与varargin相同,差别仅在于varargout承载的是输出变量和输出变量之间的配置关系。
谢谢大家!