变量
在前面的内容中, 我们已经接触过一些matlab中的变量, 但是仅涉及double类型的向量和矩阵. 这里介绍一些matlab中其他类型的变量及其部分使用方法.matlab变量的总体分类如下:
matlab中提供一些类型之间转换的函数, 下面列举出一些常见的函数, 这些转换函数只需要对它的存在有印象即可, 等到实际应用中有需求时, 可以通过查询文档查看具体使用方法.
double()
: 将目标变量转换为double类型.single()
: 转换为单精度变量.int8()
: 转换为8位的整型变量.int16()
: 转换为16位的整型变量.int32()
: 转换为32位的整型变量.int64()
: 转换为64位的整型变量.uint8()
: 转换为无符号的8位整型变量.uint16()
: 转换为无符号的16位整型变量.uint32()
: 转换为无符号的32位整型变量.uint64()
: 转换为无符号的64位整型变量.
char & String
char
与C语言相同, Matlab中的char变量实际存储其 ASCII 码值, ASCII编码从0到255.char变量的声明, 要用一对' '
包含字符的内容. ' '
包含一个字符就是char类型变量, 包含多个字符就是string类型变量.
1 | s1 = 'h' |
通过执行上述代码, 可以得出 字符h
的ASCII编码值为104.
下面给出完整的ASCII码表.
String
String就是一系列的字符,比如:
1 | s1 = 'Example'; |
可以通过[ ]
形式将字符串拼接起来, 类似于矩阵的拼接.比如s3=[s1 s2]
.
注意到上面的命令执行结果中两个字符串之间是没有空格的, 指令中的空格只是两个输入变量之间相互区分的作用.如果想要得到带空格的结果字符串, 可以在拼接过程中手动添加空格字符,例如: s4= [s1 ' ' s2]
,
在矩阵的拼接中, 曾经提到过,只要满足拼接条件, 使用[]
的方式可以进行除了横向拼接外的其他形式的拼接,那么若执行s5=[s1;s2]
结果如何呢?
由于字符串的长度不一致, 导致无法进行纵向拼接, 可以通过补充字符的方式尝试再拼接一次,s5=[s1;s2 'x']
matlab中的String和C语言中的字符串在处理过程中还是存在一些不同之处, 看下面的例子, 思考其执行的结果.
1 | str='aardvark'; |
按C语言的理解, 比较两个字符串是否相等, 显然不相等, 那么应该返回逻辑0值. 但是事实并不是这样,
返回的结果并不是单一的0 ,而是一个由 0 和1 组成的向量, 通过观察可以发现, 返回的结果向量的长度与str长度相同, 进一步可以发现, 在str字符串中字符a
的位置在结果向量中是1. 因此, 在matlab中 字符与字符串之间的比较是字符逐一与字符串中的字符进行比较, 相同则返回1, 不同则返回0,返回的结果是一个向量值.为了进一步探究字符与字符串,字符串与字符串之间如何进行比较, 分别执行'aa'==str
,'12345678'==str
,观察结果.
结论如下:
字符与字符串进行比较: 字符与字符串中的每一个字符逐一进行比较, 相同则返回1, 不同返回0. 最终返回结果是一个向量.
字符串与字符串进行比较: 要求进行比较的字符串长度相同, 对两个字符串对应位置的字符进行比较, 相同则返回1, 不同则返回0. 最终的结果是一个向量.
那么str(str=='a')='Z'
的执行结果如何呢? 考虑到str()
就是对str字符串进行索引, 索引值就是str=='a'
的返回值, 上面已经讨论过, str=='a'
的返回值是 一个由0 和1 组成的向量, matlab面对这样一个向量的处理结果是:
似乎和想象中的存在一些差别, 对于普通的索引方式str([1 2 3])
,的结果如下:
这和我们的预期相同, 比较上述两种索引方式的区别, 可能的原因是, Matlab对于逻辑值的索引和普通的索引存在处理上的差别, 对于由0和1 组成的向量会优先处理成逻辑向量, 为了验证这一想法, 考虑执行下面两个命令:
显然, 并不是由0和1 组成的向量就是逻辑向量, 根据在其他语言处获得的经验, 我们尝试把数值变量强制转换为逻辑变量, 观察结果.
matlab中字符串对于逻辑值的索引和数值型的索引确实存在区别, 对于逻辑值的索引返回一个向量,其长度等于逻辑向量中1的个数, 字符由原字符串中与逻辑向量中1的位置相对应字符组成
str(str=='a')='Z'
的结果为:
练习:
写一个脚本文件, 实现字符串的逆置.
s1=‘I like letter E’ ==> s2=‘E rettel ekil I’
参考结果:
Structure
matlab中的结构体与C中的结构体类似 , 都是用来存储一系列的异型变量.结构体的逻辑模型如下图所示:
在matlab中输入下面的代码来写入上图中的信息.
1 | student.name = 'John Doe'; |
多个结构体类型的变量构成结构体数组.其逻辑示意图如下:
对于结构体数组, 其索引方式如之前的其他类型变量类似, 都是通过名称加( )
的方式进行索引.因此, 第二个结构变量的输入过程为:
1 | student(2).name= 'Ann Lane'; |
输入完成后, matlab中的student变量形式如下:
如果想要获得Ann Lane 第三门课程的成绩信息, 索引两次即可. student(2).grade(1,3)
下面列举一些和结构体有关的matlab内置的函数, 具体用法在需要时查看文档即可.
- cell2struct: 将元胞数组转换为结构体数组
- fieldnames: 结构体的字段名称
- getfield: 结构体数组字段
- isfield: 确定输入是否为结构体数组字段
- isstruct: 确定输入是否为结构体数组
- orderfields: 结构体数组的顺序字段
- rmfield: 删除结构体中的字段
- setfield: 为结构体数组字段赋值
- struct: 结构体数组
- struct2cell: 将结构体转换为元胞数组
- structfun: 对标量结构体的每个字段应用函数
比如:
fieldnames(student)
的执行结果:rmfield(student,'id')
的执行结果:
Nesting Structures (结构体嵌套)
结构体中可以继续嵌套结构体, 其逻辑模型如下:
结构体之间的嵌套, 可以使用函数struct
进行输入, 也可以使用索引的方式进行输入.下面给出一个例子
1 | A = struct('data',[1 2 3;4 5 6],'nest',... |
输入A.nest
查看结果:
Cell Array
细胞数组是另一种存储异型数据的数据类型.类似于一个矩阵,但是矩阵的每一个单元存储不同类型的数据.需要使用{ }
来声明.其逻辑示意图如下:
对于上述示意图中的细胞数组, 有以下两种输入方式, 但是都需要用到{ }
,只是形式上有所区别, 关于何时采用何种形式, 在后面的学习中会有更进一步的认识.
1 | % 第一种输入方式 |
上述两种输入方式只是形式上的区别,对于输入的结果没有任何影响. 实际上,matlab是通过指针来实现在一个矩阵中存放不同的数据类型, 也就是说, 细胞数组实际上是一个指针矩阵, A(1,1)中存放的是其内容的地址.示意图如下:
对于细胞数组的索引方式和普通矩阵的索引方式也有所区别, 比如, 如何才能索引到A(1,1)处的第一个元素1呢?首先想到的就是套娃思想,执行A(1,1)(1,1)
,A(1,1)(1,1)
的执行结果:
对于细胞数组的索引A{1,1}
与A(1,1)
存在着一定的区别:
从上面的结果上来看, 想要索引到第一个矩阵中的第一个元素正确的方法是A{1,1}(1,1)
:
练习:
建立一个细胞数组, 其中存储的内容如下图.
参考代码:
1 | B{1,1}= 'This is the first cell'; |
我还没有学会字符串数组的创建方法. 在最后一行代码使用B{2,2}= ['Tim' , 'Chris'];时, 总是会被执行成字符串拼接操作, 形成一个字符串. 而目前这种写法, B(2,2)处存放的不是字符串数组, 而是一个细胞数组中存放了两个字符串.
结果如下:
下面列出一些和细胞数组相关的matlab内置函数:
- cell: 细胞数组
- cell2mat: 将细胞数组转换为基础数据类型的普通数组
- cell2struct: 将细胞数组转换为结构体数组
- celldisp: 显示细胞数组内容
- cellfun: 对元胞数组中的每个细胞应用函数
- cellplot: 以图形方式显示细胞数组的结构体
- cellstr: 转换为字符向量细胞数组
- iscell: 确定输入是否为细胞数组
- mat2cell: 将数组转换为在细胞中包含子数组的细胞数组
- num2cell: 将数组转换为相同大小的细胞数组
- struct2cell: 将结构体转换为细胞数组
举个例子:
1 | a = magic(3) % magic(3)是生成3为的魔方矩阵, 魔方矩阵是横竖斜相加得数都相同的矩阵. |
效果:
Multidimensional Array
多维数组实际上就是套娃思想, 其逻辑示意图如下:
可以通过下面的代码输入一个三维的细胞数组:
1 | A{1,1,1} = [1 2 ; 4 5 ]; |
在思想上和其他语言中的多维数组应该没什么区别. 输入之后的结果示意图如下:
上面的矩阵输入方式比较复杂,在输入过程中要先考虑好每个索引值之间的相对位置, 很容易造成输入的最终结果和我们的预期结果不一致的情况, 下面介绍cat()函数, cat()
函数用来串联数组, 使用语法为C = cat(dim,A1,A2,…,An)
,dim参数代表拼接的维度参数,一般取1 2 3三个数值, 1表示列的维度,2表示行的维度,3则表示立体空间的第三个维度.比如
1 | A= [ 1 2 ; 3 4]; |
上述三种cat
方式对应的结果分别是:
于是, 对于上面的三维细胞数组的输入就可以转化为 输入两个平面细胞数组, 再对两个二维的细胞数组再第三维上执行cat()
函数.
1 | A{1,1} = [1 2;4 5]; |
下面再介绍reshape()
函数, 这个函数可以实现把一个的矩阵转化为的矩阵,但是要满足.
1 | A = {'James Bond', [1 2;3 4;5 6]; pi, magic(5)} |
可以看到, A是2维方阵, 而C是的矩阵.
关于变量的相关内容就介绍这么多, 下面列举一些和变量相关的matlab函数:
- isinteger: 确定输入是否为整数数组
- islogical: 确定输入是否为逻辑数组
- isnan: 确定哪些数组元素为 NaN
- isnumeric: 确定输入是否为数值数组
- isprime: 确定哪些数组元素为质数
- isreal: 确定数组是否为实数数组
- iscell: 确定输入是否为元胞数组
- ischar: 确定输入是否为字符数组
- isempty: 确定数组是否为空
- isequal: 确定数组相等性
- isfloat: 确定输入是否为浮点数组
- isglobal: 判断是否为全局变量
- ishandle: 测试是否有效的图形或 对象句柄
- isinf: 确定哪些数组元素为无限值
变量存储
目前为止的学习中, matlab工作区中的变量在每次关闭matlab后就随之删除了, 下次打开matlab时不会再有上次的工作区变量, 在实际的应用中, 变量的存储有着十分重要的意义.下面介绍常用的变量存储于读入的方法, 对于不常用或者用起来不方便的变量存储方法, 可以参考资料链接中的PPT或视频讲解.
把变量存储为matlab格式数据
1 | clear; |
上述代码执行完毕后 , 我们可以发现在当前工作目录中已经多了两个两个.mat
后缀的文件. 可以在windows资源管理器中查看到这两个文件. 对于第三行和第四行代码的区别, 第三行代码只是存储了当前工作区中的变量, 其编码方式没有指定, 默认为matlab的编码方式, 因此用文本编辑器打开时会出现乱码现象. 第四行代码在存储的同时指定了其编码方式 , 因此可以用文本编辑器打开查看其中的内容.
上述代码是存储工作区中的全部变量, 如果想要单独存储某一个变量, 需要执行 save data1.mat name
表示存储工作区中的name变量, 如果工作区中没有name变量则会报错.
读入变量使用load()
函数:
1 | load('mydata1.mat') |
将变量存储为Excel表格形式
只需修改扩展名即可.
1 | save data.xlsx |
和上面类似, data和data1的区别在于能否被其他软件正确解码.
matlab 从Excel表格中读取数据,可以使用xlsread()
函数, 可以指定起始读取位置和终止读取位置, 缺省为读取全部.
后面的内容在我的matlab上就开始报错了, 具体原因我还没有找到, 考虑到后面的内容实际应用可能不是很多, 因此这一章的笔记就写到这里了.
1 | b= xlsread('data.xlsx') |