MATLAB流程控制语句:if判断、for循环与异常处理

发布时间:2026/7/31 2:47:42
MATLAB流程控制语句:if判断、for循环与异常处理 任何编程语言都需要流程控制MATLAB也不例外。但MATLAB里有一个很重要的原则能用矩阵运算就不用循环循环在MATLAB里相对慢。这篇文章讲清楚各种控制结构的语法和适用场景。if-elseif-else 条件判断基本语法score82;ifscore90gradeA;elseifscore80gradeB;elseifscore60gradeC;elsegradeF;end多条件组合x15;y-3;% 和 || 是短路运算符用于标量ifx0y0disp(x正y负)end% 和 | 是逐元素运算符用于数组v[1,-2,3,-4];v(v0v5)% 取1到5之间的元素字符串条件判断methodspline;ifstrcmp(method,linear)disp(线性插值)elseifstrcmp(method,spline)disp(样条插值)end% R2017a之后可以直接比较string类型ifmethodsplinedisp(样条插值)endswitch-case枚举类型的多分支判断比写一堆 if-elseif 清晰signal_typesine;switchsignal_typecasesinet0:0.01:1;xsin(2*pi*5*t);case{square,rect}% 多值用cell合并t0:0.01:1;xsquare(2*pi*5*t);casesawtootht0:0.01:1;xsawtooth(2*pi*5*t);otherwiseerror(不支持的信号类型%s,signal_type)endswitch 也可以匹配数值n3;switchncase1disp(一)case{2,3}disp(二或三)otherwisedisp(其他)endfor 循环基础用法% 遍历数值范围fori1:5fprintf(i %d\n,i)end% 自定义步长fork0:0.2:1disp(k)end% 倒序fori10:-1:1fprintf(倒数 %d\n,i)end遍历矩阵的列A[147;258;369];% for循环遍历矩阵时每次取一列forcolAdisp(col)% 每次col是一个列向量end遍历cell数组files{data1.csv,data2.csv,data3.csv};fork1:length(files)datareadmatrix(files{k});fprintf(文件 %s 加载了 %d 行数据\n,files{k},size(data,1))end预分配内存重要性能技巧% 错误示范动态扩容每次循环都要重新分配内存速度极慢result[];fori1:10000result[result,i^2];% 每次都复制整个数组end% 正确做法提前分配好大小resultzeros(1,10000);% 预分配fori1:10000result(i)i^2;% 只填值不重新分配end这个差别在数据量大时非常明显10000次循环可能差10倍速度。while 循环当循环次数不确定时用while% 牛顿法求平方根x2.0;% 初始猜测target10.0;whileabs(x^2-target)1e-8x(xtarget/x)/2;endfprintf(sqrt(%.1f) ≈ %.10f\n,target,x)防止死循环max_iter1000;iter0;whileconditionitermax_iter% 迭代计算...iteriter1;endifitermax_iterwarning(达到最大迭代次数可能未收敛)end工程代码里while循环一定要设置最大迭代次数保护否则算法不收敛时程序会一直卡着。break 和 continuebreak提前结束循环% 找第一个大于10的元素data[3,7,2,15,4,9];found_idx-1;fori1:length(data)ifdata(i)10found_idxi;break% 找到就立即跳出endend% 更简洁的写法向量化found_idxfind(data10,1,first);continue跳过本次继续下次% 只处理正数data[1,-2,3,-4,5,-6];resultzeros(size(data));fori1:length(data)ifdata(i)0continue% 跳过负数和零endresult(i)sqrt(data(i));end同样continue的用途大多可以用逻辑索引替代性能更好resultzeros(size(data));posdata0;result(pos)sqrt(data(pos));try-catch 异常处理读文件、调外部函数时错误处理必不可少filenames{data1.csv,missing.csv,data3.csv};resultscell(length(filenames),1);fork1:length(filenames)trydatareadmatrix(filenames{k});results{k}mean(data(:));fprintf(✓ %s 处理完成均值%.4f\n,filenames{k},results{k})catchME% ME是MException对象fprintf(✗ %s 失败%s\n,filenames{k},ME.message)results{k}NaN;endend获取错误信息tryx1/0;% 不会报错InfA[12;34];A(5,5)% 这会报错catchMEfprintf(错误ID%s\n,ME.identifier)fprintf(错误信息%s\n,ME.message)fprintf(发生位置%s 第%d行\n,ME.stack(1).name,ME.stack(1).line)end自定义错误和警告functionresultsafeDivide(a,b)ifb0error(safeDivide:zeroDenominator,除数不能为零)endifabs(b)1e-10warning(safeDivide:smallDenominator,除数接近零结果可能不可靠)endresulta/b;enderror会终止执行并抛出异常warning只显示警告信息但继续执行。什么时候用循环什么时候用向量化这是MATLAB学习的一个重要思维转变适合向量化不用循环% 计算1到1000每个数的正弦值x1:1000;ysin(x);% 直接作用于整个向量内部是高度优化的C代码% 找所有大于均值的元素datarandn(1,10000);above_meandata(datamean(data));% 对矩阵每行求和Arand(100,50);row_sumssum(A,2);% 按行求和返回100x1向量不得不用循环的情况% 有前后依赖关系的递推计算x(1)1;fori2:100x(i)x(i-1)*2sin(i);% 依赖上一步结果end% 每次迭代的输入由上次迭代结果决定whilenot_converged x_newupdate(x_old);% 迭代格式ifnorm(x_new-x_old)tolbreakendx_oldx_new;end% 需要中途终止的循环fori1:n resultcompute(i);ifisnan(result)||resultthresholdbreakendend核心判断数据处理用向量化迭代算法和递推用循环。