صفحه 1:
صفحه 2:
الگوریتم و برنامه ای بنویسید که ابتدا یک
عدد صحیح مثبت را, که فرض می شود
1<ه , از ورودي بخواند. سپس درایه هاي
سه ماتریس به اسامي 8 ¥ مر و رار كه
» معکوسپذیر فرض می شود, a طور
جداگانه خوانده و مقدار det (AB+C*) را
محاسبه. و جاب كتد.
صفحه 3:
زیرالگوریتم ها: 1) ضرب کننده دو ماتریس؛ 2) جمع
کننده دو ماتریس؛ 3) وارون کننده یک ماتریس؛ 4۸)
مجاستبه کنندح دفزفیبان؟ 5) خواننده:درانه:هاي یک
ماتریس.
کابرالگوزتلی
بکار گرفته شده
)5(
)5(
آنچه که به
زیرالگوریتم
Spiga, S15
A
۸و8
C15 AB
روم
كاري كه زيرالكوريتم انجام مى
دهد
خواندن ۸ و ذخیره کردن آن در
حافظه
خواندن 8 و ذخیره کردن آن در
حافظه
خواندن © و ذخيره كردن آن در
حافظه
محاسبه و برگرداندن ۸8
محاسبه و برگرداندن 2)
محاسبه و برگرداندن -۸8+6
ل ما
صفحه 4:
1 نوشین الخوریتم ساده تر مین و33 جرا كةء كان
Masala بزرگ بین زیرالگو pis هايي کوچک, به
انضمام یک الگوریتم اصلي کوچک تقسیم می گردد.
اکنون نوشتن زیرالگوریتمها به خاطر حجم آنها و
محدودیت کارشان ساده خواهد بود.
2( آزمایش درستي الگوریتم به آزمایش یک به یک
زیرالگوریتم ها خلاصه شده و در نتیجه مشکل
آزمايش الگوریتم نیز حل می گردد. بویژه, اگر
اشتباهات احتمالي وجود داشته باشند, اصلاح آنها در
هر زیرالگوریتم مستقل راحتتر و سریعتر انجام مى
يرد.
3) از تكرار برخي بخشها در قسمتهاي مختلف
برنامه, و در نتیجه از اتلاف وقت, جلوگيري می
شود.
4) هر زیرالگوریتم را می توان بطور مستقل براي
صفحه 5:
۶ یت زیرالجوریتم هی حاري, انجام نمی
دهد مگر اینکه یک زیرالگوریتم دیگر با
الگوریتم اصلي, که بعد از اين آن را
الگوریتم (واحد) فراخوان خواهیم گفت, آن
silos ily
در ایتصورت, هي , تک و یا جتد مقداز به
زیرالگوریتم داده شده و زیرالگوریتم شروع
به اغا مى كند. در نتبجه. آين اجرا..ما
كاري انجام مى شود (مثل خواندن و در
حافظه ذخیره کردن, چاپ کردن, و يا یک
پردازش دیگر) و با یک یا چند مقدار به
الگوریتم فراخوان باز می گردد.
صفحه 6:
قاعده. در شروع یک زیرالگوریتم, نام
آن به انضمام متغيرهاي ورودي به
زیرالگوریتم و خروجي از آن را در داخل
یک بيضي ب قرار مى دهیم. مثلا .
2 ماه a Reader (a, b, 9 اس e ره ا
اتمام الگوریتم را نیز با یک بیضی با نوشته
ععلام خواهیم کرد.
صفحه 7:
متغیر هاي داخل پرانتز را آركومانهاي
صوری زیرالگوریتم می نامیم. اين آرگومانها
بر دو دسته تقسیم می شوند. دسته اول, که
آنها را پارامترهاي مقدار می ناميم,
آرگومانهاي صوري ورودي به زیرالگوریتم
مى باشند؛ يعني مقادير را از الگوریتم
فراخوان به زیربرنامه می آورند. دسته دوم,
به نام پارامترهاي perio , آرگومانهاي
صوري خروجي از زيرا الكوريتم مى باشند؛
يعني مقاديري را كه از اجراي زيرالكوريتم
حاصل شده اند از آن خارج كرده و به
الگم, رتم ف اخوان GL مه yl if
صفحه 8:
قاعده. وقتي اجراي یک زیرالگوریتم
تمام شد, کنترل اجراي برنامه به
موقعیت بعد از نقطه ای که از انجا
زیرالگوریتم فراخواني شده بود منتقل
مى شود.
صفحه 9:
در ادامه خواهیم دید که نوع
زیرالگوریتمها, و همچنین نوع
قراخواني انها ناوت اسحه ولي نگ
نکته در تمام اين فراخواني ها
مشترک است و ان اینکه,
!! در لحظه فراخواني یک
زيرا الگوریتم توسط الگوریتم فراخوان
نام آن زیرالگوریتم به انضمام برخي
متغیرها یا عبارتهايي ذکر می شود.
Dnwar/y ۱و ۱۶
صفحه 10:
آرگومانواي فعال م می نامیم. آرگومانهاي
فعال نيز به دو دسته ورودي به الگوریتم
فراخوان و خروجي از أن تقسيم مى شوند.
أركومانهاي ورودي به الكوريتم و میج
Stayt + متغير (آرگومانهاي" صوري خروجي
از زیرالگوریتم) متناظر هستند.
آرگومانهاي خروجي از الگوریتم فراخوان
wo توانند یک مقدار (متغیر. ثابت, يا یک
عبارت چبري) باشند. اين آرگومانها با
,پارامترهاي مقدا ر (آرگومانهای صوري ورودي
صفحه 11:
قاعده. تعداد, ترتیب» و نوع آرگومانهاي
صوري بايد با تعداد. ترتیب و نوع
آرگومانهاي فعال متناظر با آنها کاملا
سازگار باشند.
8 آرگومانهای فعال و صوري متناظر می توانند همنام
و یا غیر همنام باشند.
11
صفحه 12:
مثلا اگر در دستور معرف
| ۳ لسحصووسی>
نوع آرگومانهاي « و « بصورتي که هست مشخص شده
باشند, آنگاه به منظور فراخواني زیرالگوریتم براي
مقدان كاي اكه ترص مت شود از قبل :دن ره
ذخيره شده ) متناظر با آركومان صوري * , و مقدار
صحیح 8 متناظر با آرگومان صوري ۰ , می توان
فراخواني به صورت (8 1۳۹ را انجام داد ولي
ز فراخواني درست نمی , >
power (y) (,8] 16۲ ( 2۵,0 ۷) ۲کبیرو۲
12
صفحه 13:
RES)
صفحه 14:
در برنامه نویسی برگردان
زیرالگوریتم را زیربرنامه (-طاو
30 و بركردان الكوريتم
اصلي را برنامه اصلي main)
(program
یک زیربرنامه در برنامه نویسی
پاسکال در نمودار (الف) صفحه بعد
مشخص شده است. رز ررء کب
14
صفحه 15:
ازاين به بعد pm
از زیربرنامه ها را یک واحد خواهيم
گفت. به برنامه اصلي به عنوان واحد
اصلي و به هر یک از زیربرنامه ها با
نام آن واحد ارجاع خواهیم نمود. یک
برنامه قابل اجراء شامل برنامه اصلی
و زیربرنامه هایش, را یک برنامه
کامل می نامیم.
چند واحد تودرتو را نشان می دهد.
صفحه 16:
لا دستور معرف برنامه اصلي, همان
دستور
اسم برنامه Program
است و دستورهاي معرف زيربرنامه ها
16
صفحه 17:
شوند BEES, |
یک زیربرنامه تعریف می شوند
می نامند.
قاعده حوزه عمل پارامترهاي
پارامترهاي مقدار و متفيرهاي موضعي
فقط در خود آن واحد و واحدهاي
lo خلی ان قابل دسترسي (استفاده)
هستند. اينها در هيج واحد خارجی
دیربرنامه نمی توانند استفاده شوند.
صفحه 18:
واجدي که پارامتر مقدار با متغیر موضعي
در آن تعریف شده
واحدي که پارامتر مقدار یا متغیر موضعي
فقط در آن قابل دسترسي (استفاده)
است
صفحه 19:
اگر متغیر موضعي یک زیربرنامه در "
حوزه عمل خود در يكي از زیربرنامه ها
نوعش عوض شود آنگاه در آن زیربرنامه
.با همان نوع کار خواهد کرد
صفحه 20:
لا اکر متغیری هم رونت سس *
یک واحر فراخوان خارجی آن استفاده شده
باشد, آنگاه در صورتیکه استفاده آنها با هم
تداخل نداشته باشند می توان به تعریف آن
در واحد فراخوان (خارجی) اکتفا کرده و در
زیربرنامه از تعریف مجدد آن
صرفنظرنمود؛ ِ
ولی در صورتیکه استفاده آنها با هم تداخل
داشته باشند باید هم در زیربرنامه و هم در
آن واحد فراخوان آن متفیر را تعریف کرد؛
در غير اينصورت اثرات مخربی در نتایج
خواهيم داشت كه تشخيص و اصلاح آن
ترا oil (ati,
صفحه 21:
قاعده فراعو
براي اينكه حوزه سل Sole) cles
ها را همواره به خاطر داشته باشيم, يى
شيوه بسيار ساده را ارائه می دهیم. فرض
wo کنیم که هر واحد با یک کادر مرز بندي
شده باشد (مثل نمودار (ب)).
واحدي را مى توان در واحدي دیگر
فراخواني کرد که مرزهاي آن دو را بتوان,
بدون برخورد با هیچ مرزي دیگر, تواسط یک
داخلی فراخوانی کرد.
صفحه 22:
0 | B | A | واحد (زیربرنامه) |
است
واحدي که اين واحد فقط در آن قابل فراخواني |۳۳ A | اصلي: و ۸
صفحه 23:
صفحه 24:
اين زیرالگوریتم را زماني بكار مى بریم
كه بخواهيم تابعي بسازيم (تعريف كنيم)
كه اين تابع در فهرست توابع مترجم زبان
صفحه 25:
ST eee ee te OOS LS
آرگومان صوري داشته ودقيقا یک
wo مقدار به الگوریتم فراخوان با
گرداند. اين مقدار بازگشتي توسط
اسم خود تابع انجام می گیرد. به همین
علت. براي تعریف مقدار تایم. مق
تابع بايد حداقل يى بار در سمت
جب يى دستور انتساب ظاهر
شود تا مقدار تابع را در خود بكيرد. به
علاوه, نوع نتيجه تابع نيز بايد
quae كرود
صفحه 26:
O در اینجا آرگومانهاي صوري همه از
دسته پارامترهاي مقدار (ورودي به
زیرالگوریتم) می باشند و هیچ پارامتر
متغير (خروجی از زیرالگوریتم) نداربم
چون اسم تابع است که ami را به واحد
صفحه 27:
قاعده. هیچیک از آرگومانهاي sh
تایع را دیگر نباید در زیرالگوریتم تابع
توسط دستورهاي خواندن بخوانیم
مقادیر اين آرگومانها از طریق واحد
فراخوان به زیرالگوریتم می ایند.
همجنين مقدار تابع را نباید در
زیرالگوریتم جاب كنيم. اين مقدار
قرار است به واحد فراخوان بازگردد.
صفحه 28:
el علامت «وذء برای یک عدد حقیقی ؛ با
ضابطه زیر تعریف می شود:
tt x<0 SI
اگر 20 0= sign(x)
اك ر0<” 1
صفحه 29:
صفحه 30:
قاعده. فراخواني توایع درست مثل
استفاده از توابع تعریف شده براي
مترجم هر زبان می باشد.
همانطوریکه sly یک مقدار تعریف شده ۲ در
برنامه از تابع سینوس (*)510 استفاده می
کنیم, از wl (5190)۷ نیز به همان شکل
استفاده می نماییم.
صفحه 31:
s+sign(sin(y))
tesin(sign(y))
صفحه 32:
قاعده. در برنامه نويسي, دستور معرف
زیربرنامه های تابع بصورت زير نوشته می
شود:
: نوع مقدار تابع ): آركومانهاي صوري (اسم نابع
Function
صفحه 33:
ممكن است هيج آرگومان صوري نداشته
باشيم. جنين وضعيتى امكان دارد زمانى رخ
دهد كه بخواهيم مقدارى را براى يى متغير
بخصوصی تعریف کنیم. Wo در زیربرنامه el
زیر مقدار عدد نیری » تعریف می گردد:
Function e:real;
Begin
e:=exp(1.0)
End;
صفحه 34:
اماء در صورت وجود آرگومانهای صور و :
آنها به شکل زير (از چپ به راست) ظاهر
خواهند شد.
نوع دسته آخر:دسته آخر ۰ .۰ . : نوع دسته 2:دسته 2: نوع دسته
1 :دسته 1
صفحه 35:
مثلا در دستور معرف
;Function Pad(x,y:real;i,j,k:integer):char
دسته y 9 x Sle prio از نوع حقیقی,
و متغیرهای ز , :, و) از نوع
صحیح بوده, و نوع تأبع ۶۵۵ نیز
کاراکتری می باشد.
صفحه 36:
قاعده. هیچیک از آرگومانهاي صوري در
یک زیربرنامه را دیگر نباید در بلوک ۵۳
آن زیربرنامه تعریف کرد. به عبارت دیگر
یک آرگومان صوري نمی تواند در عین
حال یک متغیر موضعي نیز باشد.
صفحه 37:
لا با توجه به اینکه اسم تابع مقدار تابع
رابا خود به واحد فراخوان باز مى
كرداند, يس نوع مقدار تابع نيز بايد
مشخص باشد. زيرالكوريتم «هذه و
الگوریتم (اصلي) فراخوان آن در برنامه
1 ۲4 امده است.
صفحه 38:
و
{A program containing two units: A function sub-program
called sign, and 2 main program}
Program P41;
Uses wincrt;
Var
y,tireal;
stinteger;
عمسي يي ييه عو مجع ع
Function sign(x:real):
Begin
Tf x<0 then
sign
End; {sign}
|
Begin
Write(‘Enter a real number:
Readin(y);
sr=sign(sin(y));
tresin(sign(y));
If set then
begin
iriteLn(‘sign(sin(*,y,")=
Writeln(‘sin(sign(*1y,")=
end
End.
صفحه 39:
Sul به چگونگی اجرای برنامه دو واحدی
بالا می پردازیم. ولی قبلا لازم است
مطالبی در مورد حافظه زیربرنامه و برنامه
Oly lol کنیم.
صفحه 40:
pone براق هن حاار بارا مدن هدي
مقدار (آرگومانهاي صوري) تایع. و
همجنین برای هر یک از متغیرهای
موضعى, ٠ یک حافظه موقت در
هنكام اجراي زيربرنامه رزرو مى شود
كه با يايان اجراي أن (با اجراي دستور
G End اين حافظه هاي موقت نيز بطور
سراسرى در حافظه اى به نام حافظ
دائم ذخيره مى كردند. اين حافظه تا
يإيان اجراى برنامه باقى wo ماند.
صفحه 41:
کامپیوتر کاملا از همدیگر جدا هستند.
بنابراین ن اگر یک متغیر همنام در دو
حافظه ظاهر شده باشد, آنگاه حافظه
هاى اين دو متغير همنام هيخ برخوردي
با هم نخواهند داشت زیرا وقتي یک
زیربرنامه اجرایش تمام می شود
حافظه موقت مربوط , به آن از حافظه
کامپیوتر پاک می شود. پس برخوردي
صفحه 42:
Program P4 1;
Uses winert;
Var
y,trreal;
s:integer;
عدج ربص
Function _sign(x:real) : integer;
begin? No
If x<0 then
sign:=-1 —— *
else if x=0 then
sign
else
sign:=1 :همه -
End; {sign} 5
دورو و
Begin
Write('Enter a real number:
Readin(y);
s:=sign(sin(y)); #۳
tr=sin(sign(y));
If set then
begin تا
Writetn('sign(sin(',y,') 1
Writetn('sin(sign(',y,")=",t:8:
: فك
End.
9
صفحه 43:
6م
Program P4 1;
Uses winert;
Var
y,trreal;
s:integer;
تم بو
Function sign(x:real):integer
Begin
If x<0 then
sign:=-1
else if x=0 then
sign
else
sign:=1
End; {sign}
0
Begin
Write(‘Enter a real number
Readin(y);
s:=sign(sin(y));
tr=sin(sign(y));
If set then
begin
Writeln('sign(sin(',y,'
Writeln('sin(sign(',y,'
end
End.
صفحه 44:
Program P4 1;
Uses winert;
Var
y,trreal;
s:integer;
رعس كوو سمو سمو
Function sign(
Begin
If x<0 then
sign
9 then
1
(0
End; {sign}
ممعم معو مع عع عه معو
Begin
Write('Enter a real number
Readin(y);
s:=sign(sin(y)); #۳
tr=sin(sign(y));
If set then
begin 8
Writeln('sign(sin(',y,") :
Writetn('sin(sign(",y,')=",t:8:
End.
ee
صفحه 45:
eo
Program P4 1;
Uses winert;
Var
y,trreal;
s:integer;
تم بو
Function sign(x:real):integer
Begin
If x<0 then
sign:=-1
else if x=0 then
sign
else
sign:=1
End; {sign}
0
Begin
Write(‘Enter a real number
Readin(y);
s:=sign(sin(y));
tr=sin(sign(y));
If set then
begin
Writeln('sign(sin(',y,'
Writeln('sin(sign(',y,'
end
End.
صفحه 46:
اسم تابع به تنهايي (بدون ذکر
آركومانهايش) نبايد در سمت
راست هيج دستور انتسابي ظاهر
مثلا در بدنه تابعي كه با دستور معرف
Function Power(x:real;n:integer):real
تعریف شده است, نوشتن دستوري مثل دستور زیر
غير مجاز است: تا
oe Sy
بخ سر
:Power :=Power*x
صفحه 47:
22
ee
A
لإدسسم ig 0p 1010101010101001 تا بع
۸
آارچیه
صفحه 48:
هنگامي که بخواهیم در زیرالگوریتم
كاري مثل جابء, خواندن داده ها و
ذخيره كردن انها در حافظه, ويا هر
پردازش دیگر انجام كيرد, ويا زماني
كه لازم باشد بيش از يك مقدار از
زیرالگوریتم به الگوریتم فراخوان باز
گردد, از زیرالگوریتم رویه
-puiS cno odlaiwl (procedure)
صفحه 49:
طریقه تنظیم این زیرالگوریتم مثل
زیرالگوریتم تابع است ولي با توجه به
اينكه اينجاء اسم زيرالكّوريتم هيج
دابا وميه !| الهو
فراخوان باز نمی گرداند؛ پس
قاعده. در طول زیرالگوریتم رویه
اسم ان نبايد ظاهر شود.
صفحه 50:
Procedure Heading;
Begin
عم یبای مام زعا )
Writeln('* Sub-program to investigate the roots *');
Writeln('* of the equation a*x*2+b*x+c=0 ۳
یماد ) مآم رما )
End; {Heading}
صفحه 51:
قاعده. در برنامه نويسي, دستور معرف
زیربرنامه هاي رویه بصورت زیر نوشته می
شود:
ز اسم زیربرنامه (آرگومانهاعصوری) ۴۳۵6۵۵۷۲6
صفحه 52:
eu ful ae A) es
نوع دسته آخر: دسته آخر [م]ز ۰۰ ۰ : نوع دسته 22 tLe] 2 aims نوع
دنننته 1: دسته 1 [م:
که در آن [م] برای دسته پارامترهاي متفیر
۲ و برای دسته پارامتر هاي مقدار خالي
صفحه 53:
متلا در دستور معرف
;Procedure Pol_Cart(ro,theta:real;var x,y:real)
پارامتر مقدار بوده و 2066۵ 9 ro دو متغیر حقیقی
قبل از آنها خالي است, در حالیکه متغیرهای
* و با پارامترهاي متفیر بوده و قبل از آنها ۷۵۶ نوشته
شده است.
صفحه 54:
| ‘Two roots
a
(2*۵)/ ۵۷۷۵۱ - )سر
x2+(-b-¥d)/(2*a)
[= wear |f درت
ee
debtb-4tatc
2)
Procedure Roots(=,b,c: real);
var [No real roots”
,x,x1,x2: real;
Begin
d:=b*b-4tatc;
If d>0 then
-besqrt(d) )/(2*a);
=b-sqrt(d))/(2*a);
Wiritetn(*Two roots: *,x1:
end
else if d=0 then
begin
xz=-b/ (24a);
Wiriteln(‘One root: ',x:4:
end
else
iriteln( ‘No real roots’)
End; {Roots}
صفحه 55:
قاعده. هیچیک از پارامترهای مقدار را
دیگر نباید در آن زیرالگوریتم توسط
دستورهاي خواندن بخوانیم. مقادیر اين
آرگومانها از طریق واحد فراخوان به
زیرالگورنتم سین ایند همچنین هیچیک از
پارامترهای متغیر را نباید در زیرالگوریتم
طانه گنف اين مقادير قرار است به
واحد فراخوان باز گردند.
ee ee eee) ee ee > اه
صفحه 56:
قاعده. هیچیک از آرگومانهاي صوري در یک
زیربرنامه را دیگر نباید در بلوک ۷۵۲ آن
زیربرنامه تعریف کرد. به عبارت دیگر یک
آرگومان صوري نمی تواند در عین حال یک
متغیر موضعي نیز باشد.
در زیربرنامه بالاء آوردن : 5 , يا » در فهرست ۷3۲ کاملا مضحک
خواهد بو
صفحه 57:
قاعده. در الگوریتم نويسي, یک
زیرالگوریتم رویه به صورت زير
و در برنامه نويسي, براي فراخواني یک زیربرنامه
رویه دستور زیر بکار برده می شود:
ارگومانهاي فعال (اسم رویه
صفحه 58:
Pol_Cart(r,t,u,v
1
Pol_Cart(r,t,u,v);
صفحه 59:
777
ده
debtb-atatc
‘Two roots:’,
0-)۰۵+۷/۵۱/)2*۵(
x2-(-b-Vd) /(2¢a)
>) xe -b/(2*a)
‘No real roots’
| | rootsiu.viw) | |
وه
صفحه 60:
Progras Pa 2;
Uses winert;
var
uv wereal;
Provedure Heading
Begin
ی
to investigate the roots *"); |
Writeln('* of the equation atx~2ebrxyc=8 ۳
HrLtsln{ ‘seishesonendectathnctonestnantcontnssteiins)|
End; (Heading)
Procedure Roots(a,b,c: real);
var
4,x,20, x2: real;
Begin
disbrb-a*are;
If do then
begin
cdis(-besgrt(d))/(2%a);
۳
0
end
else if dea then
begin
xi=-b/(2"@)
Weiteln( ‘aust one root: *,x:6:2)
end
else
Weiteln('No real roots")
End; (Roots)
Begin
Reading
Writeln;
Write( ‘Enter the coefficients: *
Readln(u,¥ i);
Roots(u,,¥);
End.
صفحه 61:
ت قطبي ان؛ , بصورت زیر
(0,0)
یک زیرالگوونتم»رونههفوجسید که
مختصات قطبي یک نقطه را گرفته و
مختصات کارترین آن را محاسبه و
بازگرداند. سپس زیرالگوریتم
(زیربرنامه) اخیر را براي مقادیری از و
که از ورودم خوانده می شود فراخواني
ونتيجه را جاب كنيد. 9
صفحه 62:
Pol_Cart(ro, theta,x,y) 50
et
xero*cos (theta)
yero*sin(theta)
Pol _Cart(r,t,u,v)
fet [ow]
Program P4 3;
Uses winert;
Var
ry tyu,vereal;
مکش
| x,y:real);
Begin
End; {Pol_Cart}
|
Begin
Write('Enter the polar coordinates Ro and Theta: ');
Readin(r,t);
Pol_Cart(r,t,u,v);
Write('The Cart. coordinates are (',u:4:2,",',v:4:2,")')
End
وه
صفحه 63:
Ur WI Wo dD sould alos \li
متغیرهای سراسری (متغيرهاي برنامه
اصلي) بوده و تا اتمام اجراي برنامه
پارامتر هاي مقدار و متغیرهای موضعی
اختصاص دارد و اين حافظه پس از اتمام
اجراي زیربرنامه مربوطه, بطور کامل پاک
گردد: pe
3( حافظه مشترک (بین واحد فراخوان و
زیربرنامه), که مخصوص پارامترهاي متغیر
بوده و با آرگومانهاي فعال متناظر با آنها به
wel اكوك التق هن Sei آنته نع صافصاه
صفحه 64:
64
3
abst
ro
theta
صفحه 65:
Program P4_3;
Uses wincrt;
Var
r,t,u,vireal;
Procedure Pol_Cart(ro, theta:
Begin
ro*cos(theta) ;
ro*sin(theta)
End; {Pol_Cart}
(FERRER SSE)
Begin
Readltn(r,t);
Pol_Cant(\),!,u,v);
Write(u\v
End.
صفحه 66:
Program P4_3;
Uses wincrt;
Var
r,t,u,vireal;
FRB SHS rb يدي يدي يدي يدج دي يد ع لدع ددع د مدع ا م د م م د د IIA )
Procedure Pol_Cart(ro,theta:real;var x,y:real);
Begin
ro*cos(theta) ;
ro*sin(theta)
End; {Pol_Cart}
(FERRER SSE)
Begin
Readtn(r,t);
Pol_Cart(r,t,u,v);
Write(u,v)
End.
صفحه 67:
سوال. اگر ۷۵۳ قبل از آرگومانهاي
و ۷ را برداریم خروجی چه مى شود؟
9
صفحه 68:
Program P4 3;
Uses wincrt;
Var
Pt aera.
Begin
ro*cos(theta) ;
ro*sin(theta)
End; {Pol_Cart}
(FERRER SSE)
Begin
Readtn(r,t);
Pol_Cant(r,t,u,v);
Write(u\v
End.
صفحه 69:
Program P4_3;
Uses wincrt;
Var
r,t,u,vireal;
FRB HS Sb SS SFE H يدي يدي يدي يدج دي يد ع لدع ددع د لدع IIA )
Procedure Pol Cart(ro,theta,x,y:real) ;
Begin
ro*cos (theta) ;
ro*sin(theta)
End; {Pol_Cart}
(FERRER SSE)
Begin
Readln(r,t);
Pol_Cart(r,t,u,v);
Write(u,v)
End.
صفحه 70:
ممکن است یک آرگومان صوري, هم نقش یک |
پارامتر مشدار را بازي کند و هم نقش بک
پارامتر متغیر.
در اينصورت بايد قاعده زیر رعایت گردد.
قاعده. یک آرگومان صوري اگر هم پارامتر
مقدار و هم پارامتر متغیر باشد, حتما بايد با
۳ (قبل از آن) همراه باشد.
صفحه 71:
زیرالگوریتم بعدي کار الگوریتم ماهي طلايي را
انجام مى دهد؛ يعني دو مقدار " و 0 را گرفته و
مقادير آنها را تعويض كرده و به همان اسامي أنها را
باز می گرداند.
Program P4 4;
Uses winert;
m,
0 Swap(m,n)
Procedure Swap(var m,n:intege
جمممممم مممممم
Bey
Write('Enter two integers: ');
Readtn(m,n
‘Swap(m,n) ;
',n) ره
End.
Writeln('The interchanged values:
20
صفحه 72:
ارتباط بین زیرالگوریتم های تایع و رویه را
قاعده زیر مشخص می کند
قاعده. هر زیرالگوریتم eb را می توان
همواره بصورت یک زیرالگوریتم cre در آورد
ولی برعکس, در حالتیکه بازگشتی از
زیربرنامه بیش از یکی باشد, ممکن نیست.
صفحه 73:
SS signe -1
<—> sign-o
signel
Return
چه چیز تغییر کرد؟ چون قبلا متغیر 190و (اسم تایع) نتیجه
خواسته شده را به واحد فراخوان بازمی گرداند. پس برای
اينكه 5190 همان نقش قبلى را ايفا كند نام زيرالكوريتم
كن باهر
HW توجه كنيد كه اينجا 5190 يك پارامتر متغير است!
صفحه 74:
oe
Chee 5 star >
23
P_sign(sin(y),s)
s+sign(sin(y)) -
tesin(sign(y))
oN P_sign(y,w)
1
a tesin(w)
رس
بر
End 0
!! مجدداً تاكيد مى كنيم هنكامى كه یک مقدار بازگشتی داريد
از زيرا
از زیرالگوریتم تابع استفاده کنید چون هم آن را
است و هم فراخوانی آن. nd
صفحه 75:
Oy lado pI (lL مورد باز تشتی به واحد
قراخوآن داریم از تابع استقاده می كنيم:
وگرنه رویه را بکار می گیریم.
2 آرگومانهاي ورودي به زیرالگوریتم
(پارامترهاي مقدار) را دیگر نباید در آن
زیرالگوریتم توسط دستورهاي خواندن
بخوانیم
3) هیچیک از آرگومانهاي صوري در یک
زیربرنامه را دیگر نباید در Ul var Sol
زیربرنامه تعریف کرد. به عبارت دیگر یک
آرگومان صوري نمی تواند در عین حال یک
متغیر موضعي نیز باشد.
صفحه 76:
4 1) به در الگوریتم. و نوشتن
در برنامه دقت می کنیم.
4 بازگشت نتیجه اجرای زیرالگوریتم
(زیربرنامه) توسط اسم زیربرنامه انجام می
گیرد. در نتيجه اسم تابع بايد حداقل يك بار در
سمت چپ یک دستورعمل (دستور) انتساب
ظاهر شود. ِ
4 3) اسم تایع (بدون آرگومان) نباید در سمت
راست هیچ دستورعمل (دستور) انتساب ظاهر
شود.
4 5) به فراخوانی درست دقت می کنیم
(«فراخواني در دستور مستقل انجام نمی گیرد).
صفحه 77:
eS See a *« ae SS a
زير را درنظر بگیریم. . .
5 1) به معرفی رویه در الگوریتم» و
نوشتن د ستور معرف در برنامه دقت می
۱ ips
در نیس کل ادها مه ae
نوشته می شود.
5. 3) اسم رویه نباید درطول زیرالگوریتم
(زیربرنامه) ظاهر شود.
5 4( فراخوانی در یک دستور مستقل
Sak ltl
صفحه 78:
خودفراخوانی
صفحه 79:
خودفراخواني (Recursion) فني |
که در آن یک زیربرنامه, در رود 7
, یک يا چند بار خودش را
فراخواني مى كند. در اينصورت, در
زیر انجام می گيرند که توجه به آنها
موجب فراگيري بهتر مفهوم
خودفراخواني خواهد شد.
صفحه 80:
رت و ی وت سوت
كيرد, زیربرنامه شروع به اجرا کرده و
ابتدا ۱ موقت لايه لايه
ای به نام حافظه پشننه Stack)
2017م حم ) توليدء و در هر لايه
بارامترهاي مقدار و متغيرهاي موضعي
جديد را ذخيره مى كند بطوريكه هر
لايه از لايه قبلي خود متمايز بوده و مى
توان تصور نمود كه روي أن قرار مى
گیرد.
صفحه 81:
2) اين خودفراخواني هاي مكرر تا
نفقطه برگشت پیش می روند. نة
برگشت به اولین اجراي کامل
زیربرنامه در آخرین فراخواني می
گوییم که در vl دیگر خودفراخواني
انجام نمی گیرد و زیربرنامه به طور
کامل اجرا می شود.
صفحه 82:
با ورور
كه هر يى مربوط به يى فراخواني است,
روي هم به ترتیب فراخواني چیده شده اند,
در نقطه برگشت, لایه مربوط به آخرین
فراخواني بالاي تمام لایه ها قرار می گیرد.
حال با اتمام اجراي کامل این زیربرنامه.
لایه بالايي از حافظه موقت و می شود.
ب رود
زيربرنامه كال مى ردد.
82
صفحه 83:
با نماك ”وو سوسس"
ماقبل آخر از حافظه پشته پاک می گردد.
اين روند تا اتمام آخرين اجراي كامل
زيربرنامه در اثر اولين فراخواني (صورت
كرفته از واحد فراخوان), ر و به دنبال آن پاک
ادامه پیدا ما مى كند. بدين ترتيب اجرای"
زیربرنامه تمام شده و کنترل اجرا به
موقعيتي بلافاصله بعد از جايي كه اولين
فراخواني توسط واحد فراخوان صورت
گرفته بود منتقل مى شود.
83
صفحه 84:
0 ۳۲۲۲۲۲۲۲ ۲
يكي از مهمترین كاربردهاي خودفراخواني
در محاسبه روابط تراجعي. ۳ توابع
تراجعي, می باشد. متداولترين مثال در اين
yas رآنطه (نایه) فاكتوريل مى باشد كه با
رابطه تراجعي
1=!0 ۱-11 ۲۱۱<0,
و یا با تابع تراجعي اگ ۵ fact(fy j=
“Infact(n -1)
صفحه 85:
(تابع) براي یک مقدار ۰ , مثلا 3 , اين
است که بلافاصله به سراغ ۱۵ می رود.
آن را برداشته و کار محاسبه را با
استفاده از قاعده رابطه (تایع) تا
رسیدن به 3! تکرار می کند.
اين واكنش سریع را با بياني ساده تجزیه و
85
صفحه 86:
تصور کنید که در پشت بام یک ۰ -
(به انضمام یک طبقه همکف) قرار
گرفته اید. فرض کنید که از محاسبه
قاکتوریل یک عدد هیچ اطلاع قبلی ندارید و
براي محاسبه 3! از شما خواسته شده که
کارهای زیز زا انجام دهيد:
(منطور از
امکان تذیز
86
صفحه 87:
کی eS ee
طبقه که وارد
می شوید پردازش زیر صورت می گیرد:
عده:حاضل از بزدارتن سلبقه پایین شمان این طتفه <
عدد حاصل از پردازش این طبقه
در یک جاي اين پردازش, محاسبه ناتمام
باقي مانده و رفتن به طبقه پایین
درخواست می گردد. این کار تا رسیدن به
طبقه همكف تكرار مى شود. در اين طبقه
يردازش زير انجام مى شود:
< 1 عدد حاصل از يردازش اين طبقه
ايفجا نقطه بركشت است.
صفحه 88:
از اين به بعد. مسيري یکطرفه رو به طبقه
بالا را بايد طي كنيد. در اين مسيرء به
طبقه که وازدهمی
ناتمام باقي مانده oy أكنون: باهر دست
داشتن عدد حاصل از پردازش طبقه پایین
تكميل كه وجي حاضل به ظيعة بالا
برده مى شود.
مى كند. وقتي به يشت بام رسيديد عددي
كه در دست داريد 3! است.
صفحه 89:
حال به نوشتن الگوریتم می پردازيم. ابتدا یک
راکرس بلق ساچن نع وبا سایظه
بالا می نویسیم. این زیرالگوریتم
صفحه 90:
Program P4 5;
Uses winert;
Var
m:integer;
f:longint;
رم و
Function fact(n:integer) :Longint
Begin
If n=@ then
fact
else
fact:=n*fact (n-1)
End; {fact}
عمجم مه و (
Begin
Write(‘Enter an integer: ')
Readtn(m) ;
If m<@ then
Writeln(m,' is negative’
else
begin
fact (m);
Writeln(m,'
end
End.
<>
<x
a
<->
rf)
صفحه 91:
صفحه 92:
در الگوریتم قبلی یک زیرالگوریتم تابع داشتیم
که در محاسبه مقدار ان, و در لابلاي محاسبه,
خود زیرالگوریتم را فراخواني می کرد.
در مثال زیر یک زیرالگوریتم رویه
صفحه 93:
<<
>
[ | countineay | ]
Count (1)
Program P4 6;
Uses wincrt;
) عع عو ووه وو عع عع (
Procedure Count(n:integer) ;
Begin
If n<3 then
Count (n+1) ;
Writeln(n)
End; {Count}
عمجم (
Begin
Count (1)
End.
صفحه 94:
fegin
end
0 ۰(تحت ورس
begin
Tene then
Procedure Countinsinteger): مسب
begin
Tene then
begin
] then
count(ael)
Wwestetniay
te 3
كت
or
صفحه 95:
A AI و سرت وال ON PY) I” a
uw L برگشت وجود داشته
براي اينكه ببينيم در غير اینصورت چه
اتفاق می افتد, فرض كنيد كه به جاي
دستور
If
n<3 then
Count (n+1)
gus فقط
Count (n+1)
را داشته باشیم.
صفحه 96:
Program P4 6;
Uses wincrt;
( عع عو ووه وو عع عع )
Procedure Count(n:integer) ;
Begin
[ | countinsay [ [
Count (n+1) ;
Writeln(n)
End; {Count}
عمجم (
Begin
Count (1)
End.
Count (1)
هه
صفحه 97:
در ابنصورتء بعك ور سو سس ٠
نخواهد داشت و زيربرنامه بطور بي
oll خودش را فرا خواهد خواند. ولي
از آنجا که در هر بار فراخواني یک لایه
در حافظه پشته نشکیل می شود, و با
ae به محدود بودن ظرفیت حافظه
, پس از مدتي این حافظه سرریز
شده و در نتیجه اعلام خطاي سرریز
"Stack over flow" باعث از دست
رفتن برنامه, بدون هیچ نتیجه ای خواهد
97
صفحه 98:
بيني دیدر ار مالهاي نلاسیت براي ود کر اوابی
زیربرنامه های رویه, معماي تاريخي برجهاي
هانوي است. این مسئله در شکل زیر نشان داده
شده است.
در این معما باید دیسکها را از ستون ۸ به ستون C
منتقل کنیم مشروط بر اینکه:
1- اگر ديسكي برداشته شد باید در یک ستون دیگر
قرار داده شود؛
2- در هر حرکت فقط یک دیسک و آنهم بالاترین دیسک
را می توان حایجا کرد؛
3- یک دیسک زرگ را نمی*وان روي یک یسک کوچک
قرار داد.
همه
صفحه 99:
داشته باشد, آنگاه بسادكي مى توان Lal با
یک حرکت به ستون © منتقل نمود, وگرنه
(اكر تعداد ديسكها, 5, بيش از يكى باشد)
راه حل مسئله به صورت تراجعي انجام
مى كيرد:
الف) تعداد 0-1 ديسك از بالاي ستون ۸ را
به کمک ستون ) به ستون 8 منتقل مى
کنیم
ب) تنها دیسک باقي مانده در ستون ۸ را با
یک حرکت به ستون ) منتقل می نماییم.
ج) تعداد ۰-1 دیسک را از ستون 8 به کمک
تون ۸ به ستون ) حرکت می دهیم.
صفحه 100:
YL که در ) a> L
تو
tna Lan lve as a
گردشی آر:
‘
صفحه 101:
و مود و وم << موه
e
to
to
to
to
to
to
to
to
to
to
to
to
to
to
4
A
A
B
A
6
3
۸
A
B
B
58
8
۸
۸
to
of disks:
from
from
from
from
from
from
from
from
from
from
from
from
from
from
isk from B
disk
disk
disk
disk
disk
disk
disk
disk
disk
disk
disk
disk
disk
disk
Number
Move
Move
Move
Move
Move
Move
Move
Move
Move
Move
Move
Move
Move
Move
Move
۵ ۵ ۵ ۵ و ۵ ۵ نه ۵ ۵ وه و وه وه
همانطوریکه می بینیم؛ هقفت
حرکت اول سه دیسک را به
کمک به 8 منتقل می کنند.
حرکت هشتم بزرگترین دیسک
را از ۸ به > حرکت می دهد.
بالاخره هفت حرکت آخر سه
دیسک موجود در ة را به کمک «
به » منتقل می سازند.
aoa
Program 4 7
Uses wine
Const
pegl='A';
peg2="'B';
peg3='C';
Var
nzinteger; {Number of disks}
لمعيه عه جاه عو ع عع مو جل جو
Procedure Move(n: integer; pegA, pegB, pegC: char);
Begin
If n=l then
Writeln('Move a disk from ',pegA,' to ',pegC)
else
begin
Move(n-1, peg, pegC, pegB)
Move(1,pegA,pegB, pegC) ;
Move(n-1,pegB, peg, pegC)
end
End; {Move}
۲
Begin
Write('Number of disks: ');
Readtn(n) ;
Move(n, pegl, peg2, peg3)
End.
صفحه 102:
-خروح- و دستو رالات
اجراي دستور
Exit
باعث می شود که خروج از زیربرنامه انجام
گرفته و کنترل اجراي برنامه به بعد از
صفحه 103:
ee at coli! ۲
خروج از آن زیربرنامه را سبب می
0355 ولي اگر از +5 3 برنامه
اصلي استفاده شود رفتاري مانند ۲۷۵۱۴
سازد.
در برنامه 18 ۲3 به جاي :۱۵1 می
توانستیم 6 را نیز بنویسیم.
8 برای اینکه ابهامی پیش نیاید به
جای Halt از ۲ استفاده نکنید.
103
صفحه 104:
Program 4م 8:
Uses winert;
var
a:real;
10 اا
Procedure Test (a:real);
Begin
If a>0 then
begin
Writeln('We are in the range of ''then''
Exit
end
else
begin
Writeln('We are in the range of ''else''')
Halt
end
End; {Test}
عمسم سس ما
Begin
Write(‘Enter a number
Readtn(a) ;
Test(a);
Writeln('We are in the main program’)
End.
i
0
زيرالگوريتم
1
الگوريتم و برنامه ای بنويسيد که ابتدا يک
عدد صحيح مثبت nرا ,که فرض می شود
, n>1از ورودي بخواند .س*پس درايه هاي
سه ماتريس به اسامي , A , Bو Cرا ,که
Cمعکوسپذير فرض می شود ,به طور
جداگانه خوانده و مقدار ) det(AB+Cرا
محاسبه و چاپ کند.
-1
2
زيرالگوريتم ها )1 :ضرب کننده دو ماتريس؛ )2جمع
کننده دو ماتريس؛ )3وارون کننده يک ماتريس؛ )4
محاسبه کننده دترمينان؛ )5خواننده درايه هاي يک
ماتريس.
اصلی:
کار الگوريتم
زيرالگوريتم
بکار گرفته شده
3
آنچه که به
زيرالگوريتم
داده می شود
کاري که زيرالگوريتم انجام می
دهد
()5
A
خواندن Aو ذخيره کردن آن در
حافظه
()5
B
خواندن Bو ذخيره کردن آن در
حافظه
()5
C
خواندن cو ذخيره کردن آن در
حافظه
()1
AوB
محاسبه و برگرداندن AB
()3
C
محاسبه و برگ*رداندن C-1
()2
ABو C-1
محاسبه و برگرداندن AB+C-1
-1
)1نوشتن الگوريتم ساده تر می گردد چرا که ،کار
محاسبه ای بزرگ بين زيرالگوريتم هايي کوچک ،ب*ه
انضمام يک الگوريتم اصلي کوچک تقسيم می گردد.
اکنون نوشتن زيرالگوريتمها به خاطر حجم آنها و
محدوديت کارشان ساده خواهد بود.
)2آزمايش درستي الگوريتم به آزمايش يک به يک
زيرالگوريتم ها خالصه شده و در نتيجه مشکل
آزمايش الگوريتم نيز حل می گردد .ب*ويژه ،اگر
اشتباهات احتمالي وجود داشته باشند ،اصالح آنها در
هر زيرالگوريتم مستقل راحتتر و سريعتر انجام می
گيرد.
)3از تکرار برخي بخشها در قسمتهاي مختلف
برنامه ،و در نتيجه از اتالف وقت ،جلوگيري می
شود.
)44هر زيرالگوريتم را می توان بطور مستقل براي
‼ يک زيرالگوريتم هيچ کاري انجام نمی
دهد مگر اينکه يک زيرالگوريتم ديگر يا
الگوريتم اصلي ،که بعد از اين آن را
الگوريتم (واحد) فراخوان خواهيم گفت ،آن
را فراخواند.
در اينصورت ,هيچ ,يک ,و يا چند مقدار به
زيرالگوريتم داده شده و زيرالگوريتم شروع
به اجرا می کند .در نتيجه اين اجرا ،يا
کاري انجام می شود (مثل خواندن و در
حافظه ذخيره کردن ،چاپ کردن ،و يا يک
پردازش ديگر) و يا يک يا چند مقدار به
الگوريتم فراخوان باز می گردد.
5
قاعده .در شروع يک زيرالگوريتم ،نام
آن به انضمام متغيرهاي ورودي به
زيرالگوريتم و خروجي از آن را در داخل
يک بيضي قرار می دهيم .مثال
Power(x,n
)
)Data_Reader(a,b,c
اتمام الگوريتم را نيز با يک بيضی با نوشته
Returnاعالم خواهيم کرد.
6
متغير هاي داخل پرانتز را آرگومانهاي
صوري زيرالگوريتم می ناميم .اين آرگومانها
بر دو دسته تقسيم می شوند .دسته اول ،که
آنها را پارامترهاي مقدار می ناميم،
آرگومانهاي صوري ورودي به زيرالگوريتم
می باشند؛ يعني مقادير را از الگوريتم
فراخوان به زيربرنامه می آورند .دسته دوم،
به نام پارامترهاي متغير ،آرگومانهاي
صوري خروجي از زيرالگوريتم می باشند؛
يعني مقاديري را که از اجراي زيرالگوريتم
حاصل شده اند از آن خارج کرده و به
الگوريتم فراخوان باز می گردانند.
7
قاعده .وقتي اجراي يک زيرالگوريتم
تمام شد ،کنترل اجراي برنامه به
موقعيت بعد از نقطه ای که از آنجا
زيرالگوريتم فراخواني شده بود منتقل
می شود.
8
در ادامه خواهيم ديد که نوع
زيرالگوريتمها ،و همچنين نوع
فراخواني آنها متفاوت است .ولي يک
نکته در تمام اين فراخواني ها
مشترک است و آن اينکه،
‼ در لحظه فراخواني يک
زيرالگوريتم توسط الگوريتم فراخوان
نام آن زيرالگوريتم به انضمام برخي
متغيرها يا عبارتهايي ذکر می شود.
9
در ) ، Power(y,8عبارتهاي داخل پرانتز را
آرگومانهاي فعال می ناميم .آرگومانهاي
فعال نيز به دو دسته ورودي به الگوريتم
فراخوان و خروجي از آن تقسيم می شوند.
آرگومانهاي ورودي به الگوريتم فراخوان
حتما بايد متغير انتخاب شوند .اين آرگومانها با
پارامترهاي متغير (آرگومانهاي صوري خروجي
از زيرالگوريتم) متناظر هستند.
آرگومانهاي خروجي از الگوريتم فراخوان
می توانند يک مقدار (متغير ،ثابت ،يا يک
عبارت جبري) باشند .اين آرگومانها با
10پارامترهاي مقدار (آرگومانهاي صوري ورودي
قاعده .تعداد ،ترتيب ،و نوع آرگومانهاي
صوري بايد با تعداد ،ترتيب و نوع
آرگومانهاي فعال متناظر با آنها کامال
سازگار باشند.
‼ آرگومانهای فعال و صوري متناظر می توانند همنام
و يا غير همنام باشند.
11
مثال اگر در دستور معرف
ا*عشار*ی :
x
ص**حيح :
n
Power(x,n
)
نوع آرگومانهاي xو nبصورتي که هست مشخص شده
باشند ،آنگاه به منظور فراخواني زيرالگوريتم براي
مقدار اعشاري ( yکه فرض می شود از قبل در حافظه
ذخيره شده) متناظر با آرگومان صوري ، xو مقدار
صحيح 8متناظر با آرگومان صوري ، nمی توان
فراخواني به صورت ) Power(y,8را انجام داد ولي
هيچيک از فراخواني هاي زير درست نمی باشند.
)Power(y
12
)Power(8,y
)Power(y,8.0
زيربرنامه
13
در برنامه نويسی برگردان
زيرالگوريتم را زيربرنامه (sub-
)programو برگردان الگوريتم
اصلي را برنامه اصلي (main
)program
می ناميم .موقعيت برنامه اصلي و
يک زيربرنامه در برنامه نويسی
پاسکال در نمودار (الف) صفحه بعد
مشخص شده است( .از روی کتاب)
14
از اين به بعد ،برنامه اصلي و هر يک
از زيربرنامه ها را يک واحد خواهيم
گفت .به برنامه اصلي به عنوان واحد
اصلي و به هر يک از زيربرنامه ها با
نام آن واحد ارجاع خواهيم نمود .يک
برنامه قابل اجرا ،شامل برنامه اصلی
و زيربرنامه هايش ،را يک برنامه
کامل می ناميم.
نمودار (ب) يک برنامه کامل شامل
چند واحد تودرتو را نشان می دهد.
15
‼ دستور معرف برنامه اصلي ،همان
دستور
;
اسم برنامه
Program
است و دستورهاي معرف زيربرنامه ها
بعدا ً مورد مطالعه قرار خواهند گرفت.
16
شوند متغيرهای سراسری
يک زيربرنامه تعريف می شوند متغيرهای موضعی
می نامند.
و آنهايی را که بلوک Var
قاعده حوزه عمل پارامترهاي
مقدار و متغيرهاي موضعي.
پارامترهاي مقدار و متغيرهاي موضعي
تعريف شده در يک واحد زيربرنامه،
فقط در خود آن واحد و واحدهاي
داخلي آن قابل دسترسي (استفاده)
هستند .اينها در هيچ واحد خارجی
زيربرنامه نمی توانند استفاده شوند.
17
در نمونه (ب( :
واحدي که پارامتر مقدار يا متغير موضعي
در آن تعريف شده
واحدي که پارامتر مقدار يا متغير موضعي
فقط در آن قابل دسترسي (استفاده)
است
18
اصلي
A
B
C
اصلي, A , B ,
وC
AوB
B
C
اگر متغير موضعي يک زيربرنامه در ‼
حوزه عمل خود در يکي از زيربرنامه ها
نوعش عوض شود آنگاه در آن زيربرنامه
.با همان نوع کار خواهد کرد
19
‼ اگر متغيری هم در زيربرنامه و هم در
يک واحد فراخوان خارجی آن استفاده شده
باشد ،آنگاه در صورتيکه استفاده آنها با هم
تداخل نداشته باشند می توان به تعريف آن
در واحد فراخوان (خارجی) اکتفا کرده و در
زيربرنامه از تعريف مجدد آن
صرفنظرنمود؛
ولی در صورتيکه استفاده آنها با هم تداخل
داشته باشند بايد هم در زيربرنامه و هم در
آن واحد فراخوان آن متغير را تعريف کرد؛
در غير اينصورت اثرات مخربی در نتايج
خواهيم داشت که تشخيص و اصالح آن
20
قاعده فراخواني واحدهاي تو در تو.
براي اينکه حوزه عمل واحدهاي زيربرنامه
ها را همواره به خاطر داشته باشيم ،يک
شيوه بسيار ساده را ارائه می دهيم .فرض
می کنيم که هر واحد با يک کادر مرز بندي
شده باشد (مثل نمودار (ب)).
واحدي را می توان در واحدي ديگر
فراخواني کرد که مرزهاي آن دو را بتوان،
بدون برخورد با هيچ مرزي ديگر ،توسط يک
خط پيوسته به همديگر وصل کرد .البته يک
واحد خارجی را نمی توان در يک واحد
داخلی فراخوانی کرد.
21
در نمونه (ب( :
واحد (زيربرنامه)
A
B
C
واحدي که اين واحد فقط در آن قابل فراخواني
است
اصلي و C
A
اصلي و A
22
وند
يممیش
تهتقس
زیرالگوريتمهابهدودس
يتم
زيرالگور
تابع
23
اين زيرالگوريتم را زماني بکار می بريم
که بخواهيم تابعي بسازيم (تعريف کنيم)
که اين تابع در فهرست توابع مترجم زبان
برنامه نويسی موجود نباشد.
24
قاعده .يک تابع ،معموالً ،حداقل يک
آرگومان صوري داشته و دقيقا يک
مقدار به الگوريتم فراخوان باز می
گرداند .اين مقدار بازگشتي توسط
اسم خود تابع انجام می گيرد .به همين
علت ,براي تعريف مقدار تابع ،اسم
تابع بايد حداقل يک بار در سمت
چپ يک دستور انتساب ظاهر
شود تا مقدار تابع را در خود بگيرد .به
عالوه ،نوع نتيجه تابع نيز بايد
تعيين گردد.
25
‼ در اينجا آرگومانهاي صوري همه از
دسته پارامترهاي مقدار (ورودي به
زيرالگوريتم) می باشند و هيچ پارامتر
متغير (خروجی از زيرالگوريتم) نداريم
چون اس*م تابع اس*ت که نتيجه را به واحد
فراخوان برمی گرداند.
26
قاعده .هيچيک از آرگومانهاي صوری
تابع را ديگر نبايد در زيرالگوريتم تابع
توسط دستورهاي خواندن بخوانيم.
مقادير اين آرگومانها از طريق واحد
فراخوان به زيرالگوريتم می آيند.
همچنين مقدار تابع را نبايد در
زيرالگوريتم چاپ کنيم .اين مقدار
قرار است به واحد فراخوان بازگردد.
27
تابع عالمت signبرای يک عدد حقيقی
ضابطه زير تعريف می شود:
اگر x 0
اگر x 0
اگر x 0
28
1
sign(x) 0
1
x
با
sign(x
)
x<
0
sign← -1
x=
0
sign←0
sign←1
Return
29
قاعده .فراخواني توابع درست مثل
استفاده از توابع تعريف شده براي
مترجم هر زبان می باشد.
همانطوريکه براي يک مقدار تعريف شده xدر
برنامه از تابع سينوس ) sin(xاستفاده می
کنيم ،از تابع ) sign(xنيز به همان شکل
استفاده می نماييم.
30
Star
t
sign(x
)
y
s←sign(sin(y))
t←sin(sign(y))
s≠t
x<
0
sign← -1
x=
0
sign←0
sign←1
s,t
Return
End
31
قاعده .در برنامه نويسي ،دستور معرف
زيربرنامه های تابع بصورت زير نوشته می
شود:
; نوع مقدار تابع ) :آرگومانهاي صوري (اسم تابع
Function
32
ممکن است هيچ آرگومان صوري نداشته
باشيم .چنين وضعيتی امکان دارد زمانی رخ
دهد که بخواهيم مقداری را برای يک متغير
بخصوصی تعريف کنيم .مثال ً در زيربرنامه تابع
زير مقدار عدد نپری eتعريف می گردد:
Function
;e:real
Begin
)e:=exp(1.0
;End
33
اما ،در صورت وجود آرگومانهای صوری،
آنها به شکل زير (از چپ به راس*ت) ظاهر
خواهند شد.
نوع دسته آخر:دسته آخر ; . . .نوع دسته :2دسته ;2نوع دسته
:1دسته 1
34
مثال در دستور معرف
;Function Pad(x,y:real;i,j,k:integer):char
دسته متغيرهای xو yاز نوع حقيقی,
و متغيرهای , i , jو kاز نوع
صحيح بوده ,و نوع تابع Padنيز
کاراکتری می باشد.
35
قاعده .هيچيک از آرگومانهاي صوري در
يک زيربرنامه را ديگر نبايد در بلوک Var
آن زيربرنامه تعريف کرد .به عبارت ديگر
يک آرگومان صوري نمی تواند در عين
حال يک متغير موضعي نيز باشد.
36
‼ با توجه به اينکه اسم تابع مقدار تابع
را با خود به واحد فراخوان باز می
گرداند ،پس نوع مقدار تابع نيز بايد
مشخص باشد .زيرالگوريتم signو
الگوريتم (اصلي) فراخوان آن در برنامه
P4_1آمده است.
37
{A program containing two units: A function sub-program
called sign, and a main program}
Program P4_1;
Uses wincrt;
Var
y,t:real;
s:integer;
(*****************************)
Function sign(x:real):integer;
Begin
If x<0 then
sign:=-1
else if x=0 then
sign:=0
else
sign:=1
End;{sign}
(*****************************)
Begin
Write('Enter a real number: ');
Readln(y);
s:=sign(sin(y));
t:=sin(sign(y));
If s<>t then
begin
Writeln('sign(sin(',y,')=',s);
Writeln('sin(sign(',y,')=',t:8:4)
end
End.
38
اينک به چگونگی اجرای برنامه دو واحدی
باال می پردازيم ،ولی قبال الزم است
مطالبی در مورد حافظه زيربرنامه و برنامه
اصلی بيان کنيم.
39
قاعده .براي هر يک از پارامتر هاي
مقدار (آرگومانهاي صوري) تابع ،و
همجنين برای هر يک از متغيرهای
موضعی ،يک حافظه موقت در
هنگام اجراي زيربرنامه رزرو می شود
که با پايان اجراي آن (با اجراي دستور
);Endاين حافظه هاي موقت نيز بطور
کلي پاک می شوند .تمام متغيرهای
سراسری در حافظه ای به نام حافظ
دائم ذخيره می گردند .اين حافظه تا
پايان اجرای برنامه باقی می ماند.
40
کامپيوتر کامال از همديگر جدا هستند.
بنابراين اگر يک متغير همنام در دو
حافظه ظاهر شده باشد ,آنگاه حافظه
های اين دو متغير همنام هيچ برخوردي
با هم نخواهند داشت زيرا وقتي يک
زيربرنامه اجرايش تمام می شود
حافظه موقت مربوط به آن از حافظه
کامپيوتر پاک می شود .پس برخوردي
وجود نخواهد داشت .اين مطلب براي
حافظه موقت و حافظه دائمي نيز
معتبر است.
41
Program P4_1;
Uses wincrt;
Var
y,t:real;
s:integer;
(*****************************)
Function sign(x:real):integer;
Begin
If x<0 then
sign:=-1
else if x=0 then
sign:=0
else
Sin(10) : - 0.544
sign:=1
End;{sign}
(*****************************)
Begin
Write('Enter a real number: ');
Readln(y);
s:=sign(sin(y));
t:=sin(sign(y));
If s<>t then
begin
Writeln('sign(sin(',y,')=',s);
Writeln('sin(sign(',y,')=',t:8:4)
end
End.
-0.544
x
10.0
y
-1
s
t
42
Program P4_1;
Uses wincrt;
Var
y,t:real;
s:integer;
(*****************************)
Function sign(x:real):integer;
Begin
If x<0 then
sign:=-1
else if x=0 then
sign:=0
else
sign:=1
End;{sign}
(*****************************)
Begin
Write('Enter a real number: ');
Readln(y);
s:=sign(sin(y));
t:=sin(sign(y));
If s<>t then
begin
Writeln('sign(sin(',y,')=',s);
Writeln('sin(sign(',y,')=',t:8:4)
end
End.
10.0
y
-1
s
t
43
Program P4_1;
Uses wincrt;
Var
y,t:real;
s:integer;
(*****************************)
Function sign(x:real):integer;
Begin
If x<0 then
sign:=-1
else if x=0 then
sign:=0
else
Sin(1) : 0.841
sign:=1
End;{sign}
(*****************************)
Begin
Write('Enter a real number: ');
Readln(y);
s:=sign(sin(y));
t:=sin(sign(y));
If s<>t then
begin
Writeln('sign(sin(',y,')=',s);
Writeln('sin(sign(',y,')=',t:8:4)
end
End.
10.0
x
10.0
y
-1
s
0.841
t
44
Program P4_1;
Uses wincrt;
Var
y,t:real;
s:integer;
(*****************************)
Function sign(x:real):integer;
Begin
If x<0 then
sign:=-1
else if x=0 then
sign:=0
else
sign:=1
End;{sign}
(*****************************)
Begin
Write('Enter a real number: ');
Readln(y);
s:=sign(sin(y));
t:=sin(sign(y));
If s<>t then
begin
Writeln('sign(sin(',y,')=',s);
Writeln('sin(sign(',y,')=',t:8:4)
end
End.
10.0
y
-1
s
0.841
t
45
اسم تابع به تنهايي (بدون ذکر
آرگومانهايش) نبايد در سمت
راست هيچ دستور انتسابي ظاهر
شود.
مثال در بدنه تابعي که با دستور معرف
Function Power(x:real;n:integer):real
تعريف شده است ,نوشتن دستوري مثل دستور زير
غير مجاز است:
46
;Power:=Power*x
وندزيرالگوريتمتابع
يممیش
تهتقس
زیرالگوريتمهابهدودس
يتم
زيرالگور
رويه
47
هنگامي که بخواهيم در زيرالگوريتم
کاري مثل چاپ ،خواندن داده ها و
ذخيره کردن آنها در حافظه ،و يا هر
پردازش ديگر انجام گيرد ,و يا زماني
که الزم باشد بيش از يک مقدار از
زيرالگوريتم به الگوريتم فراخوان باز
گردد ،از زيرالگوريتم رويه
( )procedureاستفاده می کنيم.
48
طريقه تنظيم اين زيرالگوريتم مثل
زيرالگوريتم تابع است ولي با توجه به
اينکه اينجا ،اسم زيرالگوريتم هيچ
مقداري را با خود به الگوريتم
فراخوان باز نمی گرداند؛ پس
قاعده .در طول زيرالگوريتم رويه
اسم آن نبايد ظاهر شود.
49
هيچ آرگومان صوری نداريم
Headin
g
يک
عنوان
Retur
n
Procedure Heading;
Begin
Writeln('******************************************');
Writeln('* Sub-program to investigate the roots *');
Writeln('* of the equation a*x^2+b*x+c=0
*');
Writeln('******************************************')
End;{Heading}
50
قاعده .در برنامه نويسي ،دستور معرف
زيربرنامه هاي رويه بصورت زير نوشته می
شود:
; ا*س*م ز*يربرنام*ه ( آر*گومان*ه*ایص**ور*ی) Procedure
51
اگر آرگومانهاي صوري داشته باشيم ،آنها به
شکل زير (از چپ به راست) ظاهر خواهند
شد.
نوع دسته آخر :دسته آخر [م]; ; . . .نوع دسته :2دسته [ 2م]; نوع
دسته :1دسته [ 1م]
که در آن [م] برای دسته پارامترهاي متغير
varو برای دسته پارامتر هاي مقدار خالي
است (م اول کلمه مشخصه است).
52
مثال در دستور معرف
);Procedure Pol_Cart(ro,theta:real;var x,y:real
دو متغير حقيقی roو thetaپارامتر مقدار بوده و
قبل از آنها خالي است ،در حاليکه متغيرهای حقيقی
xو yپارامترهاي متغير بوده و قبل از آنها varن*وشته
شده است.
53
Roots(a,b,c
)
d←b*b-4*a*c
d>
0
d=
0
Procedure Roots(a,b,c:real);
Var
‘No real roots’
d,x,x1,x2:real;
Begin
d:=b*b-4*a*c;
If d>0 then
Retur
begin
n
x1:=(-b+sqrt(d))/(2*a);
x2:=(-b-sqrt(d))/(2*a);
Writeln('Two roots: ',x1:4:2,x2:4:2)
end
else if d=0 then
begin
x:=-b/(2*a);
Writeln('One root: ',x:4:2)
end
else
Writeln('No real roots')
End;{Roots}
x1←(-b+√d)/(2*a)
x2←(-b-√d)/(2*a)
‘Two roots:’,
x1,x2
x← -b/(2*a)
‘One root:’,
x
آرگومانها همه پارامتر مقدارند
54
قاعده .هيچيک از پارامترهای مقدار را
ديگر نبايد در آن زيرالگوريتم توسط
دستورهاي خواندن بخوانيم .مقادير اين
آرگومانها از طريق واحد فراخوان به
زيرالگوريتم می آيند .همچنين هيچيک از
پارامترهای متغير را نبايد در زيرالگوريتم
چاپ کنيم .اين مقادير قرار است به
واحد فراخوان بازگردند.
55
قاعده .هيچيک از آرگومانهاي صوري در يک
زيربرنامه را ديگر نبايد در بلوک Varآن
زيربرنامه تعريف کرد .به عبارت ديگر يک
آرگومان صوري نمی تواند در عين حال يک
متغير موضعي نيز باشد.
در زيربرنامه باال ،آوردن ، a ، bيا cدر فهرست Varکامال مضحک
خواهد بود.
56
قاعده .در الگوريتم نو*يسي ,يک
زيرالگوريتم رويه به صورت زير
فراخواني می شود:
)آر*گومان*ه*ایف**ع*ا*ل(
ا*س*م رو*ي*ه
و در برنامه نويسي ,براي فراخواني يک زيربرنامه
رويه دستور زير بکار برده می شود:
آرگومانهاي فعال ( اسم رويه
);
57
Pol_Cart(r,t,u,v
)
Pol_Cart(r,t,u,v);
5
Headin
g
Roots(a,b,c
)
d←b*b-4*a*c
يک
عنوان
Retur
n
d>
0
d=
0
x1←(-b+√d)/(2*a)
x2←(-b-√d)/(2*a)
‘Two roots:’,
x1,x2
x← -b/(2*a)
‘One root:’,
x
‘No real roots’
Start
Retur
n
Heading
u,v,w
Roots(u,v,w)
End
59
Program P4_2;
Uses wincrt;
Var
u,v,w:real;
(*******************************************************)
Procedure Heading;
Begin
Writeln('******************************************');
Writeln('* Sub-program to investigate the roots *');
Writeln('* of the equation a*x^2+b*x+c=0
*');
Writeln('******************************************')
End;{Heading}
(*******************************************************)
Procedure Roots(a,b,c:real);
Var
d,x,x1,x2:real;
Begin
d:=b*b-4*a*c;
If d>0 then
begin
x1:=(-b+sqrt(d))/(2*a);
x2:=(-b-sqrt(d))/(2*a);
Writeln('Two roots: ',x1:6:2,' and ',x2:6:2)
end
else if d=0 then
begin
x:=-b/(2*a);
Writeln('Just one root: ',x:6:2)
end
else
Writeln('No real roots')
End;{Roots}
(**************************************************)
Begin
Heading;
Writeln;
Write('Enter the coefficients: ');
Readln(u,v,w);
Roots(u,v,w);
End.
60
مختصات قطبي آن،
محاسبه می شود:
،بصورت زير
) ( ,
بنويسيد که
رويه
زيرالگوريتم
يک
(x cos
) , y
) sin(
مختصات قطبي يک نقطه را گرفته و
مختصات کارترين آن را محاسبه و
بازگرداند .سپس زيرالگوريتم
(زيربرنامه) اخير را براي مقاديری از و
ورودي خوانده می شود فراخواني
که از
ونتيجه را چاپ کنيد.
61
Star
t
Pol_Cart(ro,theta,x,y)
r,t
x←ro*cos(theta)
y←ro*sin(theta)
Pol_Cart(r,t,u,v)
Return
u,v
{Program to convert the polar coordinates to Cartesia
coordinates, using a procedure}
Program P4_3;
Uses wincrt;
Var
r,t,u,v:real;
(**********************************************)
Procedure Pol_Cart(ro,theta:real;var x,y:real);
Begin
x:=ro*cos(theta);
y:=ro*sin(theta)
End;{Pol_Cart}
(**********************************************)
Begin
Write('Enter the polar coordinates Ro and Theta: ');
Readln(r,t);
Pol_Cart(r,t,u,v);
Write('The Cart. coordinates are (',u:4:2,',',v:4:2,')')
End.
End
هم پارامتر مقدار داريم
و هم پارامتر متغير
62
)1حافظه دائم ،که مثل قبل مختص
متغيرهای سراسری (متغيرهاي برنامه
اصلي) بوده و تا اتمام اجراي برنامه
ماندگار است.
)2حافظه موقت زيربرنامه ،که به
پارامتر هاي مقدار و متغيرهای موضعی
اختصاص دارد و اين حافظه پس از اتمام
اجراي زيربرنامه مربوطه ،بطور کامل پاک
می گردد.
)3حافظه مشترک (بين واحد فراخوان و
زيربرنامه) ،که مخصوص پارامترهاي متغير
بوده و با آرگومانهاي فعال متناظر با آنها به
اشتراک گذاشته می شود .اين نوع حافظه
63
حافظه
دائم
64
حافظه
موق
ت
حافظه
مش
تر
ک
r
u
x
ro
t
v
y
theta
Program P4_3;
Uses wincrt;
Var
r,t,u,v:real;
(**********************************************)
Procedure Pol_Cart(ro,theta:real;var x,y:real);
Begin
ro
theta
x:=ro*cos(theta);
y:=ro*sin(theta)
1.0 0.0
End;{Pol_Cart}
x
y
(*****************)
Begin
1.0 0.0
Readln(r,t);
Pol_Cart(r,t,u,v);
u
v
Write(u,v)
End.
1.0
r
0.0
t
65
Program P4_3;
Uses wincrt;
Var
r,t,u,v:real;
(**********************************************)
Procedure Pol_Cart(ro,theta:real;var x,y:real);
Begin
x:=ro*cos(theta);
y:=ro*sin(theta)
End;{Pol_Cart}
(*****************)
Begin
1.0 0.0
Readln(r,t);
Pol_Cart(r,t,u,v);
u
v
Write(u,v)
End.
1.0
r
0.0
t
66
سؤال .اگر varقبل از آرگومانهاي x
و yرا برداريم خروجی چه می شود؟
67
Program P4_3;
Uses wincrt;
Var
r,t,u,v:real;
(**********************************************)
Procedure Pol_Cart(ro,theta,x,y:real);
Begin
ro
theta
x
y
x:=ro*cos(theta);
y:=ro*sin(theta)
1.0 0.0
1.0 0.0
End;{Pol_Cart}
(*****************)
Begin
Readln(r,t);
Pol_Cart(r,t,u,v);
Write(u,v)
End.
1.0
r
0.0
t
68
Program P4_3;
Uses wincrt;
Var
r,t,u,v:real;
(**********************************************)
Procedure Pol_Cart(ro,theta,x,y:real);
Begin
x:=ro*cos(theta);
y:=ro*sin(theta)
End;{Pol_Cart}
(*****************)
Begin
Readln(r,t);
Pol_Cart(r,t,u,v);
Write(u,v)
End.
1.0
r
0.0
t
69
ممکن است يک آرگومان صوري ،هم نقش يک
پارامتر مقدار را بازي کند و هم نقش يک
پارامتر متغير.
در اينصورت بايد قاعده زير رعايت گردد.
قاعده .يک آرگومان صوري اگر هم پارامتر
مقدار و هم پارامتر متغير باشد ،حتما بايد با
( varقبل از آن) همراه باشد.
70
زيرالگوريتم بعدي کار الگوريتم ماهي طاليي را
را گرفته وn وm انجام می دهد؛ يعني دو مقدار
مقادير آنها را تعويض کرده و به همان اسامي آنها را
.باز می گرداند
Program P4_4;
Uses wincrt;
Var
m,n:integer;
(*******************************)
Procedure Swap(var m,n:integer);
Var
k: integer;
Begin
k:=m;
m:=n;
n:=k
End;{Swap}
(*******************************)
Begin
Write('Enter two integers: ');
Readln(m,n);
Swap(m,n);
Writeln('The interchanged values: ',m,' ',n)
End.
Swap(m,n)
k←m
m←n
n←k
Return
71
ارتباط بين زيرالگوريتم های تابع و رويه را
قاعده زير مشخص می کند.
قاعده .هر زيرالگوريتم تابع را می توان
همواره بصورت يک زيرالگوريتم رويه در آورد
ولی برعکس ،در حالتيکه بازگشتی از
زيربرنامه بيش از يکی باشد ،ممکن نيست.
72
sign(x
)
P_sign(x,sign
)
sign← -1
<x
0
sign← -1
<x
0
sign←0
=x
0
sign←0
=x
0
sign←1
sign←1
Return
Return
چه چيز تغيير کرد؟ چون قبال متغير ( signاسم تابع) نتيجه
خواسته شده را به واحد فراخوان بازمی گرداند ،پس برای
اينکه signهمان نقش قبلی را ايفا کند نام زيرالگوريتم
را تغيير داديم.
‼ توجه کنيد که اينجا signيک پارامتر متغير است!
73
Star
t
Star
t
y
y
)P_sign(sin(y),s
))s←sign(sin(y
))t←sin(sign(y
)P_sign(y,w
s≠t
)t←sin(w
s,t
s≠t
s,t
End
End
74
‼ مجددا ً تاکيد می کنيم هنگامی که يک مقدار بازگشتی داريد
از زيرالگوريتم تابع استفاده کنيد چون هم نوشتن آن راحت
است و هم فراخوانی آن.
)1اگر دقيقا يک مورد بازگشتی به واحد
فراخوان داريم از تابع استفاده می کنيم،
وگرنه رويه را بکار می گيريم.
)2آرگومانهاي ورودي به زيرالگوريتم
(پارامترهاي مقدار) را ديگر نبايد در آن
زيرالگوريتم توسط دستورهاي خواندن
بخوانيم.
)3هيچيک از آرگومانهاي صوري در يک
زيربرنامه را ديگر نبايد در بلوک Varآن
زيربرنامه تعريف کرد .به عبارت ديگر يک
آرگومان صوري نمی تواند در عين حال يک
متغير موضعي نيز باشد.
75
)4اگر از تابع استفاده می کنيم بايد موارد زير را
درنظر بگيريم.
)1 .4به معرفی تابع در الگوريتم ،و نوشتن
دستور معرف در برنامه دقت می کنيم.
)2 .4بازگشت نتيجه اجرای زيرالگوريتم
(زيربرنامه) توسط اسم زيربرنامه انجام می
گيرد .در نتيجه اسم تابع بايد حداقل يک بار در
سمت چپ يک دستورعمل (دستور) انتساب
ظاهر شود.
)3 .4اسم تابع (بدون آرگومان) نبايد در سمت
راست هيچ دستورعمل (دستور) انتساب ظاهر
شود.
)5 .4به فراخوانی درست دقت می کنيم
(76فراخواني در دستور مستقل انجام نمی گيرد).
)5اگر از رويه استفاده می کنيم بايد موارد
زير را درنظر بگيريم.
)1 .5به معرفی رويه در الگوريتم ،و
نوشتن دستور معرف در برنامه دقت می
کنيم.
)2 .5بازگشت نتيجه اجرای زيرالگوريتم
(زيربرنامه) توسط پارامترهای متغير انجام
می گيرد .در نتيجه قبل از آنها مشخصه var
نوشته می شود.
)3 .5اسم رويه نبايد درطول زيرالگوريتم
(زيربرنامه) ظاهر شود.
)4 .5فراخوانی در يک دستور مستقل
انجام می گيرد.
77
خودفراخواني
78
خودفراخواني ( )Recursionفني است
که در آن يک زيربرنامه ،در روند اجراي
ناتمام خود ،يک يا چند بار خودش را
فراخواني می کند .در اينصورت ،در
روند اجراي اين فراخواني ها کارهاي
زير انجام می گيرند که توجه به آنها
موجب فراگيري بهتر مفهوم
خودفراخواني خواهد شد.
79
)1هر بار که فراخواني صورت می
گيرد ،زيربرنامه شروع به اجرا کرده و
ابتدا يک اليه در حافظه موقت اليه اليه
ای به نام حافظه پشته (Stack
)memoryتوليد ،و در هر اليه
پارامترهاي مقدار و متغيرهاي موضعي
جديد را ذخيره می کند بطوريکه هر
اليه از اليه قبلي خود متمايز بوده و می
توان تصور نمود که روي آن قرار می
گيرد.
80
)2اين خودفراخواني هاي مکرر تا
نقطه برگشت پيش می روند .نقطه
برگشت به اولين اجراي کامل
زيربرنامه در آخرين فراخواني می
گوييم که در آن ،ديگر خودفراخواني
انجام نمی گيرد و زيربرنامه به طور
کامل اجرا می شود.
81
با تصور اينکه اليه هاي متمايز حافظه پشته،
که هر يک مربوط به يک فراخواني است،
روي هم به ترتيب فراخواني چيده شده اند،
در نقطه برگشت ،اليه مربوط به آخرين
فراخواني باالي تمام اليه ها قرار می گيرد.
حال با اتمام اجراي کامل اين زيربرنامه،
اليه بااليي از حافظه موقت پاک می شود.
سپس کنترل اجرا ،به نقطه ای بالفاصله
بعد از جايي که آخرين فراخواني صورت
گرفته بود منتقل گشته و اجراي ناتمام اين
زيربرنامه کامل می گردد.
82
با اتمام اجراي اين زيربرنامه نيز ,اليه
ماقبل آخر از حافظه پشته پاک می گردد.
اين روند تا اتمام آخرين اجراي کامل
زيربرنامه در اثر اولين فراخواني (صورت
گرفته از واحد فراخوان) ،و به دنبال آن پاک
شدن آخرين (پايين ترين) اليه حافظه پشته،
ادامه پيدا می کند .بدين ترتيب اجرای
زيربرنامه تمام شده و کنترل اجرا به
موقعيتي بالفاصله بعد از جايي که اولين
فراخواني توسط واحد فراخوان صورت
گرفته بود منتقل می شود.
83
يکي از مهمترين کاربردهاي خودفراخواني
در محاسبه روابط تراجعي ،يا توابع
تراجعي ،می باشد .متداولترين مثال در اين
مورد ،رابطه (تابع) فاکتوريل می باشد که با
رابطه تراجعي
1=!0
,n!=n(n-1)1
و يا با تابع تراجعي
اگر n0
اگر n0
تعريف می شود.
84
fact(n) 1
)nfact(n 1
واکنش ذهن براي محاسبه اين رابطه
(تابع) براي يک مقدار ، nمثال ، 3اين
است که بالفاصله به سراغ !0می رود.
آن را برداشته و کار محاسبه را با
استفاده از قاعده رابطه (تابع) تا
رسيدن به !3تکرار می کند.
اين واکنش سريع را با بياني ساده تجزيه و
تحليل می کنيم.
85
تصور کنيد که در پشت بام يک آپارتمان سه
طبقه (به انضمام يک طبقه همکف) قرار
گرفته ايد .فرض کنيد که از محاسبه
فاکتوريل يک عدد هيچ اطالع قبلی نداريد و
براي محاسبه !3از شما خواسته شده که
کارهای زير را انجام دهيد:
ابتدا تمام طبقات را يک به يک در يک مسير
يکطرفه رو به پايين طي کنيد (منظور از
يکطرفه يعني اينکه طي عکس مسير
امکان پذير نيست).
86
در اين مسير يکطرفه رو به پايين ،به هر
طبقه که وارد
می شويد پردازش زير صورت می گيرد:
عدد حاصل از پردازش طبقه پايين × شماره اين طبقه =
عدد حاصل از پردازش اين طبقه
در يک جاي اين پردازش ،محاسبه ناتمام
باقي مانده و رفتن به طبقه پايين
درخواست می گردد .اين کار تا رسيدن به
طبقه همکف تکرار می شود .در اين طبقه
پردازش زير انجام می شود:
= 1عدد حاصل از پردازش اين طبقه
اينجا نقطه برگشت است.
87
از اين به بعد ،مسيري يکطرفه رو به طبقه
باال را بايد طي کنيد .در اين مسير ،به هر
طبقه که وارد می شويد محاسبه ای که
ناتمام باقي مانده بود ،اکنون ،با در دست
داشتن عدد حاصل از پردازش طبقه پايين
تکميل گشته و عدد حاصل به طبقه باال
برده می شود.
اين کار تا رسيدن به پشت بام ادامه پيدا
می کند .وقتي به پشت بام رسيديد عددي
که در دست داريد !3است.
88
حال به نوشتن الگوريتم می پردازيم .ابتدا يک
زيرالگوريتم برای ساختن تابع factبا ضابطه
باال می نويسيم .اين زيرالگوريتم يک عدد
صحيح نامنفي را گرفته و فاکتوريل آن را با
استفاده از ضابطه تابع محاسبه و برگرداند.
89
Program P4_5;
Uses wincrt;
Var
m:integer;
f:longint;
(*******************************)
Function fact(n:integer):longint;
Begin
If n=0 then
fact:=1
else
fact:=n*fact(n-1)
End;{fact}
(*******************************)
Begin
Write('Enter an integer: ');
Readln(m);
If m<0 then
Writeln(m,' is negative')
else
begin
f:=fact(m);
Writeln(m,'!=',f)
end
End.
fact(n)
n=
0
fact←n*fact(n-1)
fact←1
Return
Start
m
m<
0
f←fact(m)
m,’is negative’
m,’!=’,f
End
90
Begin
Readln(m);
.
.
f:= fact(m);
.
.
.
End.
6
n
Function fact(n:integer):integer;
Begin
If n=0 then
fact:=1
else
3
fact:=n * fact(n-1);
End;
2
n
Function fact(n:integer):integer;
Begin
If n=0 then
factt:=1
else
2
fact:=n * fact(n-1);
End;
1
n
Function fact(n:integer):integer;
Begin
If n=0 then
fact:=1
else
1
fact:=n * fact(n-1);
End;
1
Function fact(n:integer):integer;
Begin
If n=0 then
fact:=1
else
fact:=n * fact(n-1);
End;
نقطه
برگشت
n
0
91
در الگوريتم قبلی يک زيرالگوريتم تابع داشتيم
که در محاسبه مقدار آن ،و در البالي محاسبه،
خود زيرالگوريتم را فراخواني می کرد.
در مثال زير يک زيرالگوريتم رويه
خودفراخواني می شود.
92
Count(n
)
Program P4_6;
Uses wincrt;
(**************************)
Procedure Count(n:integer);
Begin
If n<3 then
Count(n+1);
Writeln(n)
End;{Count}
(**************************)
Begin
Count(1)
End.
n<
3
Count(n+1)
n
Return
Star
t
Count(1)
End
93
Begin
Count(1)
End;
n
Procedure Count(n:integer);
Begin
If n<3 then
Count(n+1)
1
Writeln(n)
End;
n
Procedure Count(n:integer);
Begin
If n<3 then
Count(n+1)
2
Writeln(n)
End;
Procedure Count(n:integer);
Begin
If n<3 then
Count(n+1)
Writeln(n)
End;
نقطه
برگشت
n
3
94
در هر زيربرنامه خودفراخوان بايد يک
نقطه برگشت وجود داشته باشد.
براي اينکه ببينيم در غير اينصورت چه
اتفاق می افتد ،فرض کنيد که به جاي
دستور
If
n<3 then
)Count(n+1
فقط دستور
)Count(n+1
را داشته باشيم.
95
Count(n
)
Program P4_6;
Uses wincrt;
(**************************)
Procedure Count(n:integer);
Begin
If n<3 then
Count(n+1);
Writeln(n)
End;{Count}
(**************************)
Begin
Count(1)
End.
Count(n+1)
n
Return
Star
t
Count(1)
End
96
در اينصورت ،نقطه برگشت وجود
نخواهد داشت و زيربرنامه بطور بي
پايان خودش را فرا خواهد خواند .ولي
از آنجا که در هر بار فراخواني يک اليه
در حافظه پشته تشکيل می شود ،و با
توجه به محدود بودن ظرفيت حافظه
پشته ،پس از مدتي اين حافظه سرريز
شده و در نتيجه اعالم خطاي سرريز
“ ”Stack over flowباعث از دست
رفتن برنامه ،بدون هيچ نتيجه ای خواهد
شد.
97
يکي ديگر از مثالهاي کالسيک براي خودفراخوانی
زيربرنامه های رويه ،معماي تاريخي برجهاي
هانوي است .اين مسئله در شکل زير نشان داده
شده است.
در اين معما بايد ديسکها را از ستون Aبه ستون C
منتقل کنيم مشروط بر اينکه:
-1اگر ديسکي برداشته شد ،بايد در يک ستون ديگر
قرار داده شود؛
-2در هر حرکت فقط يک ديسک و آنهم باالترين ديسک
را می توان جابجا کرد؛
-3يک ديسک Cبزرگ را نمی Bتوان روي يک Aديسک کوچک
قرار داد.
98
اگر فقط يک ديسک در ستون Aوجود
داشته باشد ،آنگاه بساد*گي می توان آنرا با
يک حرکت به ستون Cمنتقل نمود ,وگرنه
(اگر تعداد ديسکها ,n ,بيش از يکی باشد)
راه حل مسئله به صورت تراجعي انجام
می گيرد:
الف) تعداد n-1ديسک از باالي ستون Aرا
به کمک ستون Cبه ستون Bمنتقل می
کنيم.
ب) تنها ديسک باقي مانده در ستون Aرا با
يک حرکت به ستون Cمنتقل می نماييم.
ج) تعداد n-1ديسک را از ستون Bبه کمک
ستون Aبه ستون Cحرکت می دهيم.
99
با توجه به الگوريتم شفافی که در باال
گفته شد ,می توان برنامه را مستقيما،
بدون نياز به رسم نمودار گردش*ی آن،
نوشت.
100
Program P4_7;
Uses wincrt;
Const
peg1='A';
peg2='B';
peg3='C';
Var
n:integer; {Number of disks}
(***********************************************)
Procedure Move(n:integer;pegA,pegB,pegC:char);
Begin
If n=1 then
Writeln('Move a disk from ',pegA,' to ',pegC)
else
begin
Move(n-1,pegA,pegC,pegB);
Move(1,pegA,pegB,pegC);
Move(n-1,pegB,pegA,pegC)
end
End;{Move}
(***********************************************)
Begin
Write('Number of disks: ');
Readln(n);
Move(n,peg1,peg2,peg3)
End.
Number of disks:
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move a disk from
Move disk from B
4
A to B
A to C
B to C
A to B
C to A
C to B
A to B
A to C
B to C
B to A
C to A
B to C
A to B
A to C
to C
هفت،همانطوريکه می بينيم
حرکت اول سه ديسک را به
، منتقل می کنندB بهC کمک
حرکت هشتم بزرگترين ديسک
. حرکت می دهدC بهA را از
باالخره هفت حرکت آخر سه
A را به کمکB ديسک موجود در
. منتقل می سازندC به
101
خروج و دستور
Exit
اجراي دستور
Exit
باعث می شود که خروج از زيربرنامه انجام
گرفته و کنترل اجراي برنامه به بعد از
لحظه فراخواني منتقل شود.
102
‼ استفاده از Exitدر يک زيربرنامه،
خروج از آن زيربرنامه را سبب می
گردد ،ولي اگر از Exitدر برنامه
اصلي استفاده شود رفتاري مانند Halt
داشته و اجراي برنامه را متوقف می
سازد.
در برنامه P3_18به جاي Haltمی
توانستيم Exitرا نيز بنويسيم.
‼ برای اينکه ابهامی پيش نيايد به
جای Haltاز Exitاستفاده نکنيد.
103
Program P4_8;
Uses wincrt;
Var
a:real;
(********************************************)
Procedure Test(a:real);
Begin
If a>0 then
begin
Writeln('We are in the range of ''then''');
Exit
end
else
begin
Writeln('We are in the range of ''else''');
Halt
end
End;{Test}
(********************************************)
Begin
Write('Enter a number: ');
Readln(a);
Test(a);
Writeln('We are in the main program')
End.
104