MATLAB被称为第四代编程语言,语言简洁易学、可读性强。下面简要介绍MATLAB语言的基础知识。
MATLAB共有十几种基本数据类型,主要是整型、浮点型、字符型、逻辑型、结构数组、元胞数组和函数句柄等,如图2-1所示。
图2-1 MATLAB数据类型
1.整型
整型从字节数、有符号还是无符号两个方面可以分为int8、uint8、int16、uint16、int32、uint32、int64和uint64等几种细分的类型。int8表示一个字节长度的有符号整数,用intmax('int8')和intmin('int8')可分别返回int8类型的整数所能表示的最大值127和最小值-128。整型数相除,结果四舍五入为新的整型数,例如:
2.浮点型
浮点数包括单精度浮点数(single)和双精度浮点数(double)。realmax('double')和realmax('single')分别返回两者能表示的最大值。
class函数返回输入参数的数据类型,可以看出,常数数字默认为double型浮点数。
3.字符型
MATLAB中用一对单引号分隔字符,字符串存储为字符数组。如string='I Love Matlab',string即为1行13列的字符向量。多个字符串可以形成矩阵,但每个字符串长度必须相等,如a=['a';'abc']的形式是不允许的。解决方法是人为加入空格,使矩阵的各行对齐,即a=['a ','abc'],或使用char函数:a=char('a','abc')。这两种形式是等效的。
一种更灵活的方法是使用元胞数组。元胞数组中的各元素不限数据类型、不限大小。例如,a={'a','abc'},用a{1}、a{2}的方式引用元胞数组中的各字符串。元胞数组的效率相对比较低,这是它的缺点。
字符串操作中常用的函数如表2-1所示。
表2-1 字符串操作常用函数
续表
4.逻辑型
逻辑型(logical)变量只能取true(1)或false(0),在矩阵操作中逻辑型变量非常有用。例如:
5.结构数组
结构数组是包含一组记录的数据类型,每一条记录都拥有若干字段。结构中的字段值可以是任意数据类型和任意维度的变量,也可以是另一个结构数组。结构数组的创建有两种方法,一种是直接创建,另一种是利用struct函数创建。例如:
对结构中字段的访问使用操作符“.”,还可以使用动态字段,编写函数对字段进行统一操作。动态字段允许字段名不是常量,因此可以用同一变量作为字段,通过不断修改变量的值对不同字段进行处理。例如:
结构数组可以有多个记录,对多个不同记录中同一字段的值,可以用运算符“[]”单独抽取出来形成新的数值数组,方便计算。例如:
与结构数组相关的函数如表2-2所示。
表2-2 结构数组相关函数
6.元胞数组
元胞数组是MATLAB的特殊数据类型。MATLAB的基础数据类型是矩阵,同一矩阵的元素数据类型相同,元胞数组则没有这个限制。元胞数组的内存空间是动态分配的,这一点决定了它更优秀的灵活性和相对较低的运行效率。元胞数组的元素可以是任意数据类型、任意维度的常数或常量。与矩阵不同,元胞数组引用元素时使用“{}”操作符,此时得到的数据的类型是元素本身的类型,而使用“()”操作符引用元素时,得到的是一个小一些的元胞数组。
元胞数组可以直接创建,也可以使用cell函数创建。
与元胞数组操作相关的函数如表2-3所示。
表2-3 元胞数组相关函数
7.函数句柄
函数句柄的直接声明要用到“@”符号,方法是:变量名=@函数名。此函数可以是预定义函数,也可以是用户自定义的函数,声明函数句柄以后,就可以像使用函数名一样使用该函数句柄了,如h=@sin,则h(pi)与sin(pi)是等效的。函数句柄包含函数的路径、函数名、类型及可能存在的重载方法,可以用functions(function_handle)来显示函数句柄所包含的函数信息。
函数句柄可以使用“@”符号直接声明,也可以使用str2func函数进行声明,结果是一样的。例如:
使用函数句柄可以提高运行速度,系统不需要在每次调用时搜索一遍路径,而是在函数句柄包含的信息中直接可以找到函数的路径,因此,对于一个经常使用的函数,函数句柄可以提高程序的运行速度。另外,也正因为函数句柄包含了路径信息,因此在系统切换工作路径时,不需要将函数文件复制过来就可以同样使用该函数。自定义一个名为myfun的函数,声明其句柄如下:
函数句柄的另一种用法是匿名函数句柄。匿名函数是函数句柄的高级用法,句柄不是指向一个已经定义好的函数,而是指向一个表达式,声明方法是:变量名=@(输入参数列表)函数表达式。例如:
MATLAB中的变量名由字母、数字和下画线组成,且必须以字母开头。在MATLAB R2010b中,变量长度不超过63个字符,超过部分将被忽略。意味着如果声明了两个变量,变量名只有第64个字符之后是不同的,那么这两个变量将被视为同一个变量。MATLAB的变量名是区分大小写的,一种不错的编程风格是一律使用小写字母,不同单词之间使用下画线分开,如book_price。
MATLAB是用C语言开发的,C语言属于强类型语言,变量在使用之前必须强制声明。MATLAB则属于弱类型语言,通过赋值即可创建变量,变量类型取决于创建时的类型,而不需要强制声明。
MATLAB的变量和运算是以数组(矩阵)为基础的。数组分为向量和矩阵,向量是一维数组,矩阵是二维或多维的数组,标量也被当做数组,它是只有1行1列的数组。
1.数组的创建
数组可以使用“[]”操作符直接创建,也可以用函数进行创建。二维和多维数组中每一个维度都是对齐的,例如,每一行都包含相同个数的元素,如果不同系统将会报错。
变量名不超过63个字符:
向量的创建:
创建二维和多维数组:
MATLAB中用于创建数组或矩阵的部分函数如表2-4所示。
表2-4 创建数组或矩阵的函数
2.数组元素的访问和操作
多维数组元素的访问,有3种方法:全下标方式、单下标方式、逻辑1方式。全下标方式形如a(m,n,p…),需要指定元素是矩阵中的第几行第几列。单下标是以列优先的方式将矩阵的全部元素排列为一个大的向量,再指定元素的索引,形如a(index),这是由于在内存中,MATLAB数组是一列一列保存的。逻辑1方式是建立一个与矩阵同型的逻辑型数组,抽取该数组等于1的位置对应的元素。例如:
矩阵的操作中,还可能用到“:”操作符、end函数和空矩阵[]。冒号操作符可以表示抽取一整行或一整列,end函数表示下标的最大值,即最后一行或最后一列,空矩阵[]可以用于删除矩阵。
MATLAB中存在一些常量,属于系统中的预定义变量。这些预定义变量有特定的含义,默认情况下其值为常数。
■ ans:预设的保存计算结果的变量名,是用户没有指定运算结果名称时,系统默认的变量名。
■ eps:MATLAB定义的正的最小值,表示精确度。事实上,eps是一个函数,不带参数时默认参数为1,即eps(1),表示1附近的精确度。浮点数的表示中,越靠近零,精确度越高,因此eps(1)>eps(0)。eps(1)表示离1最近的浮点数与1相差eps(1)。浮点数运算时,系统自动将数字舍入到最近的一个数,例如:
1+eps(1)*4/5离1+eps更近,因此1-(1+eps(1)*4/5)等于eps(1)。
■ pi:圆周率的值。
■ Inf:表示无穷大,即1/0。-Inf即负无穷大。
■ NaN:即Not-a-Number,非数,无法定义的一个数。
■ i或j:虚数单位,等于sqrt(-1)。编写程序时注意尽量不要定义名为i或j的自定义变量,以防引起混乱。
■ realmax:最大的正实数。
■ realmin:最小的正实数。
■ nargin:函数输入参数的个数。
■ nargout:函数输出参数的个数。
MATLAB语言的运算符主要有算术运算符、关系运算符、逻辑运算符及一些特殊的运算符。
1.算术运算符
算术运算符可分为矩阵的运算符和数组的运算符两大类。矩阵运算将矩阵作为整体,按线性代数的规则进行运算,而数组运算是在矩阵或数组中的对应元素之间进行的运算。
矩阵的运算符如表2-5所示。
表2-5 矩阵运算的运算符
进行矩阵运算时应注意矩阵大小必须符合特定要求才能正确进行运算。如在矩阵加减运算中,矩阵大小必须相同;a*b中,a的列数必须等于b的行数。举例如下:
数组运算中的加减法使用了与矩阵运算相同的运算符,其余的运算符如表2-6所示。
表2-6 数组运算的运算符
数组运算是针对矩阵或数组中的每一个元素进行的运算,标量与数组的运算,是该标量与数组中每一元素分别进行的运算。
2.关系运算符
关系运算是同型数组对应元素之间进行的运算,关系运算符如表2-7所示。
表2-7 关系运算符
关系运算符的含义非常容易理解,常用于选择结构(如if-end语句)和while循环的判断中。这里需要注意,类似a>b这样的表达式,返回的是逻辑型变量,“==”和“~=”运算符同时比较复数的实部与虚部,其他关系运算符均忽略虚部。
3.逻辑运算符
MATLAB的逻辑运算符可分为一般逻辑运算符和先决逻辑运算符,如表2-8所示。
表2-8 逻辑运算符
逻辑运算中,所有非零值被当做true,零值当做false。“&&”与“||”是先决逻辑运算符。一般逻辑运算符可以对标量或数组进行运算,先决逻辑运算符只能对标量进行计算。另外,如果计算了第一个参与运算的对象就可以确定整个表达式的值,先决运算符就不会接下去计算其他剩下的运算对象,这种方式提高了执行效率,也可以避免一些错误。
另外,由于浮点数存在误差,所以“==”与“~=”的使用常常会出现意想不到的结果,这种错误通常称为round off错误。此时可以设定一定的精确度范围,忽略小于精确度的误差。
4.特殊运算符
MATLAB还有一些常用的特殊运算符,如表2-9所示。
表2-9 特殊运算符
“=”被用做赋值运算符,而不是按数学习惯表示相等(相等关系用“==”),是因为赋值运算使用的频率远高于相等关系用到的频率,用较短的符号作为赋值运算符在编程时间上更经济。
结构化程序设计包括3种结构:顺序结构、选择结构、循环结构。顺序结构是最简单的程序结构,系统按照程序的编写顺序依次执行。下面重点介绍选择结构和循环结构的几种流程控制语句。
1.if-else-end语句
if-else-end语句属于选择结构,只有一种选择是其中最简单的一种,格式如下:
当条件表达式为真时,执行if与end之间的语句。当有两种选择时,格式如下:
如果条件表达式为真,则执行程序语句1,否则执行程序语句2。如果程序需要有3个或3个以上的选择分支,可以使用如下方式的if-else-end语句格式:
在这种格式的语句中,else语句可有可无,程序遇到某个表达式为真时,即执行对应的程序语句,其他的分支将被跳过。
2.switch-case-otherwise-end语句
与C语言类似,除了if语句以外,switch语句也能实现选择结构,而且在多选择分支时使用switch语句更为方便。使用格式如下:
如果开关表达式等于case中的某一个表达式,则执行相应的程序语句。当开关表达式与所有表达式都不相等时,就执行otherwise所对应的程序语句。otherwise语句并不是必需的。
建立M脚本文件,输入以下内容:
命令窗口输出的结果为:
3.for-end语句
程序往往需要执行同一段或类似的程序语句,这时往往就需要使用循环结构。MATLAB中有两种循环结构的语句:for循环和while循环。for循环格式如下:
i是一个向量,向量长度代表循环执行的次数。对i中的每一个元素值,程序都执行一遍循环体程序。i也可以是字符串、字符串矩阵或字符串构成的元胞数组。for循环的循环体程序中,应避免人为修改循环变量i的值,以免造成错误。
for循环使用实例:
建立M脚本文件如下:
命令窗口输出:
4.while-end语句
for循环的循环次数是由表达式确定的,while循环则可以使用逻辑判断语句作为循环条件,因此循环次数可以是一个不确定的数。使用格式为:
只要表达式的值不为false,程序就执行循环。如果表达式的值总为true,程序就永远不会退出循环,形成死循环,因此,在循环体中必须有使表达式值为false的情况。
while循环使用实例:
建立M脚本文件,求整数1~9阶乘的和。
命令窗口输出的结果为:
5.其他流程控制命令
■ break:break通常与if语句一起使用,用于在一定条件下跳出循环的执行。在有多重循环时,只能跳出break所在的最里层循环。
■ continue:continue 用于结束本次 for 或 while 循环,紧接 着程序开始执行下一次循环,并不跳出整个循环的执行。 continue 命令也常常与 if 一起出现。
■ return:return命令可以直接结束程序的运行,并返回到上一层函数。
■ echo on/off:执行M文件时,显示/关闭显示文件中的命令。
■ pause:pause指令用于暂停程序,等待用户按任意键继续,pause(n)则暂停n秒后继续执行。
本小节介绍MATLAB的部分常用命令,如表2-10所示,并结合实例进行说明。
表2-10 MATLAB部分常用命令
续表
下面举例说明命令的用法。