前言
视频教程:b站视频【MATLAB教程_台大郭彦甫(14课)原视频补档】https://www.bilibili.com/video/BV1GJ41137UH/?share_source=copy_web&vd_sourc*e=d6b9f96888e9c85118cb40c164875dfc
官网教程:
参考博客:
声明:自己跟着敲了一遍,仅供个人参考学习。
软件版本:MATLAB R2016b
更新说明:
日期 | 更新内容 |
---|---|
2024.04.10 | 发布本文 |
2024.06.03 | 1.2.节处新增打开变量的位置 |
1. 数据类型转换
1.1. 数据(变量)类型
- int有符号整数
- uint无符号整数
- single单精度
- double双精度(默认)
1.2. 数据类型转换
例子:变量A为-1.5(默认双精度)
提示打开变量的位置:
也可以直接双击右侧工作区的"A"
1.3. char字符
- 一个字符在ASCll中使用0到255之间的数字代码表示;
- 创建一个字符或字符串,将它们放入单引号
''
中。 - ASCII码表
例子:
>> s1 = 'h'
s1 =
h
>> uint16(s1) %转为16位无符号整数
ans =
uint16
104
>> whos %查看变量
Name Size Bytes Class Attributes
ans 1x1 2 uint16
s1 1x1 2 char
>> s2 = 'H'
s2 =
H
>> uint16(s2)
ans =
uint16
72
>> whos
Name Size Bytes Class Attributes
ans 1x1 2 uint16
s1 1x1 2 char
s2 1x1 2 char
1.4. String字符串
同char放入单引号''
中。
例子:
>> s1='Example';
>> s2='String';
>> s3=[s1 s2]; %同s6=[s1, s2];
>> s4=[s1;s2];
错误使用 vertcat
串联的矩阵的维度不一致。
>> s4=[s1;s1];
>> s5=[s2;s2];
>> s6=[s1,s2];
说明:
s4报错是因为s1和s2拼接的维度不同。s1维度:1×7,s2维度:1×6
所以要维度一样的拼接。
打印结果:
>> s3
s3 =
ExampleString
>> s4
s4 =
Example
Example
>> s5
s5 =
String
String
>> s6
s6 =
ExampleString
1.5. 逻辑操作与赋值
例子:有一个字符串str = 'aardvark';
1.5.1.索引
>> str = 'aardvark';
>> str(3)
ans =
r
1.5.2.逻辑操作
>> 'a' == str
ans =
1×8 logical 数组
1 1 0 0 0 1 0 0
逻辑判断(==):找到字符串中所有为a的元素。true返回1,false返回0。
1.5.3.赋值操作(=)
>> str(str == 'a') = 'Z'
str =
ZZrdvZrk
赋值操作符为=
。这里是把a元素替换为Z.
1.5.4.思考(字符串比较)
如果我们想要将整个字符串与另一个字符串进行比较,用strcmp
函数。
查看strcmp函数:
>> help strcmp
strcmp Compare strings or character vectors
TF = strcmp(S1,S2) compares S1 and S2 and returns logical 1 (true)
if they are identical, and returns logical 0 (false) otherwise. Either
text input can be a character vector or a string scalar.
上段译为:
比较 s1 和 s2,如果二者相同,则返回 1 (true),否则返回 0(false)。
如果文本的大小和内容相同,则它们将视为相等。返回结果 tf 的数据类型为 logical。
>> str = 'aardvark';
>> str1 = 'arrdvark';
>> %比较str与str1
>> strcmp(str,str1)
ans =
logical
0
- 由于str与str1的文本大小和内容相同(相等),返回logical。
1.5.5.练习
分析:s2中元素是s1的逆序。s1的索引是1:19(我总和python的索引搞错,python是从0开始的),s2的索引逆序从-1开始。
1.5.5.1.方法1
查看s1的长度:
>> s1='I like the letter E'
s1 =
I like the letter E
>> length(s1) %查看s1的长度
ans =
19
>> size(s1,2) %size(s1)是查看s1的维度1×19。size(s1,2)是取size的第二个维度,即长度
ans =
19
逆序:
>> s2 = s1(length(s1):-1:1)
s2 =
E rettel eht ekil I
>> s2 = s1(size(s1,2):-1:1)
s2 =
E rettel eht ekil I
1.5.5.2.方法2
关于reverse
反转函数的用法:
>> help reverse
reverse Reverse the order of characters in string
NEWSTR = reverse(STR) reverses the order of the characters in each
element of STR and returns the reversed elements as NEWSTR. STR can be
a string array, character vector, or cell array of character vectors.
NEWSTR is the same type as STR.
reverse does not reverse the order of code units within Unicode
characters.
Example:
STR = string({'airport','control tower','radar','runway'});
reverse(STR)
returns
"tropria" "rewot lortnoc" "radar" "yawnur"
>> reverse(s1)
ans =
E rettel eht ekil I
1.5.5.3.方法3
关于flip
翻转函数的用法:
>> help flip
flip Flip the order of elements
Y = flip(X) returns a vector Y with the same dimensions as X, but with the
order of elements flipped. If X is a matrix, each column is flipped
vertically. For N-D arrays, flip(X) operates on the first
nonsingleton dimension.
flip(X,DIM) works along the dimension DIM.
For example, flip(X) where
X = 1 4 produces 3 6
2 5 2 5
3 6 1 4
>> flip(s1)
ans =
E rettel eht ekil I
2. Struct结构体数组
2.1. 创建一个学生结构体
学生作业的成绩:
分析:
- 创建的学生结构体包含4个属性(name,id,number,grade)
- 用
.
操作符表示属于student的成员。如student.name表示学生的姓名。
>> student.name = 'John Doe';
>> student.id = 'jd2@sfu.ca';
>> student.number = 301073268;
>> student.grade = [100 75 73; 95 91 85.5; 100 98 72];
>> %查看创建的学生结构体数组
>> student
student =
包含以下字段的 struct:
name: 'John Doe'
id: 'jd2@sfu.ca'
number: 301073268
grade: [3×3 double]
>> %查看分数
>> student.grade
ans =
100.0000 75.0000 73.0000
95.0000 91.0000 85.5000
100.0000 98.0000 72.0000
2.2. 向结构体中添加学生2信息
>> student2.name = 'Ann Lane';
>> student2.id ='aln4@sfu.ca';
>> student2.number = 301078853;
>> student2.grade = [95 100 90; 95 82 97; 100 85 100];
>> student2
student2 =
包含以下字段的 struct:
name: 'Ann Lane'
id: 'aln4@sfu.ca'
number: 301078853
grade: [3×3 double]
>> student2.grade
ans =
95 100 90
95 82 97
100 85 100
增加学生2的年龄:
>> student2.age = 18;
>> student2
student2 =
包含以下字段的 struct:
name: 'Ann Lane'
id: 'aln4@sfu.ca'
number: 301078853
grade: [3×3 double]
age: 18
查看学生2属性中的元素:
>> student2.id(1)
ans =
a
2.3. 结构体功能
例子:把学生2的age删了。
>> fieldnames(student2)
ans =
5×1 cell 数组
'name'
'id'
'number'
'grade'
'age'
>> student2
student2 =
包含以下字段的 struct:
name: 'Ann Lane'
id: 'aln4@sfu.ca'
number: 301078853
grade: [3×3 double]
age: 18
>> rmfield(student2,'age')
ans =
包含以下字段的 struct:
name: 'Ann Lane'
id: 'aln4@sfu.ca'
number: 301078853
grade: [3×3 double]
3. 嵌套结构
例子:创建结构体A、A2
- 创建结构体A:
>> %创建结构体数组A(写在一个结构体内)
>> A = struct('data', [3 4 7; 8 0 1], 'nest', ...
struct('testnum', 'Test 1',...
'xdata', [4 2 8], 'ydata', [7 1 6]));
>> A
A =
包含以下字段的 struct:
data: [2×3 double]
nest: [1×1 struct]
>> A.data
ans =
3 4 7
8 0 1
>> A.nest
ans =
包含以下字段的 struct:
testnum: 'Test 1'
xdata: [4 2 8]
ydata: [7 1 6]
- 创建结构体A2:
>> %创建结构体数组A2
>> A2.data = [9 3 2; 7 6 5];
>> A2.nest.testnum = 'Test2';
>> A2.xdata = [3 4 2];
>> A2.ydata = [5 0 9];
>> A2
A2 =
包含以下字段的 struct:
data: [2×3 double]
nest: [1×1 struct]
xdata: [3 4 2]
ydata: [5 0 9]
4. 元胞数组(Cell Array)
元胞数组(Cell Array)将类型不同的相关数据集成到一个单一的变量中,可存储不同类型的数据。
参考博客:Matlab中的元胞数组(cell)
创建元胞数组2种方法:
- 直接赋值法
- 利用{ }直接创建元胞数组的所有单元
例子:
4.1. 直接赋值法
4.1.1.内容索引法
赋值语句的左边用大括号{ }
将标识单元的下标括起来,右边为单元的内容。
{}
像是一个指针,指向一块区域,在那一块区域填写内容。
>> cell{1,1}=[1 4 3; 0 5 8; 7 2 9];
>> cell{1,2}='Anne Smith';
>> cell{2,1}=3+7i;
>> cell{2,2}=-pi:pi:pi;
>> cell
cell =
2×2 cell 数组
[3×3 double] 'Anne Smith'
[3.0000 + 7.0000i] [1×3 double]
4.1.2.单元索引法
赋值语句的左边用小括号( )
将标识单元的下标括起来,右边用大括号{ }
将单元的内容括起来。
即将左边看作一个简单的数组,然后用{}
在里面填写内容。
>> cell(1,1)={[1 4 3; 0 5 8; 7 2 9]};
>> cell(1,2)={'Anne Smith'};
>> cell(2,1)={3+7i};
>> cell(2,2)={-pi:pi:pi};
>> cell
cell =
2×2 cell 数组
[3×3 double] 'Anne Smith'
[3.0000 + 7.0000i] [1×3 double]
4.2. 利用{ }直接创建元胞数组
在大括号中一次列出所需创建元胞数组的内容。它们之间用逗号隔开,行与行之间用分号隔开。
>> cell={[1 4 3; 0 5 8; 7 2 9], 'Anne Smith'; ...
3+7i, -pi:pi:pi}
cell =
2×2 cell 数组
[3×3 double] 'Anne Smith'
[3.0000 + 7.0000i] [1×3 double]
4.3. 练习
4.3.1.练习1
把上面的方法都练习一遍。
>> B = {'This is the first cell', [5+j*6 4+j*5];...
[1 2 3; 4 5 6; 7 8 9], {'Tim', 'Chris'}}
B =
2×2 cell 数组
'This is the first cell' [1×2 double]
[3×3 double] {1×2 cell }
>>%--------------------------------------------
>> B(1,1) = {'This is the first cell'};
>> b(1,2) = {[5+j*6 4+j*5]};
>> B(1,2) = {[5+j*6 4+j*5]};
>> B(2,1) = {[1 2 3; 4 5 6; 7 8 9]};
>> B(2,2) = {{'Tim', 'Chris'}};
>> B
B =
2×2 cell 数组
'This is the first cell' [1×2 double]
[3×3 double] {1×2 cell }
>>%--------------------------------------------
>> B{1,1}='This is the first cell';
>> B{1,2}=[5+j*6 4+j*5];
>> B{2,1}=[1 2 3; 4 5 6; 7 8 9];
>> B{2,2}={'Tim', 'Chris'};
>> B
B =
2×2 cell 数组
'This is the first cell' [1×2 double]
[3×3 double] {1×2 cell }
访问元胞数组中的数据:
- 内容索引
B{2,2}
:返回该元胞数组对应区域中的内容
>> B{2,2}
ans =
1×2 cell 数组
'Tim' 'Chris'
- 单元索引
B(2,2)
:返回一个1×2的子元胞数组
>> B(2,2)
ans =
cell
{1×2 cell}
4.3.2.练习2
>> cell{1,1}(1,1)
ans =
1
4.4. 元胞数组函数
num2cell和mat2cell示意图:
例子:
>> a = magic(3)%magic(n) 产生n阶魔方矩阵
a =
8 1 6
3 5 7
4 9 2
>> b = num2cell(a)
b =
3×3 cell 数组
[8] [1] [6]
[3] [5] [7]
[4] [9] [2]
>> c = mat2cell(a, [1 1 1], 3)
c =
3×1 cell 数组
[1×3 double]
[1×3 double]
[1×3 double]
>> c{1} %直接访问元胞数组里的内容
ans =
8 1 6
>> c(1) %访问子元胞数组
ans =
cell
[1×3 double]
5. 多维数组
一个三维的元胞数组可以有行(row),列(column),层(layer)三个维度。在对元胞数组进行索引时,优先级从高到低的顺序分别是:行→列→层
5.1. 用花括号{}
定义三维元胞数组
例子:
分析:layer=2,每层的row=2,col=2
>> %第一层元胞数组
>> cell{1,1,1} = [1 2;4 5];
>> cell{1,2,1} = 'Name';
>> cell{2,1,1} = 2-4i;
>> cell{2,2,1} = 7;
>> %第二层元胞数组
>> cell{1,1,2} = 'Name2';
>> cell{1,2,2} = 3;
>> cell{2,1,2} = 0:1:3; % [0 1 2 3]
>> cell{2,2,2} = [4 5]'; %[4 5]的转置
>> %打印元胞数组
>> cell
2×2×2 cell 数组
cell(:,:,1) =
[2×2 double] 'Name'
[2.0000 - 4.0000i] [ 7]
cell(:,:,2) =
'Name2' [ 3]
[1×4 double] [2×1 double]
>> %查看子元胞数组
>> cell{1,1,1}
ans =
1 2
4 5
>> cell{2,1,2}
ans =
0 1 2 3
>> cell{2,2,2}
ans =
4
5
5.2. 用 cat() 函数对元胞数组进行拼接
使用 cat()
函数在指定维度(行、列、层3个纬度)上对元胞数组进行拼接。
例子:
分析:这里的1、2、3分别代表了按行、按列、按层拼接
>> A = [1 2;3 4];
>> B = [5 6;7 8];
>> %按行拼接
>> C = cat(1,A,B)
C =
1 2
3 4
5 6
7 8
>> %按列拼接
>> C = cat(2,A,B)
C =
1 2 5 6
3 4 7 8
>> %按层拼接
>> C = cat(3,A,B)
C(:,:,1) =
1 2
3 4
C(:,:,2) =
5 6
7 8
举一反三:再把5.1.节的例子用cat( )按层拼接做一遍。
>> cell{1,1} = [1 2;4 5];
>> cell{1,2} = 'Name';
>> cell{2,1} = 2-4i;
>> cell{2,2} = 7;
>> cell_1{1,1} = 'Name2';
>> cell_1{1,2} = 3;
>> cell_1{2,1} = 0:1:3;
>> cell_1{2,2} = [4 5]';
>> C = cat(3,cell,cell_1)
2×2×3 cell 数组
C(:,:,1) =
[2×2 double] 'Name'
[2.0000 - 4.0000i] [ 7]
C(:,:,2) =
'Name2' [ 3]
[1×4 double] [2×1 double]
C(:,:,3) =
'Name2' [ 3]
[1×4 double] [2×1 double]
5.3. reshape()改变数组行列数
例子:
分析:A是一个2×2 cell 数组,C是一个1×4 cell 数组。
C的排列方式是按行优先(1,1)-(1,2)-(2,1)-(2,2)还是按列优先(1,1)-(2,1)-(1,2)-(2,2)呢?
>> A = {'James Bond', [1 2;3 4;5 6]; pi, magic(5)}
A =
2×2 cell 数组
'James Bond' [3×2 double]
[ 3.1416] [5×5 double]
>> C = reshape(A,1,4)
C =
1×4 cell 数组
'James Bond' [3.1416] [3×2 double] [5×5 double]
- 最后发现是按列优先排列的,即 matlab 是按列优先存储矩阵的。
练习
>> A = [1:3; 4:6]
A =
1 2 3
4 5 6
>> B = reshape(A,3,2)
B =
1 5
4 3
2 6
5.4. 检查变量和变量状态
6. 文件访问(文件读写)
6.1. MATLAB Data:save()和load()
MATLAB工作区内的数据可以 以*.mat
格式保存在文件中。
使用save()
函数将数据保存到文件,使用load()
函数加载文件中的数据。
例子:
测试:
>> clear; a = magic(4);
save mydata1.mat %将变量以二进制形式存入文件中
save mydata2.mat -ascii %加上后缀-ascii,将变量以文本形式存入文件中
敲回车键就出现左侧的mydata1.mat和mydata2.mat。
双击2个文件就可以加载数据:
注:此时加载的mydata2.mat报错,原因是保存是以文本形式,加载却是以二进制形式。所以加上后缀
-ascii
,才能读取数据。
6.2. Excel表格:xlsread()和xlswrite()
例子:
- 创建一个名为04Score.xlsx的Excel表格,表格的数据如下:
- 然后读取数据如下:
注:最好保存在相对路径中,不然打开文件报错。
>> Score = xlsread('04Score.xlsx')
Score =
94 83 89
76 88 82
68 72 75
>> Score = xlsread('04Score.xlsx','B2:D4')
Score =
94 83 89
76 88 82
68 72 75
- 计算3位同学各自的平均成绩,然后放在最后一列:
>> M = mean(Score,2)
M =
88.6667
82.0000
71.6667
>> M = mean(Score')'
M =
88.6667
82.0000
71.6667
>> %把M放在sheet1的最后一列
>> xlswrite('04Score.xlsx', M, 1, 'E2:E4')
>> %此时再读一下写入M后的表
>> Score = xlsread('04Score.xlsx')
Score =
94.0000 83.0000 89.0000 88.6667
76.0000 88.0000 82.0000 82.0000
68.0000 72.0000 75.0000 71.6667
此时的表格中还没有平均值的列名。写入列名即可。
xlswrite('04Score.xlsx', {'Mean'}, 1, 'E1');
- 获取文本信息
>> [Score Header] = xlsread('04Score.xlsx')
Score =
94.0000 83.0000 89.0000 88.6667
76.0000 88.0000 82.0000 82.0000
68.0000 72.0000 75.0000 71.6667
Header =
4×5 cell 数组
1 至 4 列
'' 'Test1' 'Test2' 'Test3'
'John' '' '' ''
'Selina' '' '' ''
'Peter' '' '' ''
5 列
'Mean'
''
''
''
6.3. 低级文件 I/O
6.3.1.说明
- 在字节或字符级别读取和写入文件;
- 文件ID为
fid
; - 文件中的位置由可移动的指针(Pointer)指定。
6.3.2.低级文件I/O功能
6.3.2.1.打开和关闭文件
fid = fopen(filename,permission);
fclose(fid);
- 先获得fileID (文中为fid),用
fopen
打开文件。filename
为文件名,permission
为文件访问类型。文件访问类型有:
- ‘r’: 打开要读取的文件
- ‘r+’: 打开要读写的文件
- ‘w’: 打开或创建要写入的新文件。放弃现有内容(如果有)。
- ‘w+’: 打开或创建要读写的新文件。放弃现有内容(如果有)。
- ‘a’: 打开或创建要写入的新文件。追加数据到文件末尾。
- ‘a+’: 打开或创建要读写的新文件。追加数据到文件末尾。
参考博客:https://blog.csdn.net/qq_41880030/article/details/105051983
- 操作完毕后务必用
fclose
关闭文件,否则 matlab 将一直占用文件。
例子:将正弦值写入文件
新建脚本,命名为sinx_func.m,脚本代码为:
x = 0:pi/10:pi;
y = sin(x);
fid = fopen('sinx.txt','w');
for i=1:11 %循环11次
fprintf(fid, '%5.3f %8.4f\n', x(i), y(i));
end
fclose(fid);
6.3.2.2.通过格式化I/O进行读写
例子:先创建一个文件04asciiData.txt,再写一个脚本命名为fscanf_.m。
feof(fid)
检查是否到达文件结尾,到达结尾返回 true.
fid = fopen('04asciiData.txt','r');
i= 1;
while ~feof(fid)
name(i,:)= fscanf(fid,'%5c',1);
year(i)= fscanf(fid,'%d',1);
no1(i)= fscanf(fid,'%d',1);
no2(i)= fscanf(fid,'%d',1);
no3(i)= fscanf(fid,'%g',1);
no4(i)= fscanf(fid,'%g\n');
i=i+1;
end
fclose(fid);
tips:我后面的章节内容暂时不更了,可以根据需求来针对学习单块内容更快,没必要挨着从头学完。
-END-