目录
控制流 | 运算符 |
if, elseif, else | < |
for | <= |
switch, case | > |
try, catch | >= |
while | == |
break | ~=(不等) |
continue | &&(与) |
pause | ||(或) |
return |
1.if, elseif, else
伪代码:
if condition1
statement1elseif condition2
statement2else
statement3end
示例1:
a = 3;
if rem(a, 2) == 0
disp('a 是偶数')
else
disp('a 是奇数')
end
结果:
>> demo_02
a 是奇数
关于rem、mod
rem | r = rem(a,b) 返回 a 除以 b 后的余数,其中 a 是被除数,b 是除数,表达式为 r = a - b.*fix(a./b) |
mod | b = mod(a,m) 返回 a 除以 m 后的余数,其中 a 是被除数,m 是除数,表达式为 b = a - m.*floor(a./m) |
关于fix和floor和ceil
fix | 向零舍入:在坐标轴上fix的时候,正负半轴的数都指向0点即:
|
floor | 向负无穷舍入 |
ceil | 向正无穷舍入 |
示例2:
>> X = [-1.9 -3.4; 1.6 2.5; -4.5 4.5]
X =
-1.9000 -3.4000
1.6000 2.5000
-4.5000 4.5000
>> fix(X) % -1.9向0舍入的话离0最近的整数就是-1,2.5向0舍入离0最近的是2
ans =
-1 -3
1 2
-4 4
>> floor(X) % 向下取整,往x轴负方向取
ans =
-2 -4
1 2
-5 4
>> ceil(X) % 向上取整,往x轴正方向取
ans =
-1 -3
2 3
-4 5
rem和mod返回的都是余数,这两个有什么区别呢?如果不想看下面的解释,可以直接带公式计算,简单粗暴。
>>% 关于mod和rem的区别,当除数与被除数符号一样的时候,两者结果是一样的。
>>% 先说mod,不管被除数(也就是5)是正还是负,余数的符号只与除数的符号一致
>> mod(5, 2) % 除数(2)为正,所以不管被除数(5)是正还是负那么结果都是和除数(2)符号一致
ans =
1
>> mod(-5, 2) % 推导:ans = -5 - 2.*floor(-5 ./ 2),其中floor(-5 ./ 2)是想下取整,即-2.5向下取整是-3,ans = -5 - 2.*(-3) = -5 + 6 = 1
ans =
1
>> mod(5, -2) % 除数(-2)为负,所以不管被除数(5)是正还是负那么结果都是和除数(-2)符号一致 % 推导:ans = 5 - (-2).*floor(5 ./ -2),其中floor(5 ./ -2)是想下取整,即-2.5向下取整是-3,ans = 5 - (-2).*(-3) = 5 - 6 = -1
ans =
-1
>> mod(-5, -2) % 推导:ans = -5 - (-2).*floor(-5 ./ -2),其中floor(-5 ./ -2)是想下取整,即2.5向下取整是2,ans = -5 - (-2).*2 = -5 + 4 = -1
ans =
-1
>>% 再说rem,不管除数(也就是2)是正还是负,余数的符号只与被除数(5)的符号一致
>> rem(5, 2) % 被除数(5)为正,所以不管除数(2)是正还是负那么结果都是和被除数(5)符号一致
ans =
1
>> rem(5, -2) % 不做推导
ans =
1
>> rem(-5, 2) % 被除数(-5)为负,所以不管除数(2)是正还是负那么结果都是和被除数(-5)符号一致
ans =
-1
>> rem(-5, -2) % 不做推导
ans =
-1
2.switch case
伪代码:
switch expression
case value1
statement1case value2
statement2
otherwise
statementend
示例:input_num可自行填入。后面再讲input
input_num = 1;
switch input_num
case -1
disp('不是1');
case 0
disp('是0');
case 1
disp('是1');
otherwise
disp('其它值');
end
结果:
>> demo_03
是1
3.while
伪代码:
while expression
statementend
示例1:
n = 1;
while prod(1:n) < 1e100 % 1*2*3*...*n = n!(n的阶乘) 1e100 = 1×10^100
n = n + 1;
%disp(n); % 把每次的结果都输出
end
disp(n); % 只显示最后一条结果
结果:
>> demo_04
70
prod: 数组元素的乘积 |
|
示例2:
>> prod(1:3:7) % 数组中的所有元素,1 4 7相乘
ans =
28
>> A=[1:3:7;2:3:8;3:3:9]
A =
1 4 7
2 5 8
3 6 9
>> B = prod(A) % 按照列相乘,行展示
B =
6 120 504
>> C = prod(A, 2)
C =
28
80
162
练习:从1一直加到999-->1+2+3+...+999
while写法:
n = 1;
sum = 0;
while n <= 999
sum = sum + n;
n = n + 1;
end
disp(n)
disp(sum)
>> demo_05 % 结果
1000
499500
for写法:
sum = 0;
for i=1:999
sum = sum + i;
end
disp(sum);
>> demo_10 % 结果
499500
4.for
伪代码:
for variable=start : increment : end
commands
end
示例1:
for n = 1:10
a(n) = 2^n;
end
disp(a);
结果:
>> demo_06
2 4 8 16 32 64 128 256 512 1024
简单变形:分别输出2的奇数位次方和偶数次方
示例2:
for n = 1:10
if mod(n, 2) == 0
b(n) = 2^n;
else
a(n) = 2^n;
end
end
disp('偶数位');
disp(b);
disp('奇数位');
disp(a);
结果:
>> demo_06
偶数位
0 4 0 16 0 64 0 256 0 1024
奇数位
2 0 8 0 32 0 128 0 512
会发现上述结果虽然都输出了正确的答案,但是多了很多0,怎么只显示我们想要的结果呢?方法很简单,只需要改对应的n就行。
方法一:
for n = 1:10
if mod(n, 2) == 0
b(n) = 2^n;
else
a(n) = 2^n;
end
end
disp('偶数位');
disp(b(2:2:10)) % 显示对应偶数位置上的
disp('奇数位');
disp(a(1:2:10)) % 显示对应奇数位置上的
结果:
>> demo_06
偶数位
4 16 64 256 1024
奇数位
2 8 32 128 512
方法二:
for n = 1:10
if mod(n, 2) == 0
b(n/2) = 2^n; % 在存放的时候直接存放偶数位置上
else
a((n+1)/2) = 2^n; % 在存放的时候直接存放奇数位置上
end
end
disp('偶数位');
disp(b);
disp('奇数位');
disp(a);
结果:
>> demo_06
偶数位
4 16 64 256 1024
奇数位
2 8 32 128 512
在本节一开始:a(n) = 2^n这里,a是没有提前声明的,可以看成是一个vector没有固定大小,你存多少到a里面它就会是多少,这样有一个坏话就是,每次存进a中的时候,系统会为a分配相应的内存,这样无疑会降低性能。接下来看看提前声明,和不声明的时间大小。
示例:
%%
tic
%for n = 1:1000000 % 如果这里的注释取掉的话单独运行,系统会显示正忙,这时候在命令窗口按Ctrl + c会直接终止此次运行
%未提前声明
for ii = 1:2000
for jj = 1:2000
A(ii, jj) = ii + jj;
end
end
%end
toc
%%
tic
%提前声明
A = zeros(2000, 2000);
for ii = 1:2000
for jj = 1:2000
A(ii, jj) = ii + jj;
end
end
toc
结果:
>> demo_07 % 显而易见,提前声明的效率更高
历时 3.430534 秒。
历时 0.019535 秒。
练习:用for循环将A矩阵的所有元素都变成0,如果按照第一节索引的方式会很慢。
示例:
A = [0 -1 4;9 -14 35; -34 49 64];
for i = 1:size(A, 1) % 此时A是一个3×3的矩阵size(A, 1)表示第1个维度即行
for j = 1:size(A, 2) % 此时A是一个3×3的矩阵size(A, 2)表示第2个维度即列
A(i, j) = 0;
end
end
disp(A);
结果:
>> demo_08
0 0 0
0 0 0
0 0 0
5.break终止for和while最近一层循环
示例:
while 1 % 此时只会打印外循环
disp('外循环');
while 1
break;
disp('内循环');
end
end
%%
while 1 % 此时不会打印任何直接终止外循环
break;
disp('外循环');
while 1
disp('内循环');
end
end
for循环同理,不再演示。
6.continue 跳过当前执行条件,继续迭代
示例:
for i = 1:3
if i == 1
continue; % i=1的话直接跳过1这次执行,会转向i=2开始继续执行
end
disp(i);
end
结果:
>> demo_09
2
3
7.一些简单使用的指令
clear all | 清除所有的变量 |
close all | 清楚所有的figure |
... | 三个点换行 |
Ctrl + c | 终止指令,见for循环那一小节 |
edit | 如果要找某一个写好的.m文件 命令:edit(which('demo_01.m'))这里以我写的demo_01.m为例。 |
换行符...
A = [1 2 3;...
3 4 5;...
3 4 5]
>> demo_09
A =
1 2 3
3 4 5
3 4 5
8.function
例:function y = mean(x)
function是关键字,y是输出,x是输入,mean()是function的名字和你的file名一样。如果我们想直接盗用mean,前提是要有function这个关键字,要不然调用不了。算出来mean的结果之后保存在y中输出。
示例1:
function x = freebody(x0, v0, t) % 保存在freebody.m文件中
x = x0 + v0.*t + 1/2*9.8*t.*t;%.*是元素之间的乘法,数的乘法用*,注意区分
结果:
>> freebody(0, 0, 10) % 在命令行中键入
ans =
490
>> freebody([0 1], [0 1], [10 20]) % 这里第组参数是0 0 10 第二组是1 1 20如果function中不是点乘的话会报错。注意区分点乘和乘
ans =
490 1981
示例2:
function [a, F] = acc(v2, v1, t2, t1,m) % 建议用","隔开两个变量,保存为acc.m文件
a = (v2 - v1)./(t2 - t1);
F = m.*a;
结果:
>> [a, F] = acc(10, 5, 2, 1, 3) % 在命令行中键入 当然你把a, F换成其他字符也行,但是不建议。建议和function中的变量保持一致
a =
5
F =
15
>> acc(10, 5, 2, 1, 3) % 如果没有写输出的两个变量默认输出第一个
ans =
5
练习:华氏温度和摄氏温度的转换。如果用户没输入则停止此程序。
可能涉及input, isempty, break, disp, num2str等相关函数
摄氏温度C ,将其转化为华氏温度F,转换公式为:F = C*9/5 + 32, C = (F - 32)*5/9
示例(仅供参考,每个人的写法不一样):
while 1
prompt = "请输入摄氏温度C:";
C = input(prompt);
if isempty(C)
break;
else
F = C*1.8 + 32;
data = ['转换后的华氏温度是:' num2str(F) 'F'];
disp(data);
%disp("转换后的华氏温度是:" + num2str(F) + "F"); % 这种打印也可
end
end
结果:
>> C2F
请输入摄氏温度C:34
转换后的华氏温度是:93.2F
请输入摄氏温度C:56
转换后的华氏温度是:132.8F
请输入摄氏温度C:67
转换后的华氏温度是:152.6F
请输入摄氏温度C:23
转换后的华氏温度是:73.4F
请输入摄氏温度C:
>>
9.Function Default Variables
inputname | 函数输入的变量名称 |
mfilename | 当前正在运行的代码的文件名 |
nargin | 函数输入参数数目 |
nargout | 函数输出参数数目 |
varargin | 可变长度输入参数列表 |
varargout | 可变长度的输出参数列表 |
示例:
function [volume]=pillar(Do,Di,height)
if nargin==2 % 本来pillar的参数是Do Di height 这3个,当我们命令行输出参数的时候如果是两个的时候那么height的值默认是1
height=1;
end
disp("height = " + num2str(height)); % 我在这里加了一行来验证当输入的参数是两个的时候height的值
volume=abs(Do.^2-Di.^2).*height*pi/4;
结果:
>> volume = pillar(1, 2) % 当我们输入两个参数时height默认是1
height = 1
volume =
2.3562
>> volume = pillar(1, 2, 3) % 当输入的是3个的时候第三个参数就是height的值
height = 3
volume =
7.0686
>> volume = pillar(1) % 输入参数不满足会报错,读者可以自行尝试nargin的值
输入参数的数目不足。
出错 pillar (第 5 行)
disp("height = " + num2str(height));
10.Function Handles
示例:
f = @(x) exp(-2*x); % @x对应exp(-2*x)中的x变量, f就是exp(-2*x)的输出
x = 0:0.1:2; % x = 0 0.1 0.2 0.3 ... 2
plot(x, f(x)); % 依次画出 当x = 0时,f(x) = exp(-2*0) 一次类推
OVER