1
הוראות בקרה – control statements
נבחין בין שני סוגי הוראות בקרה:
הוראות "בחירה" - באמצעותן בוחרים אחת, מבין כמה קבוצות של הוראות, כדי לבצע אותה.
ב Matlab, קיימות שתי הוראות מסוג זה : if ,ו- switch. לכל אחת מהן צמודות אחת או יותר קבוצות של הוראות, ומנגנון לבחירת אחת מהן לביצוע.
לולאות - אלה הוראות בקרה שמאפשרות חזרה על קבוצה אחת של הוראות, מספר מבוקר של פעמים. ההוראות שאמונות על סוג זה של בקרה הן הלולאות for, while. השוני ביניהן הוא באופן הבקרה על הלולאה.
Conditional Control בקרה על פי תנאי, ההוראה if
התצורה הפשוטה ביותר של ההוראה if, שכוללת ביטוי- שמשמש כתנאי - וקבוצת פקודות. אם ערך הביטוי הוא true, אזי מתבצעות הפקודות statements :
if expression
statements
end
מילת המפתח end מסיימת את ההוראה, ומן הסתם גם "סוגרת" את קבוצת הפקודות.
תנאי לוגי יכול להיות "פשוט" כגון:
(a>7)
או מורכב יותר, שמכיל קשרים לוגים (logical connectives), כמו :
(a>7 && b*a~=12)
ב Matlab גם ביטוי מספרי יכול לשמש כתנאי: ערך שונה מאפס יחשב כ-true (1), ואפס יחשב כ- false, (0). דוגמאות:
if (x>y)
tmp=y;
y=x;
x=tmp;
end
או:
if(fix(a/7))
a=a+1;
b=a*pi;
end
(fix(a) מעגלת את a אל השלם הקרוב בכיוון ה- 0)
מילת המפתח else
ל - if יש מספר תצורות. תצורה נוספת כוללת תנאי ושתי קבוצות של פקודות. אם ערך התנאי הוא true, מתבצעת הקבוצה הראשונה, ואם false, השנייה. מילת המפתח else מפרידה בין שתי הקבוצות :
if expression
statements1
else
statements2
end
כאן מנצלים את שני הערכים האפשריים של התנאי, ולא רק את ה- true.
דוגמא:
a=12;
b=sin(35);
if (a/b>pi)
c=2*pi;
d=cos(12*c-a);
b=b^2;
else
c=pi/4;
d=tan(10*c-b);
end
disp(c)
disp(d)
תצורה נוספת עם מילת המפתח elseif משמשת להפרדה בין הקבוצות, וכדי "למקם" את התנאים הללו. נראה מבנה עם שלושה תנאים לוגיים וארבעה קבוצות של פקודות:
if expression1
statements1
elseif expression2
statements2
elseif expression3
statements3
else
statements4
end
דוגמא:
a=12;
b=sin(35);
if (a/b>pi)
c=2*pi;
d=cos(12*c-a);
b=b^2;
elseif(a/b+1>pi)
c=2.1*pi;
d=cos(12.5*c-a);
b=b^3;
elseif(a/b+1.5>pi)
c=2.3*pi;
d=cos(13.5*c-a);
b=b^3.2;
else
c=2.5*pi;
d=cos(14.5*c-a);
b=b^3.5;
end
disp(c)
disp(d)
disp(b)
ניתן לכונן (nesting)מספר כלשהו של הוראות if. דוגמא:
if (a>b)
c=a-b;
if (c/a<2)
c=c+2;
end
else
if(a>b+1)
c=2*a-b/3;
else
c=3*b+a/2;
end
end
לנוחות העבודה בחלון הפקודות : את הוראת ה- if ניתן גם לרשום בשורה אחת, אם נפריד בין הרכיבים שלה על ידי פסיקים או semicolons. למשל, במקום לרשום כך :
>> if(pi>1)
disp(1)
i=5;
disp(3)
end
נוכל לרשום את אותה הוראה בשורה אחת:
>> if(pi>1), disp(1), i=5; disp(3), end
1
3
כזכור, הוספת סימן ה semicolon אחרי פקודה מונע את הדפסת התוצאה שלה.
אם ערך ביטוי התנאי של ההוראה הוא מבנה, הוא יחשב ל true, רק אם כל אבריו שונים מאפס. למשל נניח ש A הינה מטריצה. אזי המבנה :
if A
statements
end
שקול למבנה :
if all(A(:))
statements
end
אם ערך ביטוי התנאי הוא מטריצה ריקה, אזי זו נחשבת ל false. דוגמא:
>> if([])
disp(1)
else
disp(2)
end
2
חומר למחשבה:
התנאים יכולים גם להיות בין מבנים, נראה מקרה מעניין שבו מבצעים פעולת OR בין שני וקטורים באורכים שונים, וזה עובד ! :
>> a
a =
1 2 3 4
>> d
d =
1 2 3 4 5 6
>> if(a|d),disp(1),else, disp(0),end
1
גם זה יעבוד:
d =
1 0 0 0 0 0
>> if(a|d),disp(1),else, disp(0),end
1
אבל אם נחליף מקומות בין אותם a ל- d בביטוי הלוגי, זה כבר לא יעבוד:
>> if(d|a),disp(1),else, disp(0),end
??? Error using ==> or
Inputs must have the same size.
ומה עם הOR המקוצר, "||" על אותם וקטורים ?
>> if(a||d),disp(1),else, disp(0),end
??? Operands to the || and && operators must be convertible to logical scalar values.
המקוצר אינו עובד.
כעת נבדוק את ה AND הרגיל :
>> b=[1 2 3 4 5];
>> c=[1 1 1];
>> if(c&b),disp(1),else, disp(0),end
??? Error using ==> and
Inputs must have the same size.
ולגבי AND מקוצר מקבלים הערה אחרת:
>> if(c&&b),disp(1),else, disp(0),end
??? Operands to the || and && operators must be convertible to logical scalar values.
כל הדברים הללו נכונים גם עבור הלולאה while בהמשך.
expression Control - בקרה על פי ערכים של ביטוי, ההוראה switch
בחירת הקבוצה נעשית לפי ערך של ביטוי אחד. המבנה הכללי של ההוראה הוא:
switch switch_expression
case case_expression1
statement, ..., statement
…
case {case_expression i,…, case_expression j}
statement, ..., statement
…
otherwise
statement, ..., statement
end
הביטוי switch_expression יכול להיות סקלר, או מחרוזת.
באמצעות מילת המפתח case, "מצמידים" לכל קבוצת פקודות, ערך אחד, או כמה ערכים אפשריים של ה - switch_expression. ערכים אלה מופיעים במבנה הקודם כ:
case_expressioni,… case_expressionj,…
הקבוצה שתתבצע היא זו "שצמודה" לערך שהתקבל בחישוב הביטוי switch_expression.
למשל, כדי שקבוצת הפקודות k תתבצע , אזי :
- אם תוצאת הביטוי היא סקלר, חייב להתקיים:
switch_expression==case_expressionk
- ואם התוצאה היא מחרוזת, הפונקציה הבאה חייבת להחזיר true (logical 1):
strcmp(switch_expression, case_expressionk)
אם ערך הביטוי switch_expression, אינו נמצא באף case, תתבצע קבוצת הפקודות שמופיעה אחרי מילת המפתח otherwise, אם יש כזאת. השימוש ב- otherwiseהוא אופציונאלי.
דוגמא, נשמור את ה switch הבא בקובץ script בשם sw, ואחר כך נפעיל את ה script:
switch (x)
case {1,2}
disp('2 elements vec'),[1 2].^x
case 3
disp('3 elements vec'),[1 2 3].^x
case 4
disp('4 elements vec'),[1 2 3 4].^x
otherwise
disp('rand answer'),rand(1,5).^x
end
אם נפעיל את sw על קלטים שונים, נקבל:
>> x=1;
>> sw
2 elements vec
ans =
1 2
>> x=2;
>> sw
2 elements vec
ans =
1 4
>> x=4;
>> sw
4 elements vec
ans =
1 16 81 256
>> x=6;
>> sw
rand answer
ans =
0.2925 0.5523 0.0000 0.5806 0.0639
בקרת לולאות – for,while,continue,break
הלולאה for
המבנה הכללי של ההוראה for הוא :
for index = index_range
statements
end
כאשר index הוא משתנה הלולאה, ו- index_range טווח הערכים שלו.
נבחין בין מספר תצורות: נראה תחילה מקרה שבו index הוא סקלר ו index_range הוא וקטור y בעל n איברים:
for index = y % y vector of n members
statements
end
הלולאה הזאת תתבצע n פעמים, הערך ההתחלתי של index יהיה y(1), אחריו y(2), וכו". הערך האחרון הוא y(n). נראה דוגמא עם וקטור כלשהו :
for index = [2 4 -1 21]
v(index +2)=index *v(index +4);
end
כאן המשתנה index יקבל לפי הסדר, את ערכו של כל אחד מאברי וקטור-הטווח.
את וקטור הטווח אפשר להגדיר גם על ידי אופרטור ה colon :
for index = start:increment:end
statements
end
index הוא משתנה הלולאה, וindex_range- הוא וקטור "חצי אוטומטי".
דוגמא :
for ind = 3:2:8
v(ind) = v(ind - 1)/2;
u(ind)= u(ind-1)-5;
end
כאן ind קיבל את הערכים : 3,5,7.
for ind = 8:-2:-1
v(ind+1) = 2.5 * v(ind+2);
u(ind+1)= u(ind+2)-5;
end
וכאן הוא קיבל את הערכים 8,6,4,2,0.
אם מעוניינים בגישה לוקטור הלולאה , יש להגדירם ולשמור אותם במשתנה לפני כניסה ללולאה:
>> k=11:-6:-8;
>> for i=k,disp(i),end
11
5
-1
-7
נחזור למבנה הכללי:
for index = index_range
statements
end
כאשר ה- index_range הוא מטריצה ,A nxm, ה index יהיה בכל איטרציה וקטור עמודה אחר של A .הלולאה הזאת תתבצע m פעמים - כמספר עמודות A.
לולאות for מכוננות nested for loops-
ניתן לכונן שתים או יותר לולאות for אחת בתוך השנייה:
for i = [5 1 11 4 2]
for j = [3 1 4 2]
B(i, j) = 1/(i^j)-1/(j^i);
end
end
הלולאה while
הלולאה while חוזרת ומבצעת קבוצת פקודות, כל עוד ערך ביטוי התנאי שלה, הוא true.
while while_expression
statements
end
אם ערך הביטוי הוא מטריצה, אזי כדי שהלולאה תמשיך, כל אברי המטריצה חייבים להיות שווים ל- 1.
דוגמא מאד לא יעילה: עבור איזה n, סכום אברי הוקטור 1:n, עובר את ה- 1000:
n = 1;
while sum(1:n) < 1000
n = n + 1;
end
n-1
הדוגמא לא יעילה מכיוון שבכל איטרציה מחשבים שוב את הסכום מהתחלה, במקום להשתמש בסכום הקודם.
גם לולאות while ניתנות לכינון. דוגמא:
while (a>7)
disp(a)
a=a+1;
b=b-1;
while(a>b)
disp(b)
b=b+1;
a=a-1;
end
end
ניתן לכתוב לולאת while על שורה אחת, אם משתמשים בפסיקים וב semicolons-:
>> i=0;
>> while(i<pi),disp(i),disp(2*i),i=i+1.5;end
0
0
1.5000
3
3
6
לולאת while מפסיקה כאשר ערך ביטוי התנאי שלה הוא false, או אפס, או מטריצה ריקה.
ההוראות continue, break
ההוראה break מפסיקה ביצוע של הלולאה שהיא כלולה בה. דוגמא:
while (a>9)
disp(a)
a=a+1;
b=b-1;
while(a>b)
disp(b)
b=b+1;
a=a-1;
if(a==b)
break;
end
end
end
ההוראה continue מפסיקה את האיטרציה הנוכחית שלה, וחוזרת לשורת הבקרה של הלולאה. דוגמא:
for ind=[6 3 5 2 3 1]
disp(ind+a-b)
a=a+1;
b=b-1;
for ind1=[1 3 2 4 3 5]
disp(ind1-b+a)
b=b+1;
a=a-1;
if(ind==ind1-a)
continue;
end
end
end
continue בתוך לולאה מכוננת, מפסיקה רק את האיטרציה של הלולאה שהיא כתובה בה.
הפקודות if ו-switch אינן לולאות, ולכן לא break , ולא continue יעבדו בתוכן, אלא אם אלה ימצאו בתוך לולאה:
>> if(a>3),disp(a),else,break,end
??? Error: A BREAK statement appeared outside of a loop. Use RETURN instead.
>> switch(3),case 2,break,end
??? Error: A BREAK statement appeared outside of a loop. Use RETURN instead.
>> if(a>3),disp(a),else,continue,end
??? Error: A CONTINUE may only be used within a FOR or WHILE loop.
אבל כאשר ה-if בתוך לולאה זה עובד:
>> for i=4:-1:3,if(i>3),disp(a),else,break,end,end
5
"מתוך הספר: Matlab - מדריך טיולים"
©כל הזכויות שמורות לאריה שלזינגר,2008