3.6 过程控制
过程控制用于控制程序的流程,如不同条件下执行的代码片段不同,常用的过程控制结构有如下几种。
3.6.1 if条件语句
对于简单的if 条件语句,可采用如下形式(如果条件表达式expression 为值,则执行statements语句)
if expression, statements, end
对于复杂的if条件语句,可采用下面的形式(更具有可读性)。如果表达式expression1为真,则执行statements1语句并结束判断。如果表达式expression1为假,则判断表达式expression2是否为真,如果为真,则执行statements2语句并结束判断;如果表达式expression2为假,以此类推,如果所有带if字样的分支都不满足,则执行else后面的语句statements3(如果有else的话)。
if expression1 statements1 elseif expression2 statements2 else statements3 end
程序示例:根据学生编号的奇偶平衡反应按键。
if mod(subid,2) %被试编号存储在变量subid中 correctKey=KbName('f'); %如果是奇数,正确按键为F键 else correctKey=KbName('j'); %否则,如是偶数,正确按键为J键 end
或者写成
if mod(subid,2),correctKey=KbName('f');else,correctKey=KbName('j');end
程序示例:根据IQ进行等级划分
if iq>=130 desc='超常'; elseif iq>=120 desc='优秀'; elseif iq>=110 desc='良好'; elseif iq>=100 desc='中上'; elseif iq>=90 desc='中等'; elseif iq>=70 desc='中下'; else desc='较差'; end
在上面的例子中,需要注意分界值应按一定顺序给出,否则可能会得不出正确结果。例如,下面代码中交换了分界值100和110的位置,当iq=115时,变量desc的值为“中上”。
if iq>=130 desc='超常'; elseif iq>=120 desc='优秀'; elseif iq>=100 desc='中上'; elseif iq>=110 desc='良好'; elseif iq>=90 desc='中等'; elseif iq>=70 desc='中下'; else desc='较差'; end
if条件语句还可以嵌套。假如,一个2×2实验设计,两个自变量的水平值分别用1和2来表示,我们通过if语句来设置需要呈现的图片名称(当然有更简单的方法实现),程序示例如下(其中v1和v2为两个自变量):
if v1==1 if v2==1 filename='f1.bmp'; else filename='f2.bmp'; end else if v2==1 filename='f3.bmp'; else filename='f4.bmp'; end end
上面语句也可以利用关系运算符改写为如下形式:
if v1==1 && v2==1 filename='f1.bmp'; elseif v1==1 && v2==2 filename='f2.bmp'; elseif v2==1 && v2==1 filename='f3.bmp'; else filename='f4.bmp'; end
3.6.2 switch条件语句
switch条件语句的结构如下:
switch switch_expr case case_expr statement1, ..., statement2 case {case_expr1, case_expr2, case_expr3, ...} statement3, ..., statement4 otherwise statement5, ..., statement6 end
根据表达式switch_expr的值转入对应的条件分支,即如果表达式switch_expr的值符合case_expr条件,则执行语句statement1, … statement2;如果符合case_expr1,case_expr2,case_expr3中任何一个条件,则执行语句statement3, …, statement4;当上述条件均不满足,并且有otherwise关键词时,则执行其后的语句statement5, …, statement6。在判断的过程中,按照case语句顺序,只要符合当前的case语句,则后面的case语句及otherwise语句均略过。
程序示例:根据月份字符判断季度
switch month_expr case {'Jan','Feb','Mar'} disp('First Season'); case {'Apr','May','Jun'}; disp('Second Season'); case {'Jul','Aug','Sep'}; disp('Third Season'); case {'Oct','Nov','Dec'}; disp('Fourth Season'); end
如果变量month_expr的值为“Jul”,则输出显示为:Third Season,可以在命令窗口中先对变量赋值,然后将上述代码粘贴至命令窗口中查看执行结果。
程序示例:假设一5点量表,根据其等级显示对应的文本描述
switch select case 1 option='完全不同意'; case 2 option='基本不同意'; case 3 option='中立'; case 4 option='基本同意'; case 5 option='完全同意'; otherwise option='未做选择'; end
3.6.3 for循环语句
for循环结构如下:
for index = values program statements : end
其中values可以取以下三种形式:
(1)initval:endval,initval代表初始值,endval代表结束值,中间用冒号(:)隔开;
(2)initval:step:endval,step代表步长,前一种形式每次递增值为1,此处可以指定每次递增值,如果为负值,则递减;
(3)valArray,循环按列遍历数组中的值。注意:使用break可以提前中止for循环。
程序示例:计算1~100的和
sums=0; for i=1:100 sums=sums+i; end disp(sums);
程序示例:计算1~100间所有奇数之和
sums=0; for i=1:2:100 sums=sums+i; end disp(sums);
程序示例:计算1~100间5的倍数之和
sums=0; for i=100:-5:1 sums=sums+i; end disp(sums);
程序示例:数组值累加
sums=0; for i=[27 34 18 19 52 25] sums=sums+i; end disp(sums);
程序示例:数组值累加
sums=0; a=rand(3,5) for i=a sums=sums+i; end disp(sums);
结果如下:
a = 0.7513 0.6991 0.5472 0.2575 0.8143 0.2551 0.8909 0.1386 0.8407 0.2435 0.5060 0.9593 0.1493 0.2543 0.9293 3.0694 2.3689 2.7981
程序示例:显示10以内的偶数
for i=1:10 if mod(i,2) continue; %如果是奇数,则跳过,如果for循环存在嵌套,使用continue语句作用于 包含该语句的内层循环 end disp(i); end
3.6.4 while循环语句
while循环结构如下,只要条件表达式成立,就执行中间的语句,直至条件表达式不成立,循环中间需要改变表达式的值或使用循环中断指令(break),否则将有可能限于死循环。
while expression program statements : end
程序示例:循环显示文件信息,文件命名规则为,主文件名后加1, 2, 3, …, n后缀,通过函数exist判断文件是否存在,如果存在,则利用函数imfinfo显示文件信息;如果不存在,则中止循环。
filename='a1.bmp'; index=1; while exist(filename,'file') imfinfo(filename) index=index+1; filename=['a' num2str(index) '.bmp']; end
程序示例:计算1~100的累加和
i=1; sums=0; while i<=100 sums=sums+i; i=i+1; end disp(sums);
程序示例:随机数累加,直至产生的随机数大于0.7
sums=0; while 1 a=rand if a>0.7 break; %如果产生的随机数大于0.7,则跳出while循环,与continue类似,如果存在 循环嵌套,则跳出包含该语句的内层的循环 end sums=sums+a; end disp(sums);
3.6.5 try错误控制语句
结构如下,在处理程序代码program statements部分时如果发生异常,则由error-handling statements处的程序代码来处理。
try program statements : catch exception error-handling statements : end
程序示例:当读取图片文件出错时,处理是否因文件扩展名使用有误所造成的。
function d_in = read_image(filename)(文件位于Psyfeng\Little_Examples目录下) [path name ext] = fileparts(filename); %将文件拆分为路径、前缀和后缀 try %尝试打开文件 fid = fopen(filename, 'r'); d_in = fread(fid); catch exception %如果文件打开失败 if ~exist(filename, 'file') %判断是否是因为未找到文件所致 % 尝试改变文件的扩展名 switch ext case '.jpg' % Change jpg to jpeg altFilename = strrep(filename, '.jpg', '.jpeg') case '.jpeg' % Change jpeg to jpg altFilename = strrep(filename, '.jpeg', '.jpg') case '.tif' % Change tif to tiff altFilename = strrep(filename, '.tif', '.tiff') case '.tiff' % Change tiff to tif altFilename = strrep(filename, '.tiff', '.tif') otherwise rethrow(exception); end %更改文件扩展名后再进一步尝试打开文件 try fid = fopen(altFilename, 'r'); d_in = fread(fid); catch %如果仍然无法打开文件,则抛出异常,由系统来处理 rethrow(exception) end else %如果文件存在,但无法打开 d_in=-1; return; %return语句可以提前返回(中止)某脚本或函数,其后的语句不管有多少均不再执行 end end