2.1 数据类型(2)
2.1.4 函数句柄
在MATLAB平台中,对函数的调用方法分为直接调用法和间接调用法。
● 直接调用函数,被调用的函数通常被称为子函数。但是子函数只能被与其M文件同名的主函数或在M文件中的其他函数所调用,一个文件中只能有一个主函数。
● 使用函数句柄对函数进行调用可以避免上述问题。函数句柄提供了一种间接调用函数的方法。创建函数句柄需要用到操作符@。对MATLAB库函数中提供的各种M文件中的函数和使用者自主编写的程序中的内部函数,都可以创建函数句柄,从而可以通过函数句柄来实现对这些函数的间接调用。
创建函数句柄的一般句法格式为:
Function_Handle = @Function_Filename;
其中:
● Function_Filename是函数所对应的M文件的名称或MATLAB内部函数的名称。
● @是句柄创建操作符。
● Function_Handle变量保存了这一函数句柄,并在后续的运算中作为数据流进行传递。
例如,F_Handle=@cos就创建了MATLAB内部函数cos的句柄,并将其保存在F_Handle变量中,在后续的运算过程中就可以通过F_Handle(x)来实现cos(x)的功能。
在通过函数句柄调用函数时,也需要指定函数的输入参数。例如,可以通过F_Handle(arg1,arg2,…,argn)这样的调用格式来调用具有多个输入参数的函数。
对于那些没有输入参数的函数,在使用句柄调用时,在句柄变量之后的圆括号中不填写变量名即可,即F_Handle()。
例2-11:函数句柄的创建与调用。
在命令行窗口中输入:
F_Handle = @cos
输出结果:
F_Handle = 包含以下值的 function_handle: @cos
在命令行窗口中输入:
x = 0 : 0.25 * pi : 2 * pi; F_Handle(x) %通过函数句柄调用函数
输出结果:
ans = 列 1 至 3 1.000000000000000 0.707106781186548 0.000000000000000 列 4 至 6 -0.707106781186547 -1.000000000000000 -0.707106781186548 列 7 至 9 -0.000000000000000 0.707106781186547 1.000000000000000
MATLAB库函数中提供了大量关于处理函数句柄的操作函数,将函数句柄的功能与其他数据类型联系起来,扩展了函数句柄的应用。函数句柄的简单操作函数如表2-9所示。
表2-9 函数句柄的简单操作函数
函数名称 |
函数功能 |
functions(funhandle) |
返回一个结构体,存储了函数的名称、函数类型(simple或overloaded)。以及函数M文件的位置 |
func2str(funhandle) |
将函数句柄转换为函数名称字符串 |
str2func(str) |
将字符串代表的函数转换为函数句柄 |
save filename.mat funhandle |
将函数句柄保存在*.mat文件中 |
load filename.mat funhandle |
把*.mat文件中存储的函数句柄加载到工作区 |
isa(var, 'function_handle') |
检测变量var是否是函数句柄 |
isequal(funhandle,funhandle) |
检测两个函数句柄是否对应同一个函数 |
例2-12:函数句柄的基本操作。
在命令行窗口中输入:
F_Handlea = @exp
输出结果:
F_Handlea = 包含以下值的 function_handle: @exp
在命令行窗口中输入:
F_Handleb = @log
输出结果:
F_Handleb = 包含以下值的 function_handle: @log
在命令行窗口中输入:
functions(F_Handlea)
输出结果:
ans = 包含以下字段的 struct: function: 'exp' type: 'simple' file: ''
在命令行窗口中输入:
isa(F_Handlea,'function_handle') % 判断F_Handlea是否是函数句柄
输出结果:
ans = logical 1
在命令行窗口中输入:
isequal(F_Handlea,F_Handleb) % 判断两个函数句柄是否对应同一函数
输出结果:
ans = logical 0
2.1.5 结构体类型
MATLAB中的结构体与C语言中的结构体类似,一个结构体可以通过字段存储多个不同类型的数据。因此,结构体相当于一个数据容器,把多个相关联的不同类型的数据封装在一个结构体对象中。
如图2-1所示,结构体student中有4个字段,姓名字段name中存储了一个字符串类型的数据;年级字段grade中存储了一个浮点数值;科目字段subject中存储了一个一维字符串数组;成绩字段result中存储了一个一维数组。
图2-1 结构体student的示意图
一个结构体中可以有多个字段,每个字段又可以存储不同类型的数据,通过这种方式就把多个不同类型的数据组织在一个结构体对象中。
创建结构体对象的方法有两种,可以直接通过赋值语句给结构体的字段赋值,也可以使用结构体创建函数struct。两种方法的具体操作步骤如下。
(1)通过字段赋值创建结构体。在对结构体的字段进行赋值时,赋值表达式的变量名使用“结构体名称.字段名称”的形式书写,对同一个结构体可以进行多个字段的赋值。
例2-13:通过字段赋值创建结构体。
在命令行窗口中输入:
Student.Name = 'Sam'; Student.Grade = 6; Student.Subject = {'Chinese','Math','English'}; Student.Result = {99,99,99}; Student
输出结果:
Student = 包含以下字段的 struct: Name: 'Sam' Grade: 6 Subject: {'Chinese' 'Math' 'English'} Result: {[99] [99] [99]}
在命令行窗口中输入:
whos
输出结果:
Name Size Bytes Class Attributes Student 1x1 1370 struct
在上例中,通过对4个字段赋值,创建了结构体对象Student,然后用whos函数分析出Student是一个1×1的结构体数组。
注意:在进行字段赋值操作时,没有明确赋值的字段,MATLAB默认赋值为空数组。通过圆括号索引进行字段赋值,还可以创建任意尺寸的结构体数组。需要注意的是,同一个结构体数组中的所有结构体对象具有相同的字段组合。
(2)利用struct函数创建结构体。
struct函数的句法形式为:
StrArray = struct('filed1',var1,'filed2',var2,...,'filedn',varn)
上述语句可以创建结构体对象StrArray,并将其n个字段分别赋值为var1,var2,…,varn。
例2-14:利用struct函数创建结构体。
在命令行窗口中输入:
Schedule(2) = struct('Day','Thursday','Time','17:00','Number',18)
输出结果:
Schedule = 包含以下字段的 1×2 struct 数组: Day Time Number
在命令行窗口中输入:
Schedule(1) % 结构体第一个元素没有赋值,因此所有字段均为空数组
输出结果:
ans = 包含以下字段的 struct: Day: [] Time: [] Number: []
在命令行窗口中输入:
ScheduleArray = repmat(struct('Day','Thursday','Time','15:00','Number',18),1,2)
输出结果:
ScheduleArray = 包含以下字段的 1×2 struct 数组: Day Time Number
在命令行窗口中输入:
ScheduleArray(1) % 1×2的结构体数组的两个元素完全相同
输出结果:
ans = 包含以下字段的 struct: Day: 'Thursday' Time: '15:00' Number: 18
在命令行窗口中输入:
ScheduleArray(2)
输出结果:
ans = 包含以下字段的 struct: Day: 'Thursday' Time: '15:00' Number: 18
在命令行窗口中输入:
newArray = struct('Day',{'Thursday','Friday'},'Time',{'15:00','9:00'},'Number',{18,6})
输出结果:
newArray = 包含以下字段的 1×2 struct 数组: Day Time Number
在命令行窗口中输入:
newArray(1)
输出结果:
ans = 包含以下字段的 struct: Day: 'Thursday' Time: '15:00' Number: 18
在命令行窗口中输入:
newArray(2)
输出结果:
ans = 包含以下字段的 struct: Day: 'Friday' Time: '9:00' Number: 6
2.1.6 数组类型
在MATLAB中进行运算的所有数据类型,都是按照数组及矩阵的形式进行存储和运算的,二者在MATLAB中的基本运算性质不同,数组强调元素对元素的运算,而矩阵则采用线性代数的运算方式。本节主要介绍数组类型,关于矩阵的详细运算语法在第3章中讲解。
数组的属性及数组之间的逻辑关系,是编写程序时非常重要的两个方面。在MATLAB平台上,数组的定义是广义的,数组的元素可以是任意数据类型,例如可以是数值、字符串、指针等。
利用数组的构建方法可以直接对变量进行赋值。
例2-15:对变量赋值创建数组。
在命令行窗口中输入:
Array = [1 2 3 4 5 6]
输出结果:
Array = 1 2 3 4 5 6
在MATLAB中可以使用冒号“:”来代表一系列数值,有时也使用它来定义数组。其句法格式如下:
Array = i : k
创建从i开始、步长为1、到k结束的数字序列,即i,i+1,i+2,…,k。如果i>k,MATLAB则返回一个空矩阵。数字i和k不必是整数,该序列的最后一个数小于或等于k。
Array = i : j : k
创建从i开始、步长为j、到k结束的数字序列,即i,i+j,i+2j,…,k。如果j=0,则返回一个空矩阵。数字i、j和k不必是整数,该序列的最后一个数小于或等于k。
还有一些预定义函数也可以用来创建线性序列和逻辑序列。
Array = linspace(a,b,100)
在区间[a,b]上创建一个有100个元素的向量,这100个数把整个区间线性分隔。
Array = linspace(a,b,n)
在区间[a,b]上创建一个有n个元素的向量。这个命令和冒号表示形式相近,但是它直接定义了数据的个数。
例2-16:创建等差数列。
在命令行窗口中输入:
Array_a = 0:5,Array_b = linspace(0,5,6)
输出结果:
Array_a = 0 1 2 3 4 5 Array_b = 0 1 2 3 4 5
当数组的元素个数为0时,就称数组为空。空数组是特殊的数组,它不含有任何元素。空数组主要用于逻辑运算、数组声明、数组的清空等。
例2-17:创建空数组。
在命令行窗口中输入:
Array_Empty = []
输出结果:
Array_Empty = []