《Matlab学习》【2】结构化编程和自定义函数、循环语句、循环分支

目录

1.if, elseif, else

2.switch case

3.while

4.for

5.break终止for和while最近一层循环

6.continue 跳过当前执行条件,继续迭代

7.一些简单使用的指令

8.function

9.Function Default Variables

10.Function Handles


控制流运算符
if, elseif, else<
for<=
switch, case>
try, catch>=
while==
break~=(不等)
continue&&(与)
pause||(或)
return

1.if, elseif, else

伪代码:

if condition1
        statement1

elseif condition2
        statement2

else
        statement3

end

示例1:

a = 3;
if rem(a, 2) == 0
    disp('a 是偶数')
else
    disp('a 是奇数')
end

 结果:

>> demo_02
a 是奇数

关于rem、mod

remr = rem(a,b) 返回 a 除以 b 后的余数,其中 a 是被除数,b 是除数,表达式为 r = a - b.*fix(a./b)
modb = mod(a,m) 返回 a 除以 m 后的余数,其中 a 是被除数,m 是除数,表达式为 b = a - m.*floor(a./m)

关于fix和floor和ceil

fix

向零舍入:在坐标轴上fix的时候,正负半轴的数都指向0点即:

  • 对于正数,fix 的行为与 floor 相同。
  • 对于负数,fix 的行为与 ceil 相同。

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
        statement1

case value2
        statement2
otherwise
        statement

end

示例: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
        statement

end

示例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:

数组元素的乘积

B = prod(A,'all') 计算 A 的所有元素的乘积。18以上的版本适用

B = prod(A,dim) 返回沿维度 dim 的乘积。就是每一行相乘最后所有的行结果按照列表示出来

示例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

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HenceDang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值