صفحه 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 و يا با تابع تراجعي اگر n0 اگر n0 تعريف می شود. 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

62,000 تومان