2、MATLAB编程基础:变量与数据类型、矩阵与数组操作、流程控制语句、脚本与函数编写
说实话,很多刚接触MATLAB的朋友,上来就急着写算法、跑仿真。我见过不少项目,代码写得跟天书似的,变量名乱起,循环套循环,最后自己都看不懂。嗯,这其实是个坑。
我个人习惯是,先把MATLAB的编程基础打扎实。你想想看,地基不稳,楼盖得再高也危险。今天我们就聊聊MATLAB编程的四个核心模块:变量与数据类型、矩阵与数组操作、流程控制语句、脚本与函数编写。
核心观点:MATLAB的编程思维和C语言、Python不太一样。它天生就是为矩阵运算设计的。如果你还在用for循环一个一个处理数据,那说明你还没入门。
2.1 变量与数据类型
MATLAB的变量,用起来很随意。不需要提前声明类型,直接赋值就行。比如:
a = 5; % 数值
b = 'Hello'; % 字符串
c = [1 2 3]; % 行向量
d = true; % 逻辑值
但随意不代表可以乱来。我在项目中遇到过一个问题:同事用i和j做循环变量,结果MATLAB默认i和j是虚数单位,导致复数运算全乱了。避坑指南:别用i、j做变量名。
MATLAB的数据类型,常用的有这些:
| 类型 | 说明 | 示例 |
|---|---|---|
| double | 双精度浮点数(默认) | x = 3.14 |
| single | 单精度浮点数 | y = single(3.14) |
| int8/16/32/64 | 有符号整数 | z = int32(100) |
| char | 字符数组 | str = 'MATLAB' |
| logical | 逻辑值 | flag = (a > 0) |
| cell | 元胞数组 | C = {'text', [1 2]} |
| struct | 结构体 | S.name = 'Alice' |
小技巧:用whos命令可以查看当前工作区所有变量的详细信息。我调试代码时,第一步就是敲whos,看看变量类型对不对。
2.2 矩阵与数组操作
这才是MATLAB的看家本领。说白了,MATLAB里的一切都是矩阵。一个数就是1×1的矩阵,一个向量就是1×n或n×1的矩阵。
创建矩阵很简单:
A = [1 2 3; 4 5 6; 7 8 9]; % 3×3矩阵
B = zeros(3,4); % 全零矩阵
C = ones(2,5); % 全1矩阵
D = eye(4); % 单位矩阵
E = rand(3,3); % 随机矩阵
矩阵操作,我重点说三个:索引、运算、变形。
索引:MATLAB索引从1开始,不是0。这一点和C语言不一样,刚转过来的人容易搞混。
A(2,3) % 第2行第3列
A(:,1) % 所有行的第1列
A(1,:) % 第1行的所有列
A(2:3,1:2) % 子矩阵
运算:注意点乘和矩阵乘的区别。点乘是对应元素相乘,矩阵乘是线性代数里的乘法。
X = [1 2; 3 4];
Y = [5 6; 7 8];
X .* Y % 点乘:每个元素对应相乘
X * Y % 矩阵乘:线性代数乘法
我曾经见过一个仿真结果完全不对,查了半天,发现就是这里用了*而不是.*。嗯,这种错误,犯过一次就记住了。
变形:reshape、transpose、flip这些函数很实用。
v = 1:12;
M = reshape(v, [3,4]); % 变成3行4列
M' % 转置
2.3 流程控制语句
流程控制,说白了就是让代码按你的逻辑走。MATLAB支持if-else、switch、for、while这些。
if-else:
if x > 0
disp('正数');
elseif x == 0
disp('零');
else
disp('负数');
end
for循环:
for i = 1:10
disp(i^2);
end
但我要提醒你:在MATLAB里,能不用循环就别用循环。MATLAB的循环效率很低,尤其是嵌套循环。我优化过一个通信仿真程序,把三层for循环改成矩阵运算,速度提升了50倍。
避坑指南:我曾经在仿真里写了个for i = 1:100000,每次循环都动态扩展数组。结果跑了半小时还没完。后来改成预分配内存,result = zeros(100000,1),几秒钟就搞定了。
while循环:适合不知道循环次数的情况。
while error > tolerance
% 迭代计算
error = compute_error();
end
2.4 脚本与函数编写
脚本和函数,是组织代码的两种方式。脚本就是按顺序执行的一堆命令,没有输入输出。函数则有输入参数和返回值。
脚本示例(my_script.m):
% 计算圆的面积和周长
r = 5;
area = pi * r^2;
circumference = 2 * pi * r;
fprintf('面积: %.2f, 周长: %.2f\n', area, circumference);
函数示例(circle_calc.m):
function [area, circumference] = circle_calc(r)
% 计算圆的面积和周长
% 输入: r - 半径
% 输出: area - 面积, circumference - 周长
area = pi * r^2;
circumference = 2 * pi * r;
end
我个人习惯是:能写成函数的,绝不写成脚本。函数的好处太多了:
- 变量作用域隔离,不会污染工作区
- 可复用,一次编写到处调用
- 便于调试和测试
- 支持递归调用
函数还有个小技巧:可变输入输出参数。用varargin和varargout可以处理不确定数量的参数。
function result = sum_all(varargin)
% 求所有输入参数的和
result = 0;
for i = 1:nargin
result = result + varargin{i};
end
end
调用时:sum_all(1,2,3,4,5),返回15。这个在写通用工具函数时特别有用。
知识体系总览
下面这张图,是我梳理的本章知识结构。你可以把它当成一个地图,学完一章回头看看,心里就有数了。
我的建议:学完这一章,你可以在MATLAB里新建一个脚本,把上面的代码示例都跑一遍。然后试着写一个自己的函数,比如计算信号的信噪比。动手做一遍,比看十遍都管用。