当需要执行一段代码多次时可以使用循环语句。 一般来说,语句是按顺序执行的。首先执行函数中的第一个语句,然后执行第二个语句,依此类推。
编程语言提供了允许更复杂的执行路径的各种控制结构。
循环语句允许多次执行一个语句或一组语句,以下是大多数编程语言中循环语句的一般形式 -
目录
循环结构—— while语句
课前调研:C/Java/Python语言的while语句有何特点?
当需要执行一段代码多次时可以使用循环语句。 一般来说,语句是按顺序执行的。首先执行函数中的第一个语句,然后执行第二个语句,依此类推。
编程语言提供了允许更复杂的执行路径的各种控制结构。
循环语句允许多次执行一个语句或一组语句,以下是大多数编程语言中循环语句的一般形式 -
while循环在条件为真(true)时重复执行语句。
MATLAB中while循环的语法是
while <expression>
<statements>
end
只要表达式(expression)为true,while循环将重复执行程序语句(statements)。
当结果为非空并且包含所有非零元素(逻辑或实数)时,表达式(expression)为true。 否则,表达式(expression)为false。
a = 10;
while ( a < 20 )
fprintf('value of a: %d\n', a);
a = a + 1;
end
执行上面示例代码,得到以下结果 -
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
value of a: 16
value of a: 17
value of a: 18
value of a: 19
练习:调和级数为全体自然数倒数和:
是一个发散的级数,即随着n趋于无穷大,其和s的值也是无穷大。那么请问,这个级数的前多少项之和刚刚大于3?
n=1;
s=0;
while s<3
s=s+1/n
n=n+1
end
(2)while循环的嵌套
语法:
while <expression1>
while <expression2>
<statements>
end
end
例:把数组s=rand(5,6)的元素,从左到右按行/从上到下按列 逐个打印输出。
s=rand(5,6)
x=1
y=1
while x<=5
while y<=6
disp(s(x,y))
y=y+1;
end
y=1;
x=x+1;
end
想一下,如果反过来:从最后一个元素开始,反向输出各个元素,程序该怎么改?
课堂抢答:
找出矩阵a=randi([1,300],[10,10]) 中所有可以被3或被7整除的数。
方法1:
a = randi([1,300],[10,10]) %生成10*10的整数矩阵a,整数范围1-300
y = ( mod(a,3)==0 | mod(a,7)==0 )
z = a(y) %数组z存储了所有满足条件的元素
numel(z) %显示数组z的元素数量
方法2:
a=randi([1,300],[10,10])
[M,N]=size(a) %用size()函数得到矩阵a的总行数M,总列数N
m=1; %用m记录当前行,初始化为1
n=1; %用n记录当前列,初始化为1
num=0; %用num来记录找到的符合要求的元素的总数量,初始为0
while m<=M %如果当前行数没有超出行的范围,则一直循环
while n<=N %如果当前列数没有超出列的范围,则一直循环
if mod(a(m,n),3)==0|mod(a(m,n),7)==0
fprintf('%d 可以被3或者7整除 \n',a(m,n))
num=num+1;
end
n=n+1; %往前挪一列
end
n=1; %开始新一行的话,列数从1开始
m=m+1; %往前挪一行
end
num %显示符合条件的元素数量
break语句用来强制终止for或while循环的执行,既跳出当前的循环。 在循环中break语句之后出现的语句不执行。在嵌套循环中,break仅从它所在的循环中退出。控制传递到该循环结束后的语句。
例子
a = 10;
while (a < 20 )
fprintf('value of a: %d\n', a);
a = a+1;
if ( a > 15)
% terminate the loop using break statement
break;
end
end
执行上面示例代码,得到以下输出结果 -
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
例子:
1)写一个温度以华氏度(F)为单位的程序,数值由用户提供
2)以摄氏度(C)计算等效温度,并以摄氏度显示温度
3)函数应该一直运行,直到没有提供要转换的数字
while 1
F = input ('Temperature in F = ');
if isempty(F)
break;
else
C= (F - 32) * 5 / 9;
fprintf('Temperature in C = %3.2f \n',C)
end
end
continue语句用于将控件传递给for循环或while循环的下一个迭代。
在MATLAB中的continue语句有点像break语句。 然而,“continue”不是终止整个循环,而是终止本次迭代,即本次迭代在“continue”这个关键词之后的语句都将被忽略,程序直接跳入到下一次迭代。
a = 9;
while a < 20
a = a + 1;
if a == 15
% skip the iteration
continue;
end
fprintf('value of a: %d\n', a);
end
执行上面示例代码,得到以下结果 -
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 16
value of a: 17
value of a: 18
value of a: 19
value of a: 20
如何修改上面的代码,使得a只有为奇数时才打印输出?
a = 3;
while a < 20
a = a + 1;
if rem(a,2)==1
fprintf('value of a: %d\n', a);
end
end
课堂实操:用while循环求解.
(1)求和:s=1+2+3+......+100
s=0;
k=1;
while k<101
s=s+k;
k=k+1;
end
s
向量化编程:
x=1:100;
s=sum(x)
(2)求和:S=1*2*3+2*3*4+………+50*51*52
s=0;
k=1;
while k<=50
s=s+k*(k+1)*(k+2);
k=k+1;
end
s
向量化编程:
x1=1:50;
x2=2:51;
x3=3:52;
x=x1.*x2.*x3;
s=sum(x)
(3)求和:
方法1:
clear
x=1; %每一项自变量x的值,初始化为1
s=0; %和s,初始化为0
flag=1; %用flag记录正负号,初始化为+1
while x<100
s = s + flag*x^2;
flag = -1*flag; %正负号翻转
x = x+2; %自变量x加2
end
s
方法2:
clear
x=1;
s=0;
n=0;
while x<100
s=s+(-1)^n*x^2; %通过(-1)^n来交替改变正负号
n=n+1;
x=x+2;
end
s
方法3:向量化编程1
clear
x1=1:4:97
x2=3:4:99
y1 = x1.^2;
y2 = x2.^2;
sum(y1)-sum(y2)
方法4:向量化编程2
clear
x=1:2:99
y=x.^2
flag=repmat([1,-1],1,25)
z=y.*flag
sum(z)
(4)三角形合理性判断
要求:判断输入的三角形边长是否合理,不合理则要求重新输入,合理则返回三角形的边长之和。
clear
while 1
a = input ('请输入三角形第1个边长 a = ');
b = input ('请输入三角形第2个边长 b = ');
c = input ('请输入三角形第3个边长 c = ');
if (a+b)>c&(a+c)>b&(b+c)>a
fprintf('这是一个合理的三角形,边长之和为%f \n',a+b+c)
break
else
fprintf('输入的三个边长构不成三角形,请重新输入 \n')
end
end
(5)利用如下公式求圆周率,如果要精确到小数点后3位,需要算多少项?
此时算出的圆周率为多少?
clear
s=0; %pi/4的初始值
mypi= 0; %pi的初始值
n=1; %需要算的项数
flag=1; %每一项的正负号标识
while abs( mypi-pi)>0.0005 %为什么要写成0.0005?
s= s+ flag/(2*n-1); % 第n项的分母为(2*n-1)
mypi= s*4; %s*4得出计算的圆周率
flag= flag*(-1); %正负号标识反转
n=n+1 ; %项数加1
end
n
mypi
向量化编程:
x1=repmat([1,-1],1,500);
x2=1:2:1999;
x=x1./x2;
mypi=sum(x)*4
课后作业: =======================
作业1:制作一个成绩计算程序。
(1)第1步,用input函数,让对方依次输入任意两个0-100之间的数,分别赋给变量X_ps和 X_qm。 其中变量X_ps, X_qm分别表示平时分和期末卷面分,S_zf表示总分。要求判断输入的X_ps和 X_qm是否在0-100之间,如果不在,则输出警告,并要求对方重新输入正确的数值.....直到满足两个数都在0-100之间。
(2)第2步,根据上一步得到的平时分和期末分,计算总分S_zf,公式如下:
(3)第3步,采用if或者 switch语句执行以下动作:
当总分S_zf在90-100这个区间时,输出:您的平时分为:*** 卷面分为:*** 总分为:*** 成绩优秀。
当总分S_zf在70-89.9这个区间时,输出:您的平时分为:*** 卷面分为:*** 总分为:*** 成绩良好。
当总分S_zf在60-69.9这个区间时,输出:您的平时分为:*** 卷面分为:*** 总分为:*** 成绩及格。
当总分S_zf在0-59.9这个区间时,输出: 您的平时分为:*** 卷面分为:*** 总分为:*** 等着补考吧。
(提示:需要用到while循环、 if或者 switch分支,fprintf格式输出,数值的大于、小于、与或非等逻辑判断语句。)
作业2:计算三角形面积
创建一个计算三角形面积的脚本文件。运行此脚本时,用input函数要求对方输入三角形的三个边长,然后输出三角形面积。要求判断输入的三个边长是否满足三角形的基本要求(三角形总是满足任意两边和大于第三边),不满足则要求重新输入。
作业3:对数组x=randi([1,99],5,20),按行查找,把每一行第一个能被7整除的数找出来,输出该数,然后停止查找该行,进入下一行继续查找。
提示:需要用到双重的嵌套(while或for)循环,以及break语句等。。
作业4:用while循环求解e的值。
任务1:编程计算e的值,要求当最后一项的值1/n!<0.000001时结束计算,并输出此时算出的e值(用vpa函数显示e的精确值)。
任务2 : 如果要计算出e的小数点后10的精确值,如要算到多少项目?
提示1:如果要求计算出的e的值精确到小数点后10位,则其和真实的exp(1)之间的差要小于0.0000000001.
提示2,编程时可能会用到阶乘,MATLAB里阶乘的函数为 factorial( )
当n>=1时,factorial(n) 等价于 prod([1:n])
如12的阶乘:
factorial(12) % 12的阶乘已经很大了
ans =
479001600
课外能力拓展: 力扣网(https://leetcode.cn/)练习题
第69题. 二分查找法求x 的平方根
链接:https://leetcode-cn.com/problems/sqrtx/solution/x-de-ping-fang-gen-by-leetcode-solution/
要求:实现 int sqrt(int x) 函数的功能。即,计算并返回 x 的平方根,其中 x 是非负整数。由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4 输出: 2
示例 2:
输入: 8 输出: 2 说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
clear
y=2 %即将开方求解的数
x1=0; %假设解的区间的下限为x1
x2=y; %假设解的区间的上限为x2
s=(x1+x2)/2; %假设解在上下限中间
while abs(s^2-y)>=0.0001 %如果解的误差大于0.0001,则一直循环
if (s^2-y)>0 %如果解偏大
x2=s; %把解区间的上限下移到s
s=(x1+x2)/2; %新的解在新区间的中间
end
if (s^2-y)<=0 %如果解偏小
x1=s; %把解区间的下限上移到s
s=(x1+x2)/2; %新的解在新区间的中间
end
end
vpa(s,6)