这篇学习笔记是系列第一篇,定位很明确:只要把MATLAB基础知识吃透——变量、矩阵、语法、绘图,后面不管做图像处理、信号分析还是数值仿真,都能直接上手。
学过统计、做过信号处理、跑过仿真的人,或多或少都碰到过MATLAB。我对它的定位一直是:它不是一门让人学习"编程思维"的语言,而是一台功能极其丰富的科学计算工作台。你不需要先背语法再干活,反而是先想清楚"我要算什么、画什么、验证什么",然后打开文件就开始折腾,哪一步不会,就用help现查现用。这种"边用边学"的模式,恰恰是MATLAB最舒服的打开方式。
这篇文章面向的是零基础或刚接触MATLAB不久的人。我会把最常用、最容易被忽略的基础点串起来:三个窗口怎么用、变量和数据类型怎么理解、矩阵运算和数组运算有什么区别、脚本和函数怎么组织、绘图怎么入门,最后再整理一个能复现的小实验,把前面所有知识点揉在一起。你也可以直接跳过理论部分,先跑一遍最后一章的Demo,遇到不懂的地方再回来看对应章节。
1. 为什么选MATLAB打地基:它是披着编程外衣的科学工作台
1.1 这个工具到底解决什么问题
先搞清楚MATLAB的定位。它的核心能力是"矩阵计算"和"数据可视化"。早期它叫Matrix Laboratory,名字里就写着"矩阵实验室"。你可以把它理解成一个超级计算器:这个计算器能存整个表格数据、能对整批数据统一运算、能画图、能拟合曲线、能解方程、能跑仿真。
举个例子你就明白了。用普通方式处理一组数据,通常是循环里逐个算;但在MATLAB里,你写一行A * 2 + 1,整个矩阵里所有元素都乘2再加1。这种"对整体数据做批量运算"的思维方式,是所有后续学习的基础。很多第一次接触MATLAB的新手,最容易犯的毛病就是把C语言、Python那套循环思维搬过来,明明一行能解决的事,非要写三层for循环。
1.2 什么类型的工作适合用它
我在实际辅导中经常遇到两类学生:一类是拿着MATLAB当万能工具,什么项目都想往里面塞;另一类是听学长说"MATLAB不行",就彻底绕开它。其实两者都偏了。
MATLAB真正强的地方在于:快速验证算法、处理矩阵相关数据、画科研插图、做仿真模拟。比如你导师丢给你一份实验数据,让你"先看看趋势",你半小时内就能导入、清洗、画图、给出统计量,这个效率是很多通用语言比不了的。但如果你要写一个对性能极度敏感的商业服务端、或做一个需要嵌入用户手机的交互应用,那MATLAB就不太合适,那时候Python或C语言更对路。
所以我的建议是:把MATLAB当作第一门上手工具,它会帮你建立"数据怎么组织、结果怎么可视化"的直觉。等需要做工程落地的时候再去学别的语言,你不会白学,因为分析思路是通用的。
2. 第一次打开软件要弄清楚的三个窗口:命令行、工作区、当前文件夹
2.1 三个窗口各自干什么
安装完成首次打开,界面看起来有点复杂,但真正影响日常使用的,只有三个窗口,我建议第一天就把它们的大致分工搞明白。
| 窗口 | 作用 | 最常用场景 |
|---|---|---|
| 命令行窗口 | 输入单条命令,回车立刻执行 | 查帮助、测试表达式、临时算个数 |
| 工作区 | 显示当前存在的所有变量 | 检查变量值、双击查看矩阵内容、右键保存数据 |
| 当前文件夹 | 指向你正在使用的目录 | 存放和查找脚本、数据文件、函数文件 |
提示:把"当前文件夹"这个概念放在心里。MATLAB里出现"找不到文件""未定义函数或变量"这类报错,十次里有八次是路径问题。
2.2 把路径问题从第一天就解决掉
打开MATLAB后,第一步不是写代码,而是养成本目录管理习惯。最简单的做法是每次开新项目,就新建一个文件夹,然后在MATLAB顶部把它设置为当前文件夹。
路径相关的三个命令我一直在用:
pwd % 显示当前路径,相当于看"我在哪个目录" cd 'D:\work\demo' % 切换目录 which xxx % 查看某个名字对应的文件在哪其中which特别实用。当你写了个函数叫test,运行后却报错或执行了别的东西,用which test看一下它到底定位到哪个文件,问题往往一眼就能看出来。
2.3 三个小习惯:分号、注释、help
第一天我只要求你记住三件事。
第一,语句末尾加分号。分号的作用是"执行但不显示结果"。你不加分号,MATLAB会把每个中间步骤的结果都打印出来,既刷屏又拖慢速度。我见过太多新手跑一个循环,命令行窗口滚出几万行数据,最后只能关掉重开。
第二,注释永远不嫌多。单行注释用%,区块注释用%{和%}。不要觉得"这是我的代码,过两天我还记得"。实测经验是,一周之后你连自己写的变量名都可能认不出来,更别说思路了。
第三,遇到不懂的函数,第一时间敲help 函数名。比如help plot会显示用法和样例链接,doc plot会打开图文版文档,比到处搜网页快得多。还有一个被很多人忽略的命令是lookfor 关键词,你不记得函数叫什么名字时,用它按功能搜。比如lookfor 傅里叶,就能找到相关函数。
3. 变量与数据类型:先学会给数据贴标签
3.1 变量命名规则,以及变量覆盖
MATLAB的变量命名很宽松,本质上就是一个"名字对应一块数据"。你可以直接写:
x = 3 y = x + 5工作区里就会多出x和y两个变量。命名原则我总结成几条:不能以数字开头,不能含空格和运算符,尽量别用中文,不要用len、sum这类容易和内置函数撞车的词。如果实在要用name这种通用变量名,注意先查一下which name,看看是否覆盖了内置功能。
这里要专门提一下"变量覆盖"问题。MATLAB是允许你用变量名覆盖掉内置函数名的,比如你写sin = 10,之后再调用sin(pi/2)就会报错或得到意外的结果。解决方式很简单,执行clear sin清掉这个变量。这是新手最容易踩、又最难想到的坑。
3.2 常用数据类型速查
MATLAB默认存储任何数字都是双精度浮点数,也就是double类型。你不需要像C语言一样先声明int还是float。但另外几种类型你需要认识:
| 类型 | 用途 | 例子 |
|---|---|---|
| double | 普通数值,默认类型 | 3.14, 42 |
| char | 单个字符或字符串数组 | 'hello' |
| logical | 逻辑真伪 | true, false |
| cell | 可以装不同类型数据的"大盒子" | {'张三', 23, [1,2,3]} |
| struct | 带字段名的数据集合 | student.name |
我建议新手重点掌握cell和struct,因为实际数据经常是"混合类型"的。比如导出一份学生成绩表,里面有姓名、学号、分数,分数是数值,姓名是文本,你很难用纯矩阵存,但可以用cell或struct轻松搞定。
3.3 数字世界的四个"特殊成员"
MATLAB里有几个特殊值,新手经常被它们吓到:
NaN:表示"不是一个数"。比如0/0的结果就是NaN。做数据清洗时,它很常见,可以用isnan(x)来定位缺失值。Inf:无穷大。1/0会得到它,后面做计算时要小心,因为Inf会传染,任何数加Inf还是Inf。eps:浮点数相对精度的下限。MATLAB里判断两个数相等时,很少直接用==,而是看它们的差值是否小于某个容差。pi:圆周率,但注意它是一个浮点值,虽然精度很高,不是数学上的精确 π。
如果你算出来的结果显示 }1.0000000000000002{ 这种末尾带小尾巴的数值,不用慌,这是因为电脑用二进制存十进制小数时本身的精度限制。用format long或format short切换显示位数,同时可以借助round(x, n)来四舍五入。
4. 矩阵才是MATLAB的心脏:这节不掌握,后面全白学
4.1 构造矩阵的几种姿势
在MATLAB里,最核心的数据结构是矩阵。普通语言里的标量(单个数字)在MATLAB里其实被当作1×1矩阵,字符串则常被看作是字符矩阵。所以"矩阵"这个概念是绕不开的。
创造矩阵的方式很多,记住这几种基本够用:
A = [1, 2, 3; 4, 5, 6]; % 方括号里分号表示换行 B = 1:5; % 结果是 [1 2 3 4 5] C = 0:2:10; % 从0到10,步长2 D = linspace(0, 1, 7); % 0到1之间均匀取7个数 E = zeros(3, 2); % 全0的3行2列矩阵 F = ones(2, 4); % 全1矩阵 G = eye(3); % 3阶单位矩阵 H = rand(3, 3); % 均匀分布的随机矩阵特别注意1:5和linspace(0,1,7)的区别。冒号写法是按步长生成,linspace是按个数生成。很多新手在这两个逻辑上出错:想要100个点,结果写成了1:100,于是得到从1到100共100个点;但如果范围是0到1,0:0.01:1会产生101个点而不是100个,想要恰好100个点就得用linspace(0, 1, 100)。
4.2 索引和切片:先从1开始,而且用的是圆括号
这是MATLAB和大多数编程语言最不一样的地方:数组下标从1开始,不是0。我见过无数次新手敲A(0,1)然后报错,一脸茫然。记住规则就行:第一行第一列是A(1,1)。
索引时用圆括号,不是方括号:
A = [10, 20, 30; 40, 50, 60]; A(2, 1) % 第二行第一列,结果是40 A(:, 1) % 所有行的第一列,结果是 [10; 40] A(1, :) % 第一行的所有列 A(2, [1,3]) % 第二行的第1列和第3列 A(end) % 最后一个元素end是一个很方便的关键字,表示"到末尾"。比如想删除矩阵最后一列,直接A(:, end) = []就能做到。这句代码意思是"把最后一列设为空",在MATLAB里合法且非常常用。
4.3 分清*与.*、^与.^
这是整个基础阶段最容易混淆的点,我建议你单独做几道题练一下。
不带点号的*、/、^是矩阵运算,遵循线代规则。比如矩阵乘法要求左矩阵列数等于右矩阵行数。带点号的.*、./、.^是数组运算,对应元素逐个计算,只要求两个矩阵尺寸一致或满足广播条件。
看一个具体例子:
A = [1, 2; 3, 4]; B = [2, 0; 0, 2]; A * B % 矩阵乘法,结果是 [2, 4; 6, 8] A .* B % 对应元素相乘,结果是 [2, 0; 0, 8] A ^ 2 % 矩阵自己乘自己,A*A A .^ 2 % 每个元素平方,结果是 [1, 4; 9, 16]脑子里可以把不带点的看成"整块操作",带点的看成"逐位操作"。后面画图、处理图像、算统计量时,绝大多数情况用的是带点的那组。
4.4 学会"整体操作":能不用循环就别用循环
既然矩阵能整体运算,很多循环就没有必要了。比如把矩阵里所有大于5的元素改成0,新手容易写成两层for循环,但其实一句话:
A(A > 5) = 0;这个技巧叫"逻辑索引":括号里放一个逻辑表达式,返回满足条件的位置,然后直接赋值。类似的还有mean(A, 2)按行求平均、sum(A, 1)按列求和。掌握这些整体操作,代码短、执行快、还不容易出现循环下标越界的错误。
5. 让代码有逻辑:脚本、循环、函数
5.1 从命令行到脚本:把操作变成文件
在命令行窗口里输入语句,回车就执行,适合验证想法,但没法复用。真正干活时要新建脚本文件:点"新建脚本",或直接用edit myScript.m。脚本文件就是把一串命令按顺序放进去,点"运行"就从上到下执行。
建议你在脚本里用%%做分段。这是个大杀器:写了%% 数据导入,那一段就会高亮成一个可单独运行的区块,方便一段一段调试,不用把整个几百行的脚本从头跑一遍。我强烈建议从一开始就养成这个习惯。
5.2 if、for、while够用就好
分支和循环无论在什么语言里都是基本功,MATLAB的语法很直白:
x = 10; if x > 5 disp('x比较大'); elseif x < 0 disp('负的'); else disp('中间值'); end for i = 1:5 disp(i); end while x > 0 x = x - 1; end要注意每行条件结束不用加分号,end不能漏。实际中最容易被忽略的问题是循环里不要反复打印变量,否则执行很慢。想抽查运行进度,可以在循环里用if mod(i,1000)==0每1000次输出一次。
5.3 函数文件的第一行是命门
脚本和函数最重要的区别在于:函数有输入输出参数,能传值、能返回结果。在MATLAB里写函数,文件里第一行必须是function开头的声明,否则就变成脚本了。
function y = mySquare(x) % 计算平方 y = x .^ 2; end这个文件需要保存为mySquare.m,文件名必须和函数名一致。我在这里踩过无数次坑:文件名写成了my_square.m,函数名写成了mySquare,运行时报错还找不到原因。还有一个更容易忽略的规则:函数文件里除了函数声明之外,不要在同一个文件里写不少函数之外的 "顶层命令",否则MATLAB会把函数部分忽略,只当脚本执行。
6. 让数据"看得见":绘图基础
6.1 一行plot
绘图是MATLAB吸引人的地方。画一条曲线只需要:
x = linspace(0, 2*pi, 100); y = sin(x); plot(x, y);这个操作会弹出一个单独的图窗,显示 x-y 的关系曲线。命令执行后,图形窗口会自动打开,你可以手动缩放、添加文字、保存图片。
6.2 让图"拿得出手"的几个基本修饰
很多初学者画完图就交差,但实际用的时候,图是要写进报告、放进论文的。那时候你就会发现,一张没有坐标轴标签、没有图例、没有网格的图,根本没法看。至少这四条要习惯:
plot(x, y, 'LineWidth', 2); xlabel('时间 (s)'); ylabel('振幅'); legend('sin(x)'); grid on;手里还有一组对比曲线时,用hold on把多条曲线画在同一张图上。要注意的是,画完一组数据后如果不执行hold off,后续新图还会叠加在旧图上,很多人因此画出乱七八糟的叠加图。
6.3 subplot排版与散点、直方图
如果想在一个窗口里排列多张子图,用subplot(行数, 列数, 序号)。比如:
subplot(1, 2, 1); plot(x, y); subplot(1, 2, 2); scatter(x, y);除了plot,日常用得比较多的还有scatter画散点图、histogram画直方图、bar画柱状图。它们的使用逻辑和plot几乎一样:传入数据、加上标签、调整样式。这些绘图函数的共同特征是"接受向量或矩阵作为输入",前面吃透矩阵操作,这边就会顺畅。
7. 我踩过的常见坑汇总:写给下一个新手
7.1 中英文标点与输入法
这个坑特别隐蔽。在MATLAB编辑器里,中文输入法下的分号、逗号、圆括号都是全角字符,MATLAB根本识别不了。新手最容易出错的场景就是:注释里写中文后忘了切回英文,下一行代码直接爆红。
注意:当命令行窗口出现"错误:意外的运算符"或者红色波浪线标在语句开头时,先检查是否混入了全角字符,尤其是分号
;和逗号,。
7.2 文件名不能叫什么
文件名有一类雷区,用一句话总结:不能以数字开头,不能有空格,不能是MATLAB的关键字或内置函数名。像1.m、my data.m、if.m都是不可用的。特别要提的是,别把脚本命名为plot.m、test.m这种和内置函数重名的名字,因为MATLAB会优先找当前目录的文件,一旦调用plot,加载的可能是你那个乱七八糟的脚本,行为完全无法预期。
7.3 变量被覆盖、clear all 的滥用
前面提过变量覆盖内置函数的坑,这边再深入一下clear。很多人一出问题就clear all清空一切,这在调试时非常危险:会把辛苦导入的数据全删掉,也会把断点变量清掉。我建议的做法是:只清理具体的变量,用clear x y,或者实在乱了就close all关掉图窗,然后再用clear清空工作区。
7.4 浮点数比较别直接用==
这是我见过的另一类高频错误。比如循环for i=0.1:0.1:1,你在循环里判断if i == 0.3,很可能会错过条件,因为0.3在二进制里存的是近似值。正确做法是判断差值:
if abs(i - 0.3) < eps disp('相等'); end以后处理实验数据时,这个思路非常重要。大量真实测量值不会精确到刚好等于某个值,用容差判断是基本素质。
7.5 不要硬扛:用断点和 dbstop
代码报错不可怕,可怕的是不知道错在哪。新手常见操作是满屏打印变量,或者一段段注释排查。其实有更省力的做法:在编辑器行号旁边的横条上点一下,设置一个断点,运行到那一行就会暂停,此时你可以逐个查看变量当前值、继续单步执行。还有一个救命的命令:
dbstop if error加了它之后,任何未捕获错误都会在出错的那一行停下来,而不是直接把整段脚本中断在某个你不明所以的位置。
8. 把基础串一遍:复现一个数据分析Demo
8.1 场景设定
假设现在我们要完成一个小任务:生成1000个服从正态分布的随机数,计算它们的均值、标准差、最大值和最小值,并画出直方图与累积分布曲线,最后把统计结果输出到文本里。这个任务覆盖了变量、随机数、内置函数、绘图、输出,是检验基础的绝佳试金石。
8.2 完整代码与逐行说明
打开脚本文件,把下面的代码保存为demoStats.m,建议你手敲一遍,不要直接复制,因为代码敲得越慢,语法记忆越牢。
%% 生成数据 rng(42); % 固定随机种子,保证结果可复现 data = randn(1000, 1); % 1000行1列,标准正态分布 %% 计算统计量 avg = mean(data); sd = std(data); maxVal = max(data); minVal = min(data); fprintf('均值: %.4f\n', avg); fprintf('标准差: %.4f\n', sd); fprintf('最大值: %.4f\n', maxVal); fprintf('最小值: %.4f\n', minVal); %% 画图 figure; subplot(1, 2, 1); histogram(data, 40); % 40个条形 title('频数分布'); subplot(1, 2, 2); x = sort(data); y = (1:1000) / 1000; % 累积比例 plot(x, y, 'LineWidth', 1.5); title('累积分布曲线'); grid on;第一行rng(42)是很多人会忽略的关键操作。它让随机数发生器固定下来,于是每次运行这行脚本,data都完全相同。在做可复现研究时,这个小小的种子值能让别人跑出来的结果和你一致,否则每次运行randn都是不同的一组数据,实验结果没法沟通和核对。
fprintf是格式化输出的命令,%.4f表示保留4位小数。这一段设置了固定格式,最终在命令行窗口能看到整齐的统计结果,比直接用disp(avg)更能控制输出外观。
画图部分用了subplot分左右两张图。左边直方图看数据大致分布,右边累积分布曲线看单调增长趋势。这两张图拼在一起,基本能反映一个随机变量的分布形态。
8.3 复盘清单:确认你掌握了什么
跑完这个Demo之后,建议你按下面这张清单自查一遍,每个项目如果不能独立说明白,就回到对应章节补课:
- 工作区里
data的尺寸是1000×1,打开它能不能看到一个长列数字? - 如果把
rng(42)删掉再运行一次,均值、标准差会不会变?为什么? - 如果想让直方图有20个条形,应该改哪里?
- 如果想让
fprintf输出保留2位小数,应该改哪个格式符? - 为什么
plot(x, y)之前要先执行sort(data)?
这五个问题都能答上来,说明你的MATLAB基础知识已经过关,接下来可以放心去学绘图进阶、数据处理、Simulink仿真或者各类工具箱了。
最后说一个我在实际教学中反复强调的体会:MATLAB不要死记硬背,把它当成一个巨大的交互式计算本来用。忘了函数就help,不确定结果就随手跑一下看工作区,写长代码务必用%%分段。第一遍打基础,用这篇笔记的Demo做起点,每天动手敲几行、改几个参数,比一次性啃完一本几百页的书有用得多。