0% found this document useful (0 votes)
44 views72 pages

Jozve

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views72 pages

Jozve

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 72

‫جزوه‌ی‌حل‌تمرین‌ردس‌مبانی‌ربانهم‌سازی‌کاویپمرت‌(فررتن)‬

‫‪www.msabbasian.mihanblog.com‬‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫ویرایش دوم‪ ،‬بهار ‪09‬‬


‫‪1‬‬
‫مثال‪ )1‬برنامهی سادهی زیر‪ ،‬نام شما را از ورودی دریافت کرده و سپس به کمک‬ ‫فصل اول (مفاهیم اساسی)‬
‫آن‪ ،‬در خروجی به شما سالم خواهد کرد!‬
‫در فصل اول که نسبت به فصول دیگر مطالب بسیار ساده و ابتدایی هستند‪ ،‬بیشتر به‬
‫‪! This program will greet you if you give it your name.‬‬
‫!‪! My first Fortran 90 program‬‬ ‫اصول برنامهنویسی پرداخته میشود؛ زیرا نکات فنی زیادی برای بحث وجود ندارد و‬
‫!‪! Greetings‬‬
‫‪Character (Len = 20) :: Name‬‬ ‫دانشجو نیز مشکل زیادی با این فصل ندارد‪ .‬البته این مساله نباید باعث شود که دانشجو‬
‫"?‪Print*, "What is your name‬‬
‫‪Read*, Name‬‬ ‫از این فصل غافل شود‪ .‬فراموش نکنید که نکات ریز این فصل بسیار زیاد است و این‬
‫‪Print*, "Hi there, ", Name‬‬
‫‪End‬‬ ‫فصل پایهی تمام فصول دیگر میباشد؛ لذا در صورت عدم تسلط‪ ،‬متاسفانه دانشجو تا‬
‫با به کارگیری این کدها‪ ،‬خروجی شما با ورودیِ "‪ "Garfield‬به این صورت‬ ‫آخرین فصل با مشکالت مربوط به این فصل دست و پنجه نرم میکند!‬
‫خواهد بود‪:‬‬ ‫ترکیب و شکل کلی یک برنامهی فرترن به صورت زیر است‪:‬‬
‫?‪What is your name‬‬
‫تیتر برنامه (‪)Heading‬‬ ‫‪‬‬
‫‪Garfield‬‬
‫‪Hi there, Garfield‬‬
‫قسمت اعالنها و تعاریف (‪)Specification Part‬‬ ‫‪‬‬
‫نکات‪:‬‬
‫هیچ وقت از اعالن مناسب طول متغیر کاراکتر غافل نشوید! به خاطر داشته‬ ‫‪‬‬ ‫قسمت اجرایی برنامه (‪)Execution Part‬‬ ‫‪‬‬

‫باشید که فقط در صورتی که یک متغیر کاراکتر به عنوان پارامتر اعالن شده‬ ‫قسمت زیربرنامهها (‪)Sub Program Part‬‬ ‫‪‬‬
‫باشد‪ ،‬میتوان طولش را برابر با * قرار داد؛ که این بدان معناست که طول‬
‫جملهی پایانی برنامه (‪)End Statement Part‬‬ ‫‪‬‬
‫متغیر‪ ،‬دقیقا با طول رشتهای که به آن نسبت داده میشود برابر خواهد شد‪.‬‬
‫البته استفاده از همه ی این موارد اجباری نیست؛ ولی در هر صورت یک برنامهی‬
‫تفاوت طول رشتهای که به یک متغیر کاراکتر نسبت داده میشود و طول‬ ‫‪‬‬
‫کامل باید این موارد را دارا باشد‪.‬‬
‫خودِ متغیر کاراکتر‪ ،‬حائز اهمیت میباشد‪ .‬در صورتی که طول رشته و متغیر‬
‫با هم برابر باشند‪ ،‬رشته عینا درون متغیر قرار میگیرد‪ .‬در صورتی که طول‬ ‫بخش اول – مثالها‬
‫رشته از طول متغیر بیشتر باشد‪ ،‬از سمت راستِ رشته‪ ،‬به اندازهی اختالف‬

‫‪2‬‬
‫‪! Calculates number of accumulated AIDS cases in USA‬‬ ‫طولها حذف شده و سپس رشته درون متغیر قرار میگیرد‪ .‬در نهایت‪ ،‬در‬
‫‪Integer T‬‬ ‫‪!year‬‬
‫‪Real A‬‬ ‫‪!number of cases‬‬ ‫صورتی که طول رشته از طول متغیر کمتر باشد‪ ،‬به اندازهی تفاوت طولها در‬
‫‪Read*, T‬‬
‫‪A = 174.6 * (T - 1981.2) ** 3‬‬ ‫سمت راست رشته جای خالی قرار داده شده و سپس در درون متغیر قرار‬
‫‪Print*, 'Accumulated AIDS cases in US by year', T, ':', A‬‬
‫‪End Program AIDS‬‬ ‫میگیرد‪.‬‬
‫با به کارگیری مقدار ‪ 2222‬در ورودی‪ ،‬خروجی به صورت زیر در میآید‪:‬‬ ‫به دستور چاپی که در خط پنجم آورده شده دقت کنید‪ .‬ببینید که این دستور‬ ‫‪‬‬
‫‪2000‬‬ ‫در خروجی‪ ،‬به کاربر چقدر در ارتباط برقرار کردن با برنامه کمک میکند‪.‬‬
‫‪Accumulated AIDS cases in US by year 2000 : 1.1601688E+06‬‬
‫یعنی با چاپ شدن ?‪ What is your name‬بر روی صفحهی نمایش‪،‬‬
‫نکات‪:‬‬
‫کاربر متوجه می شود که باید نام را وارد کند‪ .‬در غیر این صورت‪ ،‬با اجرای‬
‫یک برنامهی خوب‪ ،‬عالوه بر توضیحات‪ ،‬شامل دستور ‪ Program‬در ابتدا‬ ‫‪‬‬ ‫برنامه‪ ،‬بدون هیچ راهنمایی‪ Cursor ،‬چشمک میزند و کاربر با سر در‬
‫هم میشود که در این برنامه نیز از این دستور استفاده شده است‪ .‬با این کار‪،‬‬ ‫گمی مواجه میشود‪.‬‬
‫عالوه بر توضیحات راجع به برنامه‪ ،‬به آن اسم نیز اختصاص میدهیم‪.‬‬
‫به توضیحاتی (‪ )Comment‬که پیش از شروع کدنویسی در برنامه آورده‬ ‫‪‬‬
‫دقت کنید که این جا حتی برای توضیح راجع به کاربرد متغیرها نیز از‬ ‫‪‬‬ ‫شده توجه کنید‪ .‬این توضیحات اطالعاتی را در ارتباط با برنامه و کاری که‬
‫توضیحات استفاده شده است‪.‬‬ ‫انجام میدهند ارائه میکنند‪ .‬یک برنامهنویس خوب‪ ،‬خودش را مقید میکند‬
‫تسلط در فرمولنویسی بسیار مهم است‪ .‬باید قادر باشید‪ ،‬هر فرمولی را‬ ‫‪‬‬ ‫که چنین توضیحاتی را به کار گیرد!‬
‫کدنویسی کنید‪ .‬در این مثال یک فرمول بسیار ساده که شامل اپراتورهای‬ ‫مثال ‪ )2‬برنامهی زیر تعداد تجمعی (‪ )Accumulated‬موارد مشاهدهشدهی مبتال به‬
‫(‪ )Operator‬تفریق‪ ،‬ضرب و توان میشود را نوشتیم‪.‬‬
‫ایدز (‪ )AIDS‬در ایاالت متحده را در سال ‪ t‬به دست میدهد! برای این منظور از‬
‫در دستورات ‪ Print‬و ‪ Write‬میتوانیم متغیر‪ ،‬رشته‪ ،‬عدد و عبارت چاپ‬ ‫‪‬‬ ‫رابطهی زیر استفاده میکنیم‪:‬‬
‫کنیم‪ .‬لذا در این مثال میتوانستیم از متغیر ‪ A‬استفاده نکنیم و به جای اینکه‬ ‫) (‬ ‫(‬ ‫)‬
‫عبارت ‪ 174.6 * (T - 1981.2) ** 3‬را به ‪ A‬نسبت دهیم و سپس ‪ A‬را‬
‫‪Program AIDS‬‬

‫‪3‬‬
‫‪! Display Velocity and Height‬‬ ‫چاپ کنیم‪ ،‬خود عبارت را چاپ کنیم‪ .‬یعنی شکل دستور چاپ به صورت‬
‫‪Print*, "At Time", Time, "The Vertical Velocity is", Velocity‬‬
‫‪Print*, "and the Height is", Height‬‬ ‫زیر درمیآمد‪:‬‬
‫‪End Program Projectile‬‬
‫& '‪Print*, 'Accumulated AIDS cases in US by year', T, ':‬‬
‫نکات‪:‬‬ ‫‪174.6 * (T - 1981.2) ** 3‬‬

‫برای خوانا بودن فرمولها و روابط‪ ،‬همیشه بین عملگرها و عملوندها‬ ‫‪‬‬ ‫منتها اصول برنامهنویسی حکم میکند که عبارات را به متغیرها نسبت دهیم و‬
‫(‪ )Operand‬یک فاصله (‪ )Space‬قرار میدهیم‪ .‬در کل مرتب و منظم‬ ‫سپس متغیرها را چاپ کنیم‪.‬‬
‫نوشتن‪ ،‬به مرتب کردن ذهن و فکر برنامهنویس هم کمک خواهد کرد‪ .‬در‬ ‫مثال‪ )3‬برنامهی زیر‪ ،‬سرعت (‪ )Velocity‬و ارتفاع (‪ )Height‬یک پرتابه‬
‫فصول ابتدایی که حجم کدنویسی برنامهها کم است‪ ،‬خیلی این امر را حس‬ ‫(‪ )Projectile‬را در یک زمان مشخص به ما میدهد‪ .‬در واقع ورودیهای ما زمان‪،‬‬
‫نخواهید کرد‪ .‬ولی به مرور زمان و جلو رفتن در فصول و زیاد شدن حجم‬ ‫ارتفاع اولیه (‪ )Initial Height‬و سرعت اولیه (‪ ،)Initial Velocity‬و خروجی‪،‬‬
‫کدنویسیها‪ ،‬خودتان به این مساله واقف خواهید شد‪ .‬البته اگر از االن‬ ‫سرعت و ارتفاع پرتابه است‪.‬‬
‫خودتان را عادت ندهید که مرتب کدنویسی کنید‪ ،‬مطمئنا بعدا نمیتوانید این‬ ‫‪Program Projectile‬‬
‫عادت را در خودتان ایجاد کنید!‬ ‫‪! This Program Calculates the Velocity and Height of a‬‬
‫‪! Projectile‬‬
‫‪! Given its Initial Height, Initial Velocity and Constant‬‬
‫استفاده از عبارات انگلیسی در خروجی (به رشتههایی که در چاپ به کار‬ ‫‪‬‬ ‫‪! Acceleration.‬‬
‫‪Implicit None‬‬
‫گرفته شدهاند دقت کنید)‪ ،‬به کاربر در تشخیص اینکه اطالعات موجود‬ ‫& ‪Real :: Initial_Hight, Height, Initial_Velocity, Velocity,‬‬
‫مربوط به چه چیزی است‪ ،‬بسیار کمک خواهد کرد‪.‬‬ ‫‪Time, Acceleration = -9.807‬‬
‫‪! Obtain Values for Initial Height, Initial Velocity and‬‬
‫‪! Time‬‬
‫فراموش نکنید که به جز اعداد و حروف انگلیسی‪ ،‬فقط استفاده از "_"‬ ‫‪‬‬ ‫"‪Print*, "Enter the Initial Height and Velocity:‬‬
‫‪Read*, Initial_Height, Initial_Velocity‬‬
‫(‪ )Underline‬در نام متغیر مجاز است‪.‬‬ ‫& ‪Print*, "Enter Time at Which to Calculate Height and‬‬
‫"‪Velocity:‬‬
‫در این برنامه‪ ،‬تا حد ممکن‪ ،‬نام متغیرها با کاری که انجام میدهند متناسب‬ ‫‪‬‬ ‫‪Read*, Time‬‬
‫‪! Calculate the Height and Velocity‬‬
‫است‪ .‬این امر برنامهنویس را به دنبال کردن و مرور مجدد برنامه بسیار کمک‬
‫& ‪Height = 0.5 * Acceleration * Time ** 2 + Initial_Velocity‬‬
‫خواهد کرد‪ .‬البته در این برنامه‪ ،‬نام متغیرها بیش از حد طوالنی هستند و‬ ‫‪* Time + Initial_Height‬‬
‫‪Velocity = Acceleration * Time + Initial_Velocity‬‬
‫‪4‬‬
‫بنابراین از رابطهی فوق‪ ،‬با داشتن مادهی اولیه‪ ،‬مادهی در دسترس و ضریب واپاشی‪،‬‬ ‫میشد از نامهای کوتاهتری استفاده کرد؛ ولی در هر صورت سعی کنید نام‬
‫میتوان زمان واپاشی مادهی رادیواکتیو (سن ماده) را به دست آورد‪:‬‬ ‫متغیرها در عین اختصار‪ ،‬به کاربرد متغیر نیز اشاره داشته باشند‪.‬‬

‫در این برنامه دستور ‪ Implicit None‬به کار گرفته شده است‪ .‬همانطوری‬ ‫‪‬‬

‫که میدانید با به کارگیری این دستور‪ ،‬تمامی متغیرها باید اعالن شوند و در‬
‫حال میخواهیم برنامهای بنویسیم که درصد کربن ‪ 14‬باقیمانده در یک نمونه‬ ‫صورت استفاده از متغیری که اعالن نشده‪ ،‬برنامه خطا خواهد گرفت‪ .‬توصیه‬
‫(درصد مادهی فعلی به ماده ی اولیه) را بخواند و سپس سن نمونه را محاسبه و به شکل‬ ‫میشود که به منظور جلوگیری از وقوع خطاهای احتمالی‪ ،‬همیشه از این‬
‫مناسب چاپ نماید (ضریب واپاشی برای کربن ‪ 14‬برابر ‪ 0.000127097‬با واحد‬ ‫دستور در برنامههای خود استفاده کنید‪.‬‬
‫سال‪ 1/‬است)‪.‬‬
‫چنانچه بخواهیم ادامه ی یک خط را در خطوط بعد قرار دهیم‪ ،‬باید از‬ ‫‪‬‬
‫‪Program C14_Date‬‬
‫‪! A Program to Calculate the Age of an Organic Sample from‬‬ ‫عالمت "&" (‪ )Ampersand‬به یکی از دو صورت زیر استفاده کنیم‪:‬‬
‫‪! the Percentage of the Original Carbon 14 Remaining in the‬‬
‫‪! Sample.‬‬ ‫‪ .1‬عالمت "&" در انتهای خط قبل قرار میگیرد‪.‬‬
‫‪Implicit None‬‬
‫‪! Declare the Constants which are Used in This Program.‬‬
‫‪Real, Parameter :: Lambda = 0.000127097 !The Radio Activity‬‬
‫‪ .2‬عالمت "&" در انتهای خط قبل و ابتدای خط بعد قرار میگیرد‪.‬‬
‫‪!Decay Constant of‬‬
‫‪!Carbon 14, in Units‬‬ ‫مثال ‪ )4‬همانطوری که از قبل به یاد داریم‪ ،‬ایزوتوپ رادیواکتیو یک عنصر‪ ،‬شکلی‬
‫‪!of 1/Years‬‬
‫‪! Declare the Variables Which are Used in This Program.‬‬ ‫از عنصر است که پایدار نیست‪ .‬بنابراین در یک دورهی زمانی‪ ،‬برای رسیدن به پایداری‪،‬‬
‫‪Real :: Age‬‬ ‫‪!The Age of Sample in Year‬‬
‫‪Real :: Percent‬‬ ‫‪!The Percentage of Carbon 14‬‬ ‫به یک عنصر دیگر واپاشی میشود‪ .‬در اینصورت واپاشی رادیواکتیو به صورت یک‬
‫‪!Remaining at the Time‬‬
‫‪Real :: Ratio‬‬ ‫‪!The Ratio of Carbon 14‬‬
‫تابع نمایی بیان میشود‪:‬‬
‫‪!Remaining at the time of the‬‬
‫‪!Measurement to the Original‬‬ ‫) (‬
‫‪!Amount of Carbon 14‬‬
‫‪! Prompt the User for the Percentage of Carbon 14 Remaining.‬‬ ‫مقدار مادهی‬ ‫مقدار مادهی اولیه در زمان ‪ t = 0‬و‬ ‫که در آن ثابت واپاشی‪،‬‬
‫"‪Write (*,*) "Enter the Percentage of Carbon 14 Remaining:‬‬
‫‪Read (*,*) Percent‬‬ ‫موجود در زمان ‪ t‬است‪.‬‬
‫‪! Echo the User’s Input Value‬‬
‫"‪Write (*,*) "The Remaining Carbon 14 = ", Percent, "%‬‬
‫‪5‬‬
‫در این مساله هم مشخص بود‪ ،‬اول روی روابط و فرمول به دست آوردن‬ ‫‪! Perform Calculations‬‬
‫‪Ratio = Percent / 100.‬‬ ‫‪!Convert to Fractional Ratio‬‬
‫جواب بحث کردیم و بعد شروع به کدنویسی کردیم‪.‬‬ ‫)‪Age = (-1.0 / Lambda) * Log (Ratio‬‬ ‫‪!Get Age in Years‬‬
‫‪! Tell the User About the Age of the Sample.‬‬
‫"‪Write (*,*) "The Age of the Sample is", Age, "Years.‬‬
‫فراموش نکنید که همیشه از برنامهی نوشته شدهتان به کمک ورودیهای‬ ‫‪‬‬
‫‪! Finish up‬‬
‫مختلف‪ ،‬خروجی بگیرید و با چک کردن جوابها‪ ،‬از صحت عملکرد برنامه‬ ‫‪End Program C14_Date‬‬

‫مطمئن شوید؛ زیرا همواره ممکن است اشتباهات ناخواسته یا پیشبینی‬ ‫نکات‪:‬‬
‫نشدهای رخ دهد که مانع از عملکرد صحیح برنامه شود‪.‬‬ ‫عالوه بر نکات کدنویسی که در مثالهای قبل ذکر شد‪ ،‬یک نکتهی جالب‬ ‫‪‬‬

‫مجددا فرمولنویسی در این مساله نیز اهمیت پیدا میکند‪ .‬یکی از لوازم‬ ‫‪‬‬ ‫هم در این برنامه به کار گرفته شده است‪ .‬به خط شانزدهم و هفدهم کدها‬
‫توانایی در نوشتن فرمولها‪ ،‬تسلط به توابع کتابخانهای فرترن و آرگومانهای‬ ‫نگاه کنید‪ .‬در اینجا به کمک یک دستور چاپ‪ ،‬دادهای که خود کاربر وارد‬
‫آنها میباشد (مثال در همین مساله از تابع )‪ Log (x‬که به معنای لگاریتم در‬ ‫کرده‪ ،‬بالفاصله برایش چاپ میشود! مزیت این کار در آن است که کاربر‪،‬‬
‫پایهی عدد نپر میباشد و یک تابع کتابخانهای است استفاده کردیم‪ .).‬توابع‬ ‫از صحت وارد شدن دادهی مورد نظر اطمینان حاصل میکند‪ .‬به این ترتیب‪،‬‬
‫کتابخانهای متفاوتی در کتابهای مرجع فرترن موجود است ولی چندین تابع‬ ‫در این برنامهی آخر‪ ،‬میتوان یک برنامهی خوب و کامل را دید که شامل‬
‫ریاضی کتابخانهای مهم در اکثر کتابها آورده نشده و در ‪ Help‬فرترن‬ ‫نام برنامه‪ ،‬توضیحات اولیه برای توضیح راجع به عملکرد برنامه‪ ،‬دستورات‬
‫میتوان آنها را پیدا کرد که در اینجا چند نمونه را آوردهام‪:‬‬ ‫کامل همراه با خروجیهای مناسب برای برقراری ارتباط با کاربر و‬
‫توضیحات جامع راجع به هر قسمت کدنویسی میشود‪.‬‬
‫‪ -‬توابع سینوس‪ ،‬کسینوس و تانژانت با آرگومان ورودی بر حسب‬
‫درجه‪:‬‬ ‫در تمام مسائلی که برایشان برنامه مینویسید (اعم از مسـائل ریاضـی‪،‬‬ ‫‪‬‬

‫مهندسـی و ‪ )...‬باید به روش حل مساله تسلط کامل داشته باشید تا بتوانید‬


‫)‪Sind (x), Cosd (x), Tand (x‬‬
‫برنامهی آنها را بنویسید‪ .‬مثال در همین مسالهی آخر‪ ،‬شما در صورتی‬
‫‪ -‬توابع سینوسهایپربولیک‪ ،‬کسینوسهایپربولیک و‬
‫میتوانید یک برنامه برای پیدا کردن زمان واپاشی بنویسید که خودتان به‬
‫تانژانتهایپربولیک‪:‬‬
‫صورت تئوری‪ ،‬بر روش حل و روابط این مساله مسلط باشید‪ .‬همانطور که‬
‫)‪Sinh (x), Cosh (x), Tanh (x‬‬

‫‪6‬‬
‫و ‪ H‬برابر با کشش افقی کابل در نقطهی زیرین‬ ‫محاسبه میشود که در آن‬ ‫دقت کنید که آرگومان تمامی توابع فوق باید حقیقی (‪ )Real‬باشد‪.‬‬
‫کابل میباشد‪ .‬برنامهای بنویسید که مقادیر ‪ H ،W‬و ‪ x‬را از ورودی بگیرد و مقدار ‪y‬‬
‫بخش دوم – تمارین‬
‫متناظر را محاسبه و چاپ نماید‪.‬‬
‫(و‬ ‫تمرین ‪ )1‬همانطور که میدانید‪ ،‬فاصلهی بین دو نقطه به مختصات )‬
‫تمرین ‪ )4‬قرار است یک تانکر نفت به شکل یک استوانه که دارای کالهک‬
‫( در دستگاه مختصات دکارتی از رابطهی زیر به دست میآید‪:‬‬ ‫)‬
‫مخروطی است‪ ،‬ساخته شود‪ .‬ارتفاع مخروط برابر با شعاع استوانه است و ظرفیت کل‬
‫تانکر (شامل قسمت استوانهای) برابر با ‪ 522‬متر مکعب است‪ .‬برای ساختن هر متر مربع از‬ ‫(√‬ ‫)‬ ‫(‬ ‫)‬
‫بدنهی استوانهی این تانکر ‪ 322‬دالر و برای ساختن هر متر مربع از بدنهی مخروط‪422 ،‬‬ ‫را از ورودی‬ ‫برنامهای بنویسید که طول و عرض دو نقطه یعنی‬
‫دالر هزینه میشود‪ .‬برنامهای بنویسید که شعاع قاعدهی استوانه را گرفته و با توجه به‬ ‫گرفته و فاصلهی آنها از یکدیگر را محاسبه و به شکل مناسبی چاپ نماید‪.‬‬
‫حجم مخزن‪ ،‬ارتفاع استوانه و نیز هزینهی ساخت تانکر را محاسبه نماید‪ .‬برنامهی خود را‬ ‫تمرین ‪ )2‬پریود یک پاندول از رابطهی‬
‫برای مقادیر مختلف شعاع (از شعاع ‪ 4‬متر شروع کنید) اجرا کنید و هر بار مقدار کمی به‬
‫شعاع اضافه و یا کم کنید تا تعیین شود که چه شعاعی از مخزن‪ ،‬کمترین هزینهی ساخت‬
‫( √‬ ‫)) (‬
‫را دارد‪.‬‬
‫‪ L ،‬طول پاندول به سانتیمتر و ‪ a‬زاویهی‬ ‫محاسبه میشود که در آن‬
‫‪a‬‬
‫جابجایی است‪ .‬برنامهای بنویسید که مقدار ‪ L‬و ‪ a‬را از ورودی بگیرد و پریود را محاسبه‬
‫و به شکل مناسبی نمایش دهد‪ .‬برنامه را برای مقادیر زیر اجرا کنید‪.‬‬

‫‪L = 120, a = 15 )3 L = 60, a = 5 )2‬‬ ‫‪L = 83.6, a = 12 )1‬‬


‫=‪V‬‬ ‫‪h‬‬
‫‪500 m3‬‬
‫تمرین ‪ )3‬معادلهی انحنای یک کابل که وزن آن ‪ w‬کیلو در هر متر است با رابطهی‬

‫‪7‬‬
‫را در نظر بگیرید‪ .‬برنامهای‬ ‫تمرین ‪ )5‬معادلهی‬
‫بنویسید که ضرایب این معادله را از ورودی بگیرد و در خروجی فرم کلی معادله را به‬
‫نحوی که میسر است چاپ نماید!‬

‫تمرین ‪ )6‬تیر سادهی ‪ AB‬به طول ‪ ،L‬تحت بارگذاری زیر مفروض است‪ .‬برنامهای‬
‫بنویسید که مقادیر ‪ L ،P‬و ‪ a‬را از ورودی بگیرد و مقدار حداکثر لنگر خمشی را‬
‫محاسبه و چاپ نماید (پیشنیاز‪ :‬استاتیک!)‪.‬‬

‫‪a‬‬
‫‪P‬‬

‫‪A‬‬ ‫‪B‬‬
‫‪L‬‬

‫‪8‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫|√‬ ‫|‬ ‫فصل دوم (ساختارهای کنترلی)‬


‫برای توضیحات بیشتر به جزوهی ریاضیات عمومی مراجعه شود!‬ ‫بخش اول – مثالها‬
‫‪Program Roots‬‬
‫‪Implicit None‬‬ ‫تمام مطالب این فصل‪ ،‬به طور کامل در فصول دیگر به کار گرفته خواهند شد‪ .‬لذا‬
‫‪! Declare the Variables Used in this Program‬‬
‫‪Real :: A‬‬ ‫‪!Coefficient of x ** 2 Term of Equation‬‬ ‫عدم تسلط به ساختارهای کنترلی (ترکیبهای مختلف حلقه‪ ،‬ترکیبهای مختلف شرط‬
‫‪Real :: B‬‬ ‫‪!Coefficient of x Term of Equation‬‬
‫‪Real :: C‬‬ ‫‪!Constant Term of Equation‬‬ ‫و ترکیب های مختلف حلقه و شرط) باعث ایجاد مشکالت زیادی در تمام فصول بعد‬
‫‪Real :: Delta !b ** 2 – 4 * a * c‬‬
‫‪Real :: Image_Part !Imaginary Part of Complex Roots‬‬
‫خواهد شد؛ مخصوصا در فصل آرایهها که بحث حلقههای ضمنی‪ ،‬ترکیب حلقههای‬
‫‪Real :: Real_Part !Real Part of Complex Roots‬‬ ‫ضمنی با یکدیگر و ترکیب حلقههای صریح و ضمنی مطرح خواهد شد‪ .‬بنابراین در این‬
‫‪Real :: X1‬‬ ‫‪!First Solution of Equation‬‬
‫‪Real :: X2‬‬ ‫‪!Second Solution of Equation‬‬ ‫فصل‪ ،‬تا جایی که میتوانید مثالهای متنوع از آسان به سخت حل کنید و تکنیکهای‬
‫‪! Prompt User for the Coefficients of Equation‬‬
‫"‪Write (*,*) "This Program Solves for the Roots of Quadratic‬‬ ‫حل مسالههای مختلف را بیاموزید‪ .‬بدیهی است که جزوهی حاضر و مثالها و تمارین‬
‫"‪Write (*,*) "Equation of Form a * x ** 2 + b * x + c = 0.‬‬
‫"‪Write (*,*) "Enter the Coefficients a, b and c:‬‬ ‫آن‪ ،‬نمیتواند جوابگوی گستردگی این فصل باشد؛ لذا به هیچ عنوان از کتابها و‬
‫‪Read (*,*) A, B, C‬‬
‫‪! Echo Back Coefficients‬‬ ‫مراجع مختلف غافل نشوید‪.‬‬
‫‪Write (*,*) "The Coefficients a, b and c are:", A, B, C‬‬
‫‪! Calculate b ** 2 – 4 * a * c‬‬ ‫مفروض است‪ .‬میخواهیم ضرایب این‬ ‫مثال ‪ )1‬معادلهی‬
‫‪Delta = b ** 2 – 4 * a * c‬‬
‫‪! Solving Roots, Depending upon the Value of Delta‬‬ ‫معادلهی درجهی دوم (‪ )Quadratic Equation‬را از ورودی بخوانیم و ریشههای آن‬
‫‪If (Delta .GT. 0) Then‬‬ ‫…‪!There are Two Real Roots, So‬‬
‫)‪X1 = (-B + Sqrt (Delta)) / (2. * A‬‬ ‫را‪ ،‬خواه حقیقی متمایز‪ ،‬حقیقی مضاعف یا مختلط‪ ،‬به دست آوریم‪.‬‬
‫)‪X2 = (-B - Sqrt (Delta)) / (2. * A‬‬
‫"‪Write (*,*) "The Equation Has Two Real Roots:‬‬ ‫‪ ،‬از دو متغیر حقیقی استفاده میکنیم‬ ‫برای به دست آوردن ریشهی مختلطِ‬
‫‪Write (*,*) "X1 = ", X1‬‬
‫‪Write (*,*) "X2 = ", X2‬‬ ‫که یکی را به عنوان قسمت حقیقی و دیگری را به عنوان قسمت موهومی به کار میبریم‪.‬‬
‫…‪Else If (Delta .EQ. 0) Then !There is One Repeated Root, So‬‬
‫)‪X1 = (-B) / (2. * A‬‬ ‫در این صورت برای به دست آوردن قسمت حقیقی و موهومی داریم‪:‬‬
‫& ‪Write (*,*) "This Equation Has Two Identical Real‬‬
‫"‪Roots:‬‬
‫‪Write (*,*) "X1 = X2 = ", X1‬‬

‫‪9‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل دوم (ساختارهای کنترلی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫‪ Delta‬روش حل مساله فرق میکند‪ ،‬در درون شرط‪ ،‬متغیر ‪ Delta‬مورد‬ ‫‪Else‬‬ ‫…‪!There are Complex Roots, So‬‬
‫)‪Real_Part = (-B) / (2. * A‬‬
‫بررسی قرار گرفت‪.‬‬ ‫)‪Image_Part = Sqrt (Abs (Delta)) / (2. * A‬‬
‫"‪Write (*,*) "This Equation Has Complex Roots:‬‬
‫‪Write (*,*) "X1 = ", Real_Part, " + i", Image_Part‬‬
‫به طور کلی‪ ،‬اول باید با هوشمندی تمام بررسی کرد که کدام متغیر(ها) است‬ ‫‪Write (*,*) "X2 = ", Real_Part, " - i", Image_Part‬‬
‫(هستند) که با تغییر محتوایش (محتوایشان)‪ ،‬روش حل مساله فرق میکند‪.‬‬ ‫‪End If‬‬
‫‪End Program‬‬
‫سپس با کمک شرط‪ ،‬باید حالتهای آن متغیر(ها) را بررسی کرد و برای هر‬
‫نکات‪:‬‬
‫حالت‪ ،‬روش حل مناسب را به کار گرفت‪.‬‬
‫‪ ‬از این به بعد سعی میشود در تمامی فصول‪ ،‬نکات برنامهنویسی که در فصل‬
‫مثال ‪ )2‬تابع دو متغیرهی زیر مفروض است‪.‬‬
‫اول برای یک برنامهی کامل ذکر شد رعایت شود؛ مثل استفاده از دستور‬
‫‪ Program‬در ابتدا‪ ،‬استفاده از توضیحات برای ارائهی اطالعات راجع به‬
‫(‬ ‫)‬ ‫عملکرد متغیرها‪ ،‬به کار بردن عبارات مناسب در خروجی برای برقراری‬
‫{‬ ‫ارتباط با کاربر و ‪. ...‬‬
‫میخواهیم برنامهای بنویسیم که مقادیر ‪ x‬و ‪ y‬را از ورودی بگیرد و سپس به کمک‬ ‫‪ ‬مشابه موردی که در فصل اول اشاره شد‪ ،‬برای خوانا شدن برنامه‪ ،‬سعی کنید‬
‫ضابطهی تابع‪ ،‬مقدار تابع را حساب نماید‪.‬‬ ‫مرتب و منظم کدنویسی کنید‪ .‬به خصوص در جاهایی که شرط یا حلقه‬
‫‪Program Funxy‬‬ ‫دارید‪ ،‬به صورت پلهای کدنویسی کنید‪ .‬مثال سعی کنید همیشه دستورات‬
‫‪Implicit None‬‬
‫‪! Declare the Variables Used in this Program‬‬ ‫اجرایی شرط و حلقه‪ ،‬یک پله جلوتر نوشته شوند (برای مثال میتوانید از‬
‫‪Real :: X‬‬ ‫‪!First Independent Variable‬‬
‫‪Real :: Y‬‬ ‫‪!Second Independent Variable‬‬ ‫کلید ‪ Tab‬روی صفحهکلید کمک بگیرید‪.).‬‬
‫‪Real :: Fun !Resulting Function‬‬
‫‪! Prompt the User for the Values x and y‬‬ ‫‪ ‬تنها نکتهای که در این برنامه وجود دارد آن است که سه حالت مختلفی که‬
‫"‪Write (*,*) "Enter Values for x and y:‬‬
‫‪Read (*,*) X, Y‬‬ ‫برای به دست آوردن ریشههای معادلهی درجهی دو ممکن است اتفاق بیفتد‪،‬‬
‫‪! Echo Back x and y‬‬
‫‪Write (*,*) "x and y are:", X, Y‬‬ ‫ب کمک شرط بررسی شد‪ .‬منتها دقت کنید که چون با مقادیر مختلف متغیر‬
‫‪! Calculate the Function f(x, y) Based upon the Signs of‬‬
‫‪! x and y‬‬

‫‪12‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪! Ask for a Number Until 1, 2, or 3 Has been Entered‬‬ ‫‪If ((X .GE. 0.) .AND. (Y .GE.‬‬ ‫‪0.)) then‬‬
‫‪Endless : Do‬‬ ‫‪Fun = X + Y‬‬
‫" ‪Print*, "Enter a Number Between 1 and 3:‬‬ ‫‪Else If ((X .GE. 0.) .AND. (Y‬‬ ‫‪.LT. 0.)) Then‬‬
‫‪Read*, N‬‬ ‫‪Fun = X + Y ** 2‬‬
‫)‪Select Case (N‬‬ ‫‪Else If ((X .LT. 0.) .AND. (Y‬‬ ‫‪.GE. 0.)) Then‬‬
‫)‪Case (1‬‬ ‫‪Fun = X ** 2 + Y‬‬
‫"‪Print*, "You Entered 1‬‬ ‫‪Else‬‬
‫‪Exit Endless‬‬ ‫‪Fun = X ** 2 + Y ** 2‬‬
‫)‪Case (2‬‬ ‫‪End If‬‬
‫"‪Print*, "You Entered 2‬‬ ‫‪! Write the Value of Function‬‬
‫‪Exit Endless‬‬ ‫‪Write (*,*) "The Value of the‬‬ ‫‪Function is:", Fun‬‬
‫)‪Case (3‬‬ ‫‪End Program‬‬
‫"‪Print*, "You Entered 3‬‬
‫‪Exit Endless‬‬ ‫نکات‪:‬‬
‫‪Case Default‬‬
‫& ‪Print*, "Number is not Between 1‬‬ ‫‪ ‬این مثال دقیقا نشاندهندهی آن است که دو متغیر (یا حتی بیشتر) میتوانند‬
‫"‪and 3‬‬
‫‪End Select‬‬ ‫در روش حل مساله دخیل باشند‪ .‬بنابراین باید همهی متغیرهای دخالت کننده‬
‫‪End Do Endless‬‬
‫‪End Program Case_Example‬‬ ‫را شناسایی کرد‪ .‬البته مثالی که حل شد و مثالهای مشابه فوقالعاده راحت‬
‫نکات‪:‬‬ ‫هستند و شناسایی این متغیرها بسیار ساده است؛ ولی همهی مسائل لزوما‬
‫اینقدر ساده نیستند!‬
‫‪ ‬متغیری که با ساختار ‪ Select Case‬آنرا بررسی میکنیم (‪،)Selector‬‬
‫میتواند صحیح‪ ،‬کاراکتر و منطقی باشد و نمیتواند حقیقی باشد؛ بنابراین‬ ‫مثال ‪ )3‬میخواهیم به کمک ساختار ‪ ،Select Case‬برنامهای بنویسیم که یک‬
‫اگر خواستید به عنوان ‪ Selector‬یک متغیر حقیقی را بررسی کنید‪ ،‬اول باید‬ ‫عدد صحیح را در درون یک حلقهی با تکرار نامعلوم بخوانیم (یعنی دستور خواندن‬
‫آنرا موقتا به کمک توابع ذاتی )‪ Int (x‬یا )‪ NInt (x‬به صورت صحیح در‬ ‫درون حلقه است‪ .).‬اگر عدد یک‪ ،‬دو یا سه باشد‪ ،‬خود عدد به همراه یک پیغام مناسب‬
‫بیاورید‪.‬‬ ‫چاپ میشود و از حلقه خارج میشویم و اگر هر عدد دیگری وارد شود‪ ،‬فقط یک پیغام‬

‫اگر در مساله ای مجبور بودید که دقیقا مقادیر حقیقی را بررسی کنید و مجاز‬ ‫مبتنی بر اینکه عدد بین یک و سه نیست چاپ میشود‪.‬‬

‫به تبدیل آنها به مقادیر صحیح نبودید‪ ،‬ناچارا باید از ساختار ‪Select Case‬‬ ‫‪Program Case_Example‬‬
‫‪Implicit None‬‬
‫صرف نظر کنید و از ساختار ‪ If‬استفاده نمایید‪.‬‬ ‫‪Integer :: N‬‬

‫‪11‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل دوم (ساختارهای کنترلی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫نام دادیم‪ ،‬باید در انتهای بلوک حلقه یا شرط‪ ،‬جلوی عبارات ‪ End Do‬یا‬ ‫در اینجا هم مانند ساختار ‪ ،If‬باید ‪ Selector‬را با هوشمندی کامل انتخاب کرد‪.‬‬ ‫‪‬‬
‫‪ ،End If‬نام انتخابی حلقه یا شرط را هم بیاوریم و عدم انجام این کار باعث‬ ‫یعنی باید بررسی نمود و متغیری که با تغییرش روش حل مساله تغییر میکند را پیدا‬

‫ایجاد خطا میشود‪.‬‬ ‫کرد‪.‬‬

‫‪ ‬از دستور ‪ Exit‬که خاص حلقه میباشد‪ ،‬برای خارج شدن از حلقه استفاده‬ ‫‪ ‬جدول زیر را برای مقایسهی مقادیر عددی به خاطر داشته باشید‪.‬‬

‫میشود‪ .‬چون حلقه دارای نام است‪ ،‬جلوی دستور ‪ Exit‬نام حلقه هم آورده‬ ‫برچسب‬ ‫معنی‬
‫شده است؛ ولی در دستورات ‪ Cycle ،Exit‬و ‪ ،Stop‬آوردن نام حلقه‬
‫‪:x‬‬ ‫تمام مقادیر ≤ ‪x‬‬
‫اجباری نیست‪.‬‬
‫‪x:‬‬ ‫تمام مقادیر ≥ ‪x‬‬
‫مثال ‪ )4‬میخواهیم برنامهای برای محاسبهی میانگین و انحراف معیار تعدادی عدد‬
‫‪x:y‬‬ ‫تمام مقادیر بین ‪ x‬و ‪)x ≤ y( y‬‬
‫بنویسیم‪ .‬همانطور که میدانیم‪ ،‬میانگین و انحراف معیار (در صورتی که کمتر از سی‬
‫داده داشته باشیم) از روابط زیر به دست میآیند‪.‬‬ ‫‪x‬‬ ‫خود مقدار ‪x‬‬

‫∑‬ ‫‪ ‬فراموش نکنید در صورتی که ‪ Selector‬از نوع کاراکتر باشد‪ ،‬در داخل هر‬
‫̅‬
‫‪ ،Case‬باید یک رشته تحت بررسی قرار گیرد‪ .‬مثال باید داشته باشیم‪:‬‬
‫(‬ ‫)̅‬ ‫)"‪Case ("Dangerous‬‬
‫√‬
‫در غیر اینصورت برنامه با خطا مواجه میشود‪.‬‬
‫∑‬ ‫) ∑(‬ ‫‪ ‬همانطوری که مشاهده میفرمایید‪ ،‬هر حلقه یا شرط‪ ،‬میتواند به صورت‬
‫√‬
‫(‬ ‫)‬
‫اختصاصی دارای یک نام باشد (به صورت مشابه‪ ،‬ساختار ‪ Select Case‬هم‬
‫در این مساله‪ ،‬برای محاسبهی انحراف معیار‪ ،‬از رابطهی دوم استفاده میکنیم (به نظر‬ ‫میتواند دارای نام باشد‪).‬؛ به این صورت که قبل از کلیدواژههای ‪ Do‬یا ‪،If‬‬
‫شما چرا؟) و آنرا با در نظر گرفتن شرایط زیر مینویسیم‪:‬‬ ‫باید نام حلقه یا شرط را بنویسیم و نام را از ‪ Do‬یا ‪ If‬به کمک "‪ ":‬جدا کنیم‬
‫‪ .1‬اعداد ورودی فقط میتوانند مثبت یا صفر باشند‪.‬‬ ‫(به حلقه ی همین مثال نگاه کنید‪ .).‬فقط فراموش نکنید که اگر به حلقه یا شرط‬

‫‪12‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪If (N .LT. 2) Then !Insufficient Information‬‬ ‫‪ .2‬تعداد اعداد ورودی نامعلوم است و فقط در صورت وارد کردن یک عدد‬
‫"!‪Write (*,*) "At Least Two Values Must be Entered‬‬
‫‪Else !There is Enough Information, So Start Calculation‬‬ ‫منفی‪ ،‬برنامه خواندن اعداد را متوقف کرده و به انجام محاسبات روی اعداد‬
‫‪X_Bar = Sum_X / N‬‬
‫& ‪Std_Dev = Sqrt (N * Sum_X2 – Sum_X ** 2) / (N * (N‬‬ ‫خوانده شده میپردازد‪.‬‬
‫))‪– 1‬‬
‫‪!Tell User‬‬ ‫‪ .3‬حداقل باید دو داده خوانده شده باشد؛ در غیر اینصورت‪ ،‬یک پیغام خطای‬
‫‪Write (*,*) "The Mean is:", X_Bar‬‬
‫‪Write (*,*) "The Standard Deviation is:", Std_Dev‬‬ ‫مناسب چاپ می شود و بدون انجام محاسبات‪ ،‬برنامه به اتمام می رسد (زیرا‬
‫‪End If‬‬
‫‪End Program‬‬ ‫در صورتی که کمتر از دو داده داشته باشیم‪ ،‬مخرج در انحراف معیار صفر یا‬
‫نکات‪:‬‬ ‫منفی میشود‪.).‬‬

‫‪ ‬همانطور که میدانید‪ ،‬حلقهها شامل حلقههای با تکرار معلوم و حلقههای با‬ ‫‪Program Stats‬‬
‫‪Implicit None‬‬
‫تکرار نامعلوم میشوند‪ .‬مسلما در حلقههای با تکرار معلوم‪ ،‬حلقه با تکرارِ در‬ ‫‪! Declare the Variables Used in this Program‬‬
‫‪Integer :: N = 0‬‬ ‫‪!The Number of Input Values‬‬
‫نظر گرفته شده انجام میشود؛ ولی در حلقه با تکرار نامعلوم‪ ،‬اگر تدبیری در‬ ‫‪Real :: Std_Dev = 0. !The Standard Deviation of Input Values‬‬
‫‪Real :: Sum_X = 0.‬‬ ‫‪!The Sum of Input Values‬‬
‫نظر گرفته نشده باشد‪ ،‬حلقه بینهایت دفعه تکرار میشود که این (تقریبا‬ ‫‪Real :: Sum_X2 = 0. !The Sum of Squares of Input Values‬‬
‫‪Real :: X = 0.‬‬ ‫‪!An Input Data Value‬‬
‫هیچ وقت) مطلوب نیست‪ .‬بنابراین همیشه باید مکانیزمی برای خارج شدن از‬ ‫‪Real :: X_Bar = 0.‬‬ ‫‪!The Average of Input Values‬‬
‫‪! Using a Loop to Read Input Values‬‬
‫حلقههای با تکرار نامعلوم در نظر گرفته شود‪ .‬به این منظور دو راه وجود دارد‬ ‫‪Do‬‬
‫‪!Read in Next Value‬‬
‫که برنامهنویس‪ ،‬با توجه به ویژگیهای خودش در برنامهنویسی‪ ،‬یکی را‬ ‫"‪Write (*,*) "Enter Number:‬‬
‫انتخاب مینماید‪:‬‬ ‫‪Read (*,*) X‬‬
‫‪!Echo Back Input‬‬
‫‪Write (*,*) "The Number is:", X‬‬
‫‪ .1‬استفاده از بلوک ‪ If‬درون حلقه‪ ،‬به طوری که اگر شرط درون ‪If‬‬ ‫‪!Test for Loop Exit‬‬
‫‪If (X .LT. 0) Exit‬‬
‫محقق شود‪ ،‬کنترل به کمک دستور ‪ Exit‬از حلقه خارج شود و تا‬ ‫‪!Otherwise, Accumulate Sums‬‬
‫وقتی که شرط درون ‪ If‬محقق نشده است‪ ،‬حلقه دائما انجام‬ ‫‪N = N + 1‬‬
‫‪Sum_X = Sum_X + X‬‬
‫میپذیرد‪.‬‬ ‫‪Sum_X2 = Sum_X2 + X ** 2‬‬
‫‪End Do‬‬
‫‪! Check to See If We Have Enough Input Data‬‬

‫‪13‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل دوم (ساختارهای کنترلی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫استفاده از ترکیب حلقهها و شرطها‪ ،‬کمترین سطح مهارتی است که باید‬ ‫‪ .2‬استفاده از بلوک ‪ Do While‬به طوری که فقط تا وقتی که شرط‬
‫داشته باشید‪.‬‬ ‫مربوط به ‪ Do While‬برقرار باشد‪ ،‬حلقه انجام شده و در غیر‬

‫‪ ‬یک نکته ی بسیار مهم آن است که در حل مسائل تشخیص دهیم که از حلقه‬ ‫اینصورت‪ ،‬کنترل از درون حلقه خارج میشود‪.‬‬

‫با تکرار معلوم یا از حلقه با تکرار نامعلوم استفاده کنیم‪.‬‬ ‫روشهای فوق معادل هم هستند و هیچکدام بر دیگری ارجحیت نداشته و‬

‫برای پی بردن به این مساله‪ ،‬یک اصل بسیار ساده وجود دارد (که بدبختانه(!)‬ ‫فقط بسته به سلیقهی برنامهنویس میباشد‪ .‬ولی در هر صورت‪ ،‬استفاده از‬

‫با وجود ساده بودن این اصل‪ ،‬خیلی از دانشجوها با این قضیهی استفاده از‬ ‫روشهای فوق‪ ،‬باید با مهارت‪ ،‬تسلط و آگاهی انجام گیرد؛ زیرا شرط مورد‬

‫حلقه با تکرار معلوم یا نامعلوم مشکل دارند!)‪ .‬هر وقت یک سری دستور‬ ‫استفاده (چه به کمک بلوک ‪ If‬و چه به کمک بلوک ‪ )Do While‬دقیقا‬

‫اجرایی داشتیم که نمیدانستیم چند بار باید تکرار شوند‪ ،‬ولی باید آنقدر‬ ‫باید به نقطهای (یا نقاطی) که میخواهیم از حلقه خارج شویم اشاره داشته‬

‫تکرار شوند تا یک اتفاق یا اتفاقات خاصی محقق شود‪ ،‬از حلقه با تکرار‬ ‫باشد‪.‬‬

‫نامعلوم استفاده می کنیم‪ .‬از طرف دیگر‪ ،‬هر وقت یک سری دستورات‬ ‫مثال در این مثال‪ ،‬همانطوری که در صورت مساله هم مطرح کردیم‪ ،‬به تعداد‬
‫اجرایی داشتیم که دقیقا مشخص بود چند بار باید تکرار شوند‪ ،‬از حلقهی با‬ ‫دفعات نامشخصی‪ ،‬از ورودی عدد گرفتیم و عملیات گرفتن اعداد را متوقف‬
‫تکرار معلوم استفاده می کنیم‪ .‬البته لزومی ندارد که تعداد دفعات تکرار از‬ ‫نکردیم‪ ،‬مگر آنکه کاربر یک عدد کوچکتر از صفر وارد کند‪ .‬پس در‬
‫همان اول مشخص باشد و ممکن است در طول برنامه مشخص شود (به مثال‬ ‫اینجا مشخص است که کنترل ما باید بر روی عدد ورودی باشد و به طور‬
‫بعد توجه کنید‪.).‬‬ ‫خاص‪ ،‬کوچکتر از صفر بودن آنرا بررسی کنیم که به کمک یک شرط‪،‬‬

‫مثال ‪ )5‬میخواهیم برنامهای بنویسیم که دو عدد ‪ M‬و ‪ N‬را از ورودی بگیرد و جدول‬ ‫این کار انجام شد‪.‬‬

‫ضربی از ‪ 1 × 1‬تا ‪ M × N‬به شکل مناسبی تهیه نماید‪ .‬مثال برنامه برای مقادیر ورودی‬ ‫ضمنا دقت کنید که چگونه به کمک یک بلوک ‪ If‬تعداد دادهها کنترل‬
‫چهار و سه‪ ،‬جدولی مانند جدول زیر تهیه میکند‪.‬‬ ‫میشود تا تعدادشان کمتر از دو تا نباشد و فقط در صورتی که حداقل دو‬
‫‪M‬‬ ‫‪N‬‬ ‫‪M * N‬‬ ‫داده وارد شده باشد‪ ،‬محاسبات انجام میشود (روش حل این مساله که شامل‬
‫===========================‬
‫‪1‬‬ ‫‪1‬‬ ‫‪1‬‬ ‫ترکیب حلقه و شرط میشود‪ ،‬یک تکنیک برای حل مسائل مشابه به حساب‬
‫‪1‬‬ ‫‪2‬‬ ‫‪2‬‬
‫‪1‬‬ ‫‪3‬‬ ‫‪3‬‬
‫میآید‪.).‬‬
‫‪14‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪ ‬حلقههای با تکرار معلوم دارای یک شمارنده (‪ Control Variable‬یا‬ ‫‪2‬‬ ‫‪1‬‬ ‫‪2‬‬
‫‪2‬‬ ‫‪2‬‬ ‫‪4‬‬
‫‪ )Counter‬از جنس متغیر هستند‪ .‬در این مثال شمارندهی حلقه اول متغیر ‪M‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪6‬‬
‫‪3‬‬ ‫‪1‬‬ ‫‪3‬‬
‫و شمارندهی حلقهی دوم متغیر ‪ N‬است‪.‬‬ ‫‪3‬‬ ‫‪2‬‬ ‫‪6‬‬
‫‪3‬‬ ‫‪3‬‬ ‫‪9‬‬
‫هر شمارنده شامل مقدار اولیه (‪ ،)Initial Value‬مقدار نهایی (‪ )Limit‬و‬ ‫‪4‬‬ ‫‪1‬‬ ‫‪4‬‬
‫‪4‬‬ ‫‪2‬‬ ‫‪8‬‬
‫گام شمارنده (‪ )Step Size‬میباشد‪ .‬به لطف اینکه هر یک از این مقادیر‬ ‫‪4‬‬ ‫‪3‬‬ ‫‪12‬‬
‫‪Program Multiplication_Table‬‬
‫میتوانند متغیر باشند‪ ،‬حلقهها بسیار انعطافپذیر هستند‪ .‬در همین مثال هم‬ ‫‪Implicit None‬‬
‫‪Integer :: M, N‬‬ ‫‪!Control Variables of Loops‬‬
‫مقدار نهاییِ شمارندهی حلقهها متغیر هستند و اصال به کمک همین خاصیت‬ ‫‪Integer :: Last_M, Last_N‬‬ ‫‪!Variables for Input Values‬‬
‫‪Integer :: Product‬‬ ‫‪!Result of Product‬‬
‫مساله را حل کردیم‪.‬‬ ‫"‪Print*, "Enter the Last Values of Two Numbers:‬‬
‫‪Read*, Last_M, Last_N‬‬
‫فراموش نکنید که گام شمارنده به صورت پیشفرض برابر یک میباشد‪.‬‬ ‫" ‪Print*,‬‬ ‫‪M‬‬ ‫‪N‬‬ ‫"‪M * N‬‬
‫" ‪Print*,‬‬ ‫"===========================‬
‫‪Do M = 1, Last_M‬‬
‫‪ ‬به دستورات چاپ در خطهای نهم و دهم نگاه کنید‪ .‬اوال از این دستورات‬ ‫‪Do N = 1, Last_N‬‬
‫برای درست کردن جدول استفاده کردیم و ثانیا فواصل در نظر گرفته شده‬ ‫‪Product = M * N‬‬
‫‪Print*, M, N, Product‬‬
‫در درون رشتهها‪ ،‬به دلیل آن است که مترجم به صورت پیشفرض‬ ‫‪End Do‬‬
‫‪End do‬‬
‫(میگوییم پیشفرض زیرا از دستور *‪ Print‬استفاده کردهایم)‪ ،‬برای چاپ‬ ‫‪End Program‬‬

‫متغیرهای ‪ N ،M‬و ‪( Product‬که دستور چاپ آن ها در خط سیزدهم‬ ‫نکات‪:‬‬


‫آورده شده است)‪ ،‬فواصلی را در نظر میگیرد‪ .‬فواصل درون رشتهها را با‬
‫‪ ‬همانطور که مشخص است‪ ،‬در اینجا از حلقه با تکرار معلوم استفاده‬
‫توجه به فواصل پیشفرض مترجم برای چاپ متغیرها تنظیم کردهایم تا شکلی‬
‫کردیم‪ .‬درست است که از اول تعداد دفعات تکرار مشخص نیست؛ ولی پس‬
‫جدول مانند درست شود‪ .‬در فصل بعد‪ ،‬با آشنایی با مفاهیم ورودی و‬
‫از خواندن اعداد‪ ،‬تعداد دفعات تکرار مشخص میشود‪.‬‬
‫خروجی‪ ،‬خیلی ساده میتوانیم چنین جداولی را درست کنیم؛ ولی فعال‬
‫مجبوریم از همین راهکار استفاده نماییم‪.‬‬

‫‪15‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل دوم (ساختارهای کنترلی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫خودش برسد‪ .‬دقت داشته باشید که تا االن مقدار متغیر ‪ I‬برابر یک بود‪ .‬حاال‬ ‫‪ ‬توانایی بررسی نحوهی عملکرد حلقههای تو در تو بسیار با اهمیت است‪ .‬با‬
‫که به حلقهی اول بازگشتیم‪ ،‬به مقدار متغیر ‪ I‬یکی اضافه شده و بنابراین‬ ‫یک مثال‪ ،‬نحوهی عملکرد دو حلقهی تو در تو را بررسی میکنیم‪.‬‬
‫مقدارش برابر دو میشود‪ .‬سپس در ادامه‪ ،‬وقتی به حلقه ی دوم رسیدیم‪،‬‬ ‫حلقههای تو در توی زیر را در نظر بگیرید‪.‬‬
‫روال قبلی تکرار میشود؛ یعنی همانطور که مقدار ‪ I‬برابر دو میباشد‪ ،‬مقدار‬
‫‪Do I = 1, 4‬‬
‫‪ J‬اول دو و بعد سه میشود‪ .‬مجددا به حلقهی اولی بازمیگردیم و مقدار‬ ‫‪Do J = 2, 3‬‬
‫……………‬
‫متغیر ‪ I‬برابر سه میشود و این روال تا انتها ادامه پیدا میکند تا جایی که‬ ‫……………‬
‫‪End Do‬‬
‫مقدار متغیرهای ‪ I‬و ‪ J‬برابر مقدار نهایی خودشان شده باشد‪ .‬یعنی زمانی که‬ ‫‪End Do‬‬
‫مقدار ‪ I‬برابر چهار و مقدار ‪ J‬برابر سه شود‪ ،‬از مجموعهی این حلقههای تو در‬ ‫در اینجا قصد داریم فقط نحوهی تغییرات شمارندهها را بررسی کنیم و لذا‬
‫تو خارج میشویم‪.‬‬ ‫به دستورات اجرایی درون حلقهها کاری نداریم‪.‬‬
‫به عبارت سادهتر دو مورد زیر را به خاطر داشته باشد‪:‬‬ ‫وقتی به حلقهی اول میرسیم‪ ،‬ابتدا مقدار شمارندهی آن یعنی متغیر ‪ ،I‬برابر با‬
‫‪ .1‬در حالت عادی‪ ،‬با وارد شدن به هر حلقه‪ ،‬فقط وقتی از آن حلقه‬ ‫مقدار اولیهاش که در اینجا یک میباشد میشود‪ .‬سپس در ادامه وقتی به‬
‫خارج میشویم که شمارندهی آن‪ ،‬از مقدار اولیه تا مقدار نهایی‪ ،‬با‬ ‫حلقهی دوم میرسیم‪ ،‬مقدار شمارندهی آن یعنی متغیر ‪ ،J‬برابر مقدار اولیهی‬
‫توجه به گام تغییر کند (مگر اینکه با کمک دستورات ‪،Cycle‬‬ ‫خودش یعنی دو میشود‪ .‬با پیشروی در خطها‪ ،‬هرگاه که به دستور‬
‫‪ Exit‬یا ‪ ،Stop‬روال عادی حلقه را به هم بزنیم‪ .‬برای مطالعهی‬ ‫‪ End Do‬برسیم‪ ،‬به ابتدای حلقهی دوم برمیگردیم (دقت کنید که به‬
‫توضیحات و مثالها راجع به دستور ‪ Cycle‬به کتابهای مرجع‬ ‫حلقهی اول برنمیگردیم‪ .).‬در اینجا در حالی که هنوز مقدار متغیر ‪ I‬برابر‬
‫مراجعه کنید و راجع به دستور ‪ Stop‬در فصل بعدی همین جزوه‪،‬‬ ‫یک میباشد‪ ،‬به مقدار متغیر ‪ ،J‬یکی اضافه میشود (چراکه گام برابر یک‬
‫مفصال بحث شده است‪.).‬‬ ‫است) و بنابراین مقدارش برابر سه میشود‪ .‬مجددا دستورات اجرا میشوند تا‬
‫دوباره به ‪ End Do‬برسیم‪ .‬حال چون در آخرین بار به مقدار نهایی حلقهی‬
‫‪ .2‬در حلقههای تو در تو‪ ،‬هرگاه وارد حلقههای درونی شویم‪ ،‬تا وقتی‬
‫دوم (یعنی سه) رسیده بودیم‪ ،‬به حلقهی اول بازمیگردیم؛ چراکه هر حلقهی‬
‫که شمارندهی آنها از مقدار اولیه تا مقدار نهایی خودش تغییر‬
‫با تکرار معلوم‪ ،‬تا جایی ادامه پیدا میکند که شمارندهی آن به مقدار انتهایی‬
‫نکرده است‪ ،‬از آن خارج نمیشویم و به سراغ حلقههای بیرونی‬
‫‪16‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫میخواهیم برنامهای بنویسیم که با در نظر گرفتن ‪ ،g = -9.81‬مقدار سرعت اولیهی‬ ‫نمیرویم (مگر اینکه با کمک دستورات ‪ Exit ،Cycle‬یا‬
‫توپی که از سطح زمین پرتاب میشود را از ورودی بگیرد و سپس برد توپ را برای‬ ‫‪ ،Stop‬روال عادی حلقه را به هم بزنیم‪.).‬‬
‫تمامی زوایا از صفر تا نود درجه محاسبه نماید‪ .‬همچنین برنامه مقدار بردِ حداکثر و‬ ‫‪ ‬در خیلی از مسائل‪ ،‬از مقدار شمارندهی حلقه برای حل مساله نیز استفاده‬
‫زاویهی متناظر با بردِ حداکثر را یافته و چاپ مینماید‪.‬‬ ‫میشود‪ .‬مثال به حل همین مثال دقت کنید و ببینید که شمارندههای هر دو‬
‫‪Program Ball‬‬ ‫حلقه‪ ،‬چگونه در چاپ جدول ضرب به ما کمک میکنند (روش حل این‬
‫‪Implicit None‬‬
‫‪! Declare Parameters‬‬ ‫مساله نیز‪ ،‬یک تکنیک برای حل مسائل مشابه به حساب میآید‪.).‬‬
‫‪Real , Parameter :: DegreetoRadian = 0.01745329 !Deg ==> Rad‬‬
‫‪Real , Parameter :: Gravity = -9.81 !Accel. due to Gravity‬‬
‫‪! Declare Variables‬‬
‫‪ ‬در صورتی که از شمارندهی حلقه در حل مساله کمک میگیرید‪ ،‬فراموش‬
‫‪Integer :: Max_Degree = 0.!Angle at which Max Range Occurs‬‬ ‫نکنید که مقدار شمارندهی حلقه را در درون حلقه نمیتوانید تغییر دهید‪ .‬البته‬
‫‪Real :: Max_Range = 0.‬‬ ‫‪!Max Range for the Ball‬‬
‫‪Real :: Range‬‬ ‫‪!Range of Ball at a Particular‬‬ ‫تغییر مقدار شمارندهی حلقه در بیرون از حلقه بالمانع است‪.‬‬
‫‪!Angle‬‬
‫‪Real :: Radian‬‬ ‫‪!Angle in Radians‬‬
‫‪Real :: Theta‬‬ ‫‪!Angle in Degrees‬‬ ‫‪ ‬در صورتی که مقدار اولیهی شمارندهی حلقه با مقدار نهایی آن برابر باشد‪،‬‬
‫‪Real :: V0‬‬ ‫‪!Initial Velocity of Ball‬‬
‫‪! Get Velocity‬‬
‫حلقه یکبار انجام میشود‪ .‬همچنین در صورتی که مقدار اولیهی شمارنده از‬
‫‪Read*, V0‬‬ ‫مقدار نهایی آن بیشتر بوده و گام نیز مقداری مثبت باشد‪ ،‬حلقه انجام‬
‫‪! Loop Over All Specified Angles‬‬
‫‪Loop : Do Theta = 0, 90‬‬ ‫نمیشود‪.‬‬
‫‪!Get Angles in Radians‬‬
‫‪Radian = Theta * DegreetoRadian‬‬
‫‪!Calculate Range in Meters‬‬ ‫مثال ‪ )6‬همانطوری که از قبل به یاد داریم‪ ،‬برد یک پرتابه در حرکت دو بعدی (با‬
‫& * )‪Range = (-2. * V0 ** 2 / Gravity) * Sin (Radian‬‬
‫)‪Cos (Radian‬‬
‫صرف نظر از اصطکاک هوا و انحنای زمین) از رابطهی‬
‫‪!Write out the Range of This Angle‬‬
‫& ‪Write (*,*) "Theta = ", Theta, "Degrees;",‬‬
‫"‪"Range = ", Range, "Meters‬‬
‫‪!Compare the Range to the Previous Maximum Range.‬‬
‫‪!If This Range is Larger, Save it and the Angle at‬‬ ‫به دست میآید که در آن ‪ V0‬سرعت اولیهی پرتابه‪ g ،‬شتاب جاذبهی زمین و ‪ θ‬زاویهی‬
‫‪!Which it Occurred.‬‬
‫‪MaxRange : If (Range .GT. Max_Range) Then‬‬ ‫پرتاب با افق میباشد‪.‬‬
‫‪Max_Range = Range‬‬

‫‪17‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل دوم (ساختارهای کنترلی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫تکرارشده است)‪ .‬این کار باعث میشود که عمال تمامی بردهای به دست‬ ‫‪Max_Degree = Theta‬‬
‫‪End If MaxRange‬‬
‫آمده را با هم مقایسه کنیم و در نهایت بیشترین برد را درون یک متغیر‬ ‫‪End Do Loop‬‬
‫‪! Skip a Line and Then Write Out the Maximum Range and Angle‬‬
‫ذخیره نماییم (یک تکنیک دیگر!)‪.‬‬ ‫‪!at Which it Occurred.‬‬
‫)*‪Write (*,‬‬
‫‪ ‬واضح است که تبدیل زاویه از درجه به رادیان‪ ،‬خودش کاری زمانگیر است‬
‫& ‪Write (*,*) "Max Range = ", Max_Range, "at", Max_Degree,‬‬
‫و حجم کدنویسی را افزایش میدهد‪ .‬در صورتی که اگر از توابع )‪Sind (x‬‬ ‫"‪"Degrees‬‬
‫‪End Program‬‬
‫و )‪ Cosd (x‬که در فصل قبل راجع آنها بحث کردم را استفاده میکردیم‪،‬‬
‫نکات‪:‬‬
‫کارمان سادهتر می شد‪ .‬تسلط به توابع ذاتی و استفاده از توابع غیر ذاتی (که‬
‫در فصل زیر برنامهها با ساخت آنها آشنا میشوید) بسیار مهم است‪.‬‬ ‫‪ ‬هدف این مساله نیز‪ ،‬استفاده از ترکیب حلقه و شرط است‪ .‬کامال واضح است‬
‫که درون حلقه‪ ،‬از یک بلوک شرط استفاده کردیم‪ .‬باید با حل مسائل متنوع‪،‬‬
‫بخش دوم – تمارین‬ ‫به ترکیب حلقه و حلقه‪ ،‬شرط و شرط و حلقه و شرط مسلط شوید‪.‬‬

‫تمرین ‪ )1‬در هر یک از تمارین زیر‪ ،‬فرض کنید ‪ J ،I‬و ‪ ،K‬متغیرهای صحیح هستند‪.‬‬ ‫‪ ‬به مکانیزم پیدا کردن بردِ حداکثر که همان بلوک شرط درون حلقه میباشد‬
‫خروجی هر مورد را تشریح کنید‪.‬‬ ‫توجه فرمایید‪.‬‬
‫)‪a‬‬ ‫‪Do I = 6, 6‬‬
‫"‪Print*, "Hello‬‬ ‫به کمک حلقه‪ ،‬برد در هر یک از زوایای یک تا نود درجه محاسبه میشود و‬
‫‪End Do‬‬
‫)‪b‬‬ ‫‪Do I = 6, 5‬‬ ‫به کمک شرطِ درون حلقه‪ ،‬بردِ به دست آمده در هر زاویه‪ ،‬با مقدار برد‬
‫"‪Print*, "Hello‬‬
‫‪End Do‬‬ ‫ذخیره شده در متغیر ‪ Max_Range‬مقایسه میشود (دقت کنید که مقدار‬
‫)‪c‬‬ ‫‪Do I = -2, 3‬‬
‫اولیهی این متغیر صفر است)‪ .‬در صورتی که مقدار برد در این زاویه از مقدار‬
‫‪Print*, I, I * I‬‬
‫‪End Do‬‬ ‫برد در متغیر ‪ Max_Range‬بیشتر باشد‪ ،‬مقدار همین برد در متغیر‬
‫)‪d‬‬ ‫‪Do I = 1, 5‬‬
‫‪Print*, I‬‬ ‫‪ Max_Range‬ذخیره میشود؛ در غیر این صورت‪ ،‬مقدار متغیر‬
‫‪Do J = I, 1, -1‬‬
‫‪Print*, J‬‬ ‫‪ Max_Range‬همان مقدار قبلی خودش باقی میماند (همین روال برای‬
‫‪End Do‬‬
‫‪End Do‬‬ ‫پیدا کردن زاویهی متناظر با بردِ حداکثر به کمک متغیر ‪Max_Degree‬‬

‫‪18‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫را از با استفاده از رابطهی‬ ‫تمرین ‪ )4‬برنامهای بنویسید که مقدار‬ ‫)‪e‬‬ ‫‪K = 5‬‬
‫‪Do I = -2, 3‬‬
‫‪Print*, I + K‬‬
‫‪K = 1‬‬
‫∑‬ ‫‪End Do‬‬
‫)‪f‬‬ ‫‪Do I = 1, 3‬‬
‫‪Do J = 1, 3‬‬
‫با تقریب کمتر از ‪ 10-6‬حساب کند‪.‬‬ ‫‪Do K = I, J‬‬
‫‪Print*, I, J, K‬‬
‫مثال ‪ )5‬میانگین هندسی یک مجموعه از اعداد ‪ x1‬تا ‪ xn‬به صورت زیر تعریف‬ ‫‪End Do‬‬
‫‪End Do‬‬
‫میگردد‪.‬‬ ‫‪End Do‬‬

‫تمرین ‪ )2‬چنانچه ‪ Number‬و ‪ Limit‬متغیرهای صحیح باشند‪ ،‬خروجی تکه‬


‫میانگین هندسی‬ ‫√‬
‫برنامهی زیر را به ازای ‪ 4‬و ‪ -2‬به دست آورید‪.‬‬
‫برنامهای بنویسید که میانگین هندسی و حسابی تعدادی داده را با شرایط زیر‪ ،‬محاسبه‬
‫‪Read*, Limit‬‬
‫و چاپ نماید‪.‬‬ ‫‪Number = 0‬‬
‫‪Do‬‬
‫‪Print*, Number‬‬
‫‪ .1‬تعداد دادهها از پیش مشخص نیست‪.‬‬ ‫‪Number = Number + 1‬‬
‫‪If (Number .GT. Limit) Exit‬‬
‫‪ .2‬همهی دادههای ورودی مثبت هستند‪.‬‬ ‫‪End Do‬‬

‫‪ .3‬از یک حلقه‪ ،‬همزمان برای گرفتن دادهها و توقف گرفتن دادهها استفاده‬ ‫تمرین ‪ )3‬فرمول زیر‪ ،‬مقدار بار مجاز ‪( L‬بر حسب پوند بر اینچ مربع) را برای یک‬
‫شود؛ به طوری که اگر عددی منفی به عنوان ورودی‪ ،‬وارد شود‪ ،‬عملیات‬ ‫ستون با ضریب الغری ‪ S‬تعیین میکند‪.‬‬
‫خواندن دادهها متوقف گردد‪.‬‬

‫مثال ‪ )6‬مطابق شکل‪ ،‬یک شیء ‪ 222‬پوندی‪ ،‬از انتهای یک میلهی صلب افقی ‪8‬‬ ‫{‬
‫(‬ ‫)‬
‫فوتی با وزن ناچیز آویزان شده است‪ .‬میله توسط یک لوال به دیوار متصل شده و به‬
‫وسیلهی یک کابل ‪ 8‬فوتی که به نقطهای باالتر به دیوار متصل شده‪ ،‬نگه داشته شده‬ ‫برنامه ای بنویسید که ضریب الغری یک ستون را از ورودی بگیرد و مقدار بار مجاز‬

‫است‪.‬‬ ‫آنرا حساب کند‪.‬‬

‫‪19‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل دوم (ساختارهای کنترلی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫کارخانه ‪ 10 × n‬افزایش مییابد‪ .‬مدیر کارخانه میخواهد بداند‪ ،‬چنانچه با وضعیت‬


‫تولید و هزینهی فعلی شروع کند و هر ماه هزینهی تحقیق و توسعه را ‪ n‬برابر ماه قبل‬
‫‪LC = 8 ft‬‬
‫نماید‪ ،‬سود کارخانه پس از یکسال چه تغییراتی مینماید‪ .‬برنامهای بنویسید که مدیر با‬
‫وارد کردن ‪ ،n‬جواب سوالش را بگیرد!‬ ‫‪LP = 8 ft‬‬

‫‪d‬‬

‫‪200 lb‬‬

‫تنش ایجاد شده در کابل‪ ،‬از رابطهی‬

‫√‬
‫به دست میآید که در آن ‪ W‬وزن شیء‪ LC ،‬طول کابل‪ LP ،‬طول میله و ‪ d‬فاصله از‬
‫دیوار تا نقطهی اتصال کابل به میله است‪.‬‬

‫برنامهای بنویسید که میزان تنش در کابل را برای مقادیر مختلف ‪ d‬از یک فوت تا‬
‫هفت فوت‪ ،‬با گام ‪ 0.1‬فوت محاسبه و چاپ نماید‪ .‬ضمنا برنامه باید تنش حداکثر بین‬
‫مقادیر محاسبه شده و مقدار ‪ d‬متناظر با تنش حداکثر را پیدا کرده و چاپ نماید‪.‬‬

‫مثال ‪ )7‬یک کارخانهی قالبسازی در حال حاضر ‪ 222‬قالب در ماه تولید میکند و‬
‫به ازای هر قالب‪ 322 ،‬دالر سود میبرد‪ .‬مخارج ثابت این کارخانه که به مقدار تولید آن‬
‫بستگی ندارد‪ 22222 ،‬دالر در ماه است‪ .‬همچنین کارخانه ماهانه ‪ 2222‬دالر بابت تحقیق‬
‫و توسعه هزینه میکند‪ .‬چنانچه کارخانه هزینهی تحقیق و توسعه را ‪ n‬برابر نماید‪ ،‬تولید‬

‫‪22‬‬
21
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫خروجی به صورت زیر است‪:‬‬


‫فصل سوم (ورودی و خروجی)‬
‫‪˽˽˽˽˽3˽˽˽˽0˽˽˽5378˽˽˽˽-12345‬‬
‫‪˽˽˽˽03˽˽˽00˽˽˽5378˽˽-0012345‬‬
‫توجه‪ :‬عالمت "˽" به معنای جای خالی است‪.‬‬
‫‪˽˽˽˽˽3˽˽˽˽˽˽˽˽5378˽˽˽˽-12345‬‬

‫نکات‪:‬‬ ‫توجه‪ :‬مثالها و تمارین این فصل بسیار مهم هستند و توصیه میکنم اگر هیچ کدام از‬
‫فصول این جزوه را مطالعه نمی کنید‪ ،‬به هیچ عنوان از این فصل غافل نشوید‪ .‬جزئیات به‬
‫‪ ‬به نحوهی بررسی فرمتها دقت کنید‪ .‬در صورتی که به روش بررسی‬
‫کار رفته در این مثالها و تمارین مواردی هستند که به یقین در امتحان حائز اهمیت‬
‫فرمتها مسلط شوید‪ ،‬مطمئنا در پیچیدهترین فرمتها هم دچار خطا نخواهید‬
‫خواهند بود‪.‬‬
‫شد‪ .‬در مورد اول‪ ،‬بهدلیل وجود ‪ 1X‬یک جای خالی قرار میگیرد‪ .‬سپس‬
‫فرمت ‪ ،2I5‬بدان معنی است که محتوای متغیرهای ‪ Number‬و‬ ‫بخش اول – مثالها‬
‫‪ Number – 3‬با فرمت ‪ I5‬چاپ میشوند‪ .‬بنابراین ابتدا برای چاپ محتوای‬
‫مثالهای اول تا هفتم‪ ،‬مربوط به بحث خروجی میباشند‪.‬‬
‫‪ ،Number‬پنج تا جای خالی درر نظر گرفته میشود‪ .‬سپس اعداد از‬
‫راستترین جای خالی تا اولین جای خالی قرار میگیرند (زیرا همانطور که‬ ‫مثال ‪] )1‬کاربرد فرمت اعداد صحیح[ با توجه به اعالنهای انجام شده‪ ،‬خروجی‬
‫میدانیم‪ ،‬اعداد راستچین میشوند)؛ لذا چون محتوای ‪ Number‬برابر ‪3‬‬ ‫دستورات زیر را مینویسیم‪.‬‬
‫میباشد‪ ،‬عدد ‪ 3‬در جای خالی آخر قرار میگیرد و بنابراین چهار جای خالی‬ ‫‪Integer :: Number = 3, L = 5378, Kappa = -12345‬‬
‫‪Print '(1X, 2I5, I7, I10)', Number, Number – 3, L, Kappa‬‬
‫قبل از آن باقی می ماند‪ .‬در نهایت با در نظر گرفتن جای خالی برای ‪ 1X‬که‬ ‫‪Print '(1X, 2I5.2, I7, I10.7)', Number, Number – 3, L, Kappa‬‬
‫‪Print '(1X, 2I5.0, I7, I10)', Number, Number – 3, L, Kappa‬‬
‫همان اول لحاظ شد‪ ،‬پنج جای خالی پشت عدد ‪ 3‬قرار میگیرد‪ .‬به همین‬
‫فرم کلی فرمت ‪ ،I‬به صورت ‪ Iw.m‬میباشد که در آن ‪ w‬یک عدد صحیح مثبت‬
‫ترتیب‪ ،‬برای ‪ Number – 3‬نیز پنج جای خالی در نظر گرفته میشود که‬
‫ثابت و تعیینکنندهی تعداد ارقام به همراه عالمت آن بوده و به آن عرض میدان‬
‫اولین جای خالی پس از ‪ 3‬قرار میگیرد‪ .‬چون محتوای‪ Number – 3‬برابر‬
‫میگوییم و ‪ m‬یک عدد صحیح مثبت ثابت و تعیینکنندهی حداقل تعداد ارقام برای‬
‫صفر می باشد‪ ،‬پس در جای خالی آخر صفر قرار گرفته و پشت صفر‪ ،‬چهار‬
‫نمایش میباشد‪ .‬دقت کنید که ‪ m‬فقط شامل ارقام میشود و منفی اعداد کوچکتر از‬
‫جای خالی باقی می ماند‪ .‬به همین ترتیب باید تا انتها عمل شود‪ .‬فقط دقت‬
‫صفر را شامل نمیشود (به مورد دوم دقت کنید)‪.‬‬

‫‪22‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل سوم (ورودی و خروجی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫خودتان به همین شکلی که توضیح داده شد‪ ،‬چاپ دو متغیر دیگر را نیز‬ ‫کنید که همیشه برای منفی پشت اعداد کوچکتر از صفر نیز باید یک جای‬
‫بررسی کنید‪.‬‬ ‫خالی در نظر گرفته شود‪.‬‬
‫در مورد دوم‪ ،‬به جای فرمت ‪ ،I5‬از فرمت ‪ I5.2‬استفاده شده است‪ .‬طبق‬
‫مثال ‪] )2‬کاربرد فرمت اعداد حقیقی[ با توجه به اعالنهای داده شده‪ ،‬خروجی‬
‫توضیحی که آوردیم‪ ،‬پنج به منظور مشخص کردن تعداد ارقام و دو به منظور‬
‫دستورات زیر را مینویسیم‪.‬‬
‫تعیین حداقل ارقام میباشد‪ .‬لذا در خروجی‪ ،‬عدد باید با حداقل دو رقم چاپ‬
‫‪Integer :: In = 625, Out = -19‬‬
‫‪Real :: A = 7.5, B = .182, C = 625.327‬‬ ‫شوند‪ .‬پس چون محتوای ‪ Number‬و ‪ Number – 3‬تک رقمی هستند‪،‬‬
‫‪Print '(1X, 2I4, 2F6.3, F8.3)', In, Out, A, B, C‬‬
‫یک صفر پشت محتوای آنها قرار داده شده تا دو رقمی شوند (همانطور که‬
‫خروجی به صورت زیر است‪:‬‬
‫می دانیم‪ ،‬این صفر یا صفرها نیز تاثیری در مقدار اعداد از نظر ریاضی نیز‬
‫‪˽˽625˽-19˽7.500˽0.182˽625.327‬‬
‫ندارد‪.).‬‬
‫نکات‪:‬‬
‫در مورد سوم نیز فرمت ‪ I5.0‬به کار رفته است‪ .‬پس حداقل تعداد ارقام صفر‬
‫‪ ‬از قبل میدانیم که فرمت اعداد حقیقی به صورت ‪ Fw.d‬میباشد که در آن‬ ‫نیز میتواند باشد! بنابراین محتوای ‪ Number‬به صورت عادی که همان ‪3‬‬
‫‪ w‬نشاندهندهی عرض میدان و ‪ d‬نشاندهندهی تعداد ارقام اعشار است‪.‬‬ ‫میباشد چاپ میشود (زیرا خودش یک رقمی است و تعداد ارقامش از‬
‫‪ ‬ابتدا یک جای خالی برای ‪ 1X‬در نظر گرفته میشود‪ .‬سپس چون فرمت‬ ‫حداقلی که مشخص شده بیشتر است) و به عنوان محتوای ‪Number – 3‬‬
‫‪ 2I4‬داریم‪ ،‬متغیرهای ‪ In‬و ‪ Out‬با فرمت ‪ I4‬چاپ میشوند‪ .‬پس اول چهار‬ ‫هیچ چیزی چاپ نمیشود! زیرا محتوایش صفر میباشد و چون با استفاده‬
‫تا جای خالی برای متغیر ‪ In‬باز میشود و از راست‪ ،‬محتوای آن چیده‬ ‫فرمت ‪ I5.0‬این اجازه داده شده که حداقل تعداد ارقام صفر باشد‪ ،‬بنابراین‬
‫میشود؛ لذا سمت چپ ‪ 625‬یک جای خالی باقی میماند که با جای خالی‬ ‫چیزی چاپ نمیشود (دقت کنید که راجع به تعداد ارقام صحبت میکنیم)‪.‬‬
‫فرمت ‪ ،1X‬دو جای خالی میشود‪ .‬مجددا بعد از عدد ‪ ،5‬چهار تا جای خالی‬ ‫ضمنا این امکان (یعنی چاپ نشدن صفر در مبحث اعداد صحیح‪ ،‬در صورتی‬
‫برای متغیر ‪ Out‬باز میشود و ‪ -19‬از راست قرار میگیرد که در نتیجه یک‬ ‫که محتوای یک عبارت یا متغیر صفر شود)‪ ،‬فقط به کمک استفاده از همین‬
‫جای خالی در سمت چپ باقی میماند‪ .‬حال به فرمت ‪ 2F6.3‬میرسیم که‬ ‫فرمت ‪ Iw.0‬میسر است‪.‬‬
‫نشان از آن است که متغیرهای ‪ A‬و‪ B‬با فرمت ‪ F6.3‬چاپ میشوند‪ .‬بنابراین‬

‫‪23‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫نکات‪:‬‬ ‫ابتدا‪ ،‬بعد از ‪ ،9‬تعداد شش جای خالی برای عدد باز میشود‪ .‬سپس چون طبق‬
‫فرمت عدد باید دارای سه رقم اعشار در خروجی باشد‪ 7.5 ،‬به ‪7.500‬‬
‫‪ ‬در اعالن‪ ،‬به نحوهی مقداردهی به متغیرهای ‪ C ،A‬و ‪ D‬دقت کنید‪ .‬در‬
‫تبدیل می شود‪ .‬در نهایت نیز مثل قبل‪ ،‬اعداد در شش جای خالی تعیین شده‪،‬‬
‫مقداردهی به متغیرها با مقادیر بسیار بزرگ یا کوچک‪ ،‬مجبور به استفاده از‬
‫از راست به چپ قرار میگیرد‪ .‬چون طول ‪ 7.500‬برابر پنج است‪ ،‬پس یک‬
‫روش مقدار دهی نمایی هستیم‪.‬‬
‫جای خالی از سمت چپ باقی میماند (شمارش ممیز در طول عدد فراموش‬
‫‪ ‬از قبل با فرمت نمایی آشنا هستیم و میدانیم که در فرمت ‪ Ew.d‬حرف ‪w‬‬
‫نشود)‪ .‬دو متغیر بعدی نیز به همین ترتیب چاپ خواهند شد‪ .‬فقط دقت کنید‬
‫نشاندهندهی عرض میدان و ‪ d‬نشاندهندهی تعداد ارقام بین ممیز و حرف ‪E‬‬
‫که خروجی برای متغیر ‪ ،B‬به این دلیل ‪ 0.182‬شده است که صفر قبل از‬
‫میباشد‪.‬‬
‫ممیز‪ ،‬به صورت پیشفرض چاپ میشود‪.‬‬
‫‪ ‬بیاید با هم از اول تا چاپ متغیر ‪ B‬را بررسی کنیم‪ .‬ابتدا به خاطر وجود فرمت‬
‫‪ ‬در برخی از مترجمها‪ ،‬در صورتی که قسمت صحیح عدد صفر باشد‪ ،‬صفر‬
‫‪ ،1X‬یک جای خالی رها می شود‪ .‬سپس چون فرمت متناظر متغیر ‪ A‬برابر‬
‫به صورت پیشفرض چاپ میشود و در صورتی که برای چاپ عدد فقط‬
‫‪ E15.5‬میباشد‪ ،‬به اندازهی عرض میدان که پانزده است‪ ،‬جا برای متغیر ‪A‬‬
‫یک جا کم بیاید‪ ،‬به صورت خودکار صفر قبل از اعشار حذف میشود (در‬
‫در نظر گرفته میشود‪ .‬حاال باید دقت کرد که وقتی از فرمت ‪ Ew.d‬استفاده‬
‫صورتی که با حذف صفر ماقبل اعشار باز هم جا کم بیاید‪ ،‬به اندازهی عرض‬
‫میکنیم‪ ،‬فرم کلی عدد در خروجی‪ ،‬به صورت‬
‫‪d‬‬ ‫میدان قالب‪ ،‬در خروجی * چاپ میشود‪ .‬این روالی است که برای‬
‫فرمتهای دیگر هم وجود دارد و در صورت کم آمدن جا برای خروجی‪ ،‬به‬
‫میباشد که قسمت اعشاری (عدد قبل از حرف ‪ ،)E‬بزرگتر یا مساوی ‪0.1‬‬
‫اندازهی عرض میدان * چاپ میشود‪.).‬‬
‫) میباشد‪ .‬در اینجا‬ ‫و کوچکتر از ‪( 1‬‬
‫مثال ‪] )3‬کاربرد فرمت نمایی[ با توجه به اعالنهای داده شده‪ ،‬خروجی دستورات‬
‫چون ورودی برای متغیر ‪ A‬برابر ‪ 0.1234 × 108‬است‪ ،‬بنابراین خودش به‬
‫صورت فرم کلی ذکر شده میباشد و برای تبدیل شدن به فرم کلی نیازی به‬ ‫زیر را مینویسیم‪.‬‬

‫تغییرات ندارد‪ .‬حاال میدانیم که ‪ d‬در فرمت ‪ E‬نیز‪ ،‬نشاندهندهی تعداد ارقام‬ ‫‪Real :: A = .1234E8, B = .0237, C = 4.6E-12, D = -76.1684E12‬‬
‫‪Print '(1X, 2E15.5, E15.4, E14.4)', A, B, C, D‬‬
‫بین ممیز و ‪ E‬میباشد‪ .‬چون اینجا مقدار ‪ d‬برابر پنج میباشد‪ ،‬لذا ارقام بین‬
‫خروجی به صورت زیر است‪:‬‬
‫ممیز و ‪ E‬باید پنج ت ا باشند؛ ولی خود عدد در این فاصله دارای چهار رقم‬
‫‪˽˽˽˽˽0.12340E+08˽˽˽˽0.23700E-01˽˽˽˽˽0.4600E-11˽˽˽-0.7617E+14‬‬
‫‪24‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل سوم (ورودی و خروجی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫‪ ‬در صورتی که تعداد ارقام بین ممیز و ‪ E‬بیش از مقدار ‪ d‬باشد‪ ،‬گرد شدهی‬ ‫است‪ .‬پس برای مطابقت با فرمت‪ ،‬به صورت ‪ 0.12340 × 108‬درمیآید و‬
‫عدد بین ممیز و ‪ E‬در خروجی چاپ می شود (مانند اتفاقی که در چاپ متغیر‬ ‫به فرم استاندار فرترن‪ ،‬در آن پانزده جایی که همان اول برای این متغیر در‬
‫‪ D‬میافتد)‪.‬‬ ‫نظر گرفته شده بود‪ ،‬از راست به چپ قرار میگیرد‪.‬‬
‫‪ ‬در صورتی که در فرمت ‪ Fw.d‬مقدار ‪ d‬برابر با صفر باشد‪ ،‬هیچ اشکالی‬ ‫فرمت متناظر متغیر ‪ B‬نیز ‪ E15.5‬میباشد‪ .‬بنابراین در ادامهی خروجی‪،‬‬
‫پیش نیامده و عدد در خروجی بدون ارقام اعشار چاپ میشود؛ ولی در‬ ‫پانزده جای خالی برای چاپ محتوای متغیر ‪ B‬در نظر گرفته میشود‪ .‬اما‬
‫صورتی که در فرمت ‪ Ew.d‬مقدار ‪ d‬برابر صفر باشد‪ ،‬در خروجی به‬ ‫اینبار چون در مقداردهی‪ ،‬عدد ‪ 0.0237‬به متغیر ‪ B‬نسبت داده شده‪ ،‬لذا‬
‫اندازهی عرض میدان فرمت ستاره چاپ میشود‪ .‬مثال خروجی دستورات‬ ‫باید در آن تغییر ایجاد شود؛ چراکه به شکل فرم استاندار ذکر شده نیست‪.‬‬
‫چاپ‬ ‫‪0.237‬‬ ‫برای اینکه این عدد به شکل استاندارد تبدیل شود‪ ،‬به صورت‬
‫‪Print "(F4.2, E10.3)", 1.25, 1.25‬‬ ‫‪ × 10-1‬در میآید‪ .‬بنابراین االن میتواند به فرم استاندارد فرترن‪ ،‬در آن‬
‫‪Print "(F4.0, E10.0)", 1.25, 1.25‬‬
‫پانزده جایی که برایش در نظر گرفته شده بود‪ ،‬از راست به چپ قرار گیرد‪.‬‬
‫به صورت زیر است‪:‬‬
‫بقیهی متغیرها را حتما خودتان بررسی کنید‪.‬‬
‫‪1.25˽0.125E+01‬‬
‫**********‪˽˽1.‬‬ ‫‪ ‬دقت کنید که منفی در اعداد کوچکتر از صفر‪ ،‬ممیز‪ ،‬عدد دو رقمی پس از‬
‫‪ ‬فراموش نکنید که فرمتهای ‪ ESw.d‬و ‪ ENw.d‬را هم بررسی کنید؛ زیرا‬ ‫‪( E‬همانطور که در مثال هم مشخص است‪ ،‬حتی اگر توان یک رقمی هم‬
‫بر خالف تصور‪ ،‬باید بر آنها نیز تسلط داشته باشید!‬ ‫باشد‪ ،‬پشت آن صفر قرار میگیرد و در نهایت توان همیشه با دو رقم چاپ‬
‫خواهد شد)‪ ،‬مثبت یا منفیِ پشتِ عددِ دو رقمیِ پس از ‪ E‬و خود ‪ E‬را در‬
‫مثال ‪] )4‬کاربرد فرمت دادههای منطقی‪ .‬ممکن است این فرمت جزء مواردی که به‬
‫شمارش عرض میدان فرمت لحاظ کنید‪.‬‬
‫شما درس داده میشود نباشد‪ .‬ولی بسیار پرکاربرد است‪ [.‬خروجی اعالن و دستورات‬
‫‪ ‬در برخی از برنامههای مترجم‪ ،‬صفر قبـل از اعـشار برای فرمت ‪ ،E‬به‬
‫‪Logical :: Output = .True., Debug = .False.‬‬
‫‪Write (*, 200) Output, Debug‬‬ ‫صــورت پیـشفرض چـاپ میشود‪ .‬ولی در صورتی که برای چاپ عدد‪،‬‬
‫)‪200 Format (2L5‬‬
‫فقط یک جا کم بیاید‪ ،‬از صفر ماقبل اعشار صرف نظر میشود تا عدد در‬
‫به صورت زیر است‪:‬‬
‫جاهای خالی در نظر گرفته شده قرار بگیرد‪.‬‬
‫‪˽˽˽˽T˽˽˽˽F‬‬

‫‪25‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪M = 7623; N‬‬ ‫‪= 5137; A = 617.2; B = 29.25‬‬ ‫نکات‪:‬‬


‫‪Print '(1X,‬‬ ‫‪I5, 3I6)', M, N‬‬
‫‪Print '(1X,‬‬ ‫"‪5("˽˽Item˽is", A10))', "Bumper", "Headlight‬‬
‫‪Print '(1X,‬‬ ‫"‪5(:"˽˽Item˽is", A10))', "Bumper", "Headlight‬‬ ‫‪ ‬فرم کلی فرمت منطقی به صورت ‪ Lw‬میباشد که مانند فرمتهای دیگر‪w ،‬‬
‫‪Print '(1X,‬‬ ‫‪F5.1, F7.0, F10.5)', A, B‬‬
‫به معنای عرض میدان است‪.‬‬
‫خروجی به صورت زیر است‪:‬‬
‫‪ ‬دقت کنید که خروجی برای دادههای منطقی فقط به صورت ‪ T‬یا ‪ F‬است‪.‬‬
‫‪˽˽7626˽˽5137‬‬ ‫‪ ‬همان طور که کامال مشخص است‪ ،‬در صورت اضافه آمدن عرض میدان‪T ،‬‬
‫‪˽˽˽Item˽is˽˽˽˽Bumper˽˽Item˽is˽Headlight˽˽Item˽is‬‬
‫‪˽˽˽Item˽is˽˽˽˽Bumper˽˽Item˽is˽Headlight‬‬ ‫یا ‪ F‬راستچین میشوند‪.‬‬
‫‪˽617.2˽˽˽˽29.‬‬

‫نکات‪:‬‬ ‫مثال ‪] )5‬کاربرد رشته درون فرمتها[ خروجی دستورات‬


‫‪X = 0.3; Y = 7.9‬‬
‫‪ ‬در مورد اول‪ ،‬به متغیر ‪ M‬فرمت ‪ I5‬و به متغیر ‪ N‬فرمت ‪ I6‬نسبت داده‬ ‫‪Print '(1X, "X=", F6.2, 1X, "Y=", F6.2)', X, Y‬‬
‫میشود و از دو فرمتِ ‪ I6‬باقیمانده صرف نظر میشود‪ .‬اصل کلی هم بر‬ ‫را مینویسیم‪:‬‬
‫همین است که فرمتهای اضافی در نظر گرفته نمیشوند‪.‬‬ ‫‪˽X=˽˽0.30˽Y=˽˽7.90‬‬
‫به تفاوت مورد دو و سه نگاه کنید که تنها اختالف در استفاده از فرمت "‪":‬‬
‫نکات‪:‬‬
‫است‪ .‬در مورد سوم‪ ،‬اول به موارد بعد از فرمت "‪ ":‬نگاه میشود‪ .‬هرگاه هنوز‬
‫‪ ‬دستور چاپ فوق‪ ،‬معادل دستور زیر میباشد‪.‬‬
‫متغیر یا متغیرهایی که به فرمت نیاز دارند وجود داشته باشد‪ ،‬به ادامهی موارد‬
‫‪Print '(1X, A, F6.2, 1X, A, F6.2)', "X=", X, "Y=", Y‬‬
‫بعد از "‪( ":‬شامل فرمتها و رشتهها) پرداخته میشود‪ .‬در غیر اینصورت‬
‫(یعنی متغیرها تمام شده باشند)‪ ،‬به مواردی که بعد از "‪ ":‬آمدهاند پرداخته‬ ‫‪ ‬از این مثال میتوان نتیجه گرفت که رشتههایی که درون قالب به کار گرفته‬

‫نمیشود‪.‬‬ ‫میشوند‪ ،‬عینا در خروجی چاپ میشوند‪ .‬ضمنا استفاده از فرمت ‪ A‬هم بدان‬

‫در صورتی که بعد از دقت در این مثال باز هم با فرمت "‪ ":‬مشکل دارید‪،‬‬ ‫معناست که رشته دقیقا در خروجی چاپ می شود‪.‬‬

‫سعی کنید با کدنویسی در مترجم‪ ،‬مثالهایی مشابه این مثال برای خودتان‬ ‫مثال ‪] )6‬بررسی حالتهایی که فرمتها بیشتر از متغیرها باشند‪ .‬یکی از حالتهای‬
‫طراحی کنید و با کمک خروجی‪ ،‬مهارت کافی را کسب کنید‪.‬‬ ‫بسیار مهم‪ [.‬با توجه به مقداردهیها و دستورات‪ ،‬خروجی را مینویسیم‪.‬‬

‫‪26‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل سوم (ورودی و خروجی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫‪˽˽˽˽˽˽˽5139˽˽˽˽˽˽˽31.25‬‬ ‫در مثال آخر نیز مطابق همان اصل کلی‪ ،‬از فرمتهای اضافی صرف نظر شده‬
‫نکات‪:‬‬ ‫است‪.‬‬
‫‪ ‬در صورتی که تعداد متغیرها بیشتر از تعداد فرمتها باشد‪ ،‬هربار که‬ ‫‪ ‬دقت کنید که الفاظی که به کار برده شد دقیق هستند و آنها را با هم اشتباه‬
‫فرمتها تمام میشود‪ ،‬یک رکورد عوض شده و با قواعد زیر‪ ،‬فرمتها‬ ‫نکنید‪ .‬یعنی مثال گفته شد که در صورت اتمام متغیرها از فرمتها صرف نظر‬
‫مجددا به کار گرفته میشوند‪:‬‬ ‫میشود‪ .‬بنابراین (در حالت عدم استفاده از فرمت "‪ )":‬اگر بین فرمتها‬
‫‪ -‬در صورتی که هیچ گروه دارای پرانتزی در بین فرمتها وجود‬ ‫رشته به کار رفته باشد (مثل موارد دوم و سوم که رشتهی "‪"˽˽Item˽is‬‬
‫نداشته باشد‪ ،‬استفاده مجدد از فرمتها‪ ،‬از ابتدا آغاز شده و تا انتها‬ ‫آورده شده است) از آن صرف نظر نمیشود‪.‬‬
‫ادامه مییابد‪.‬‬ ‫مثال ‪] )7‬بررسی حالتهایی که متغیرها بیشتر از فرمتها باشند‪ .‬یکی از حالتهای‬
‫‪ -‬در صورتی که یک یا چند گروه دارای پرانتز در بین فرمتها‬ ‫بسیار مهم که نیاز به تمرین زیاد برای فهم موضوع دارد[ با توجه به مقداردهیها و‬
‫وجود داشته باشد‪ ،‬استفادهی مجدد از سمتِ راستترین گروه‬ ‫دستورات‪ ،‬خروجیها را مینویسیم‪.‬‬
‫دارای پرانتز آغاز شده و تا انتها ادامه مییابد‪..‬‬ ‫‪M = 7623, N = 5137, A = 617.2, B = 29.25‬‬
‫ضمنا توجه داشته باشید که‪:‬‬ ‫‪Print '(1X, 2I6)', N, N + 1, N + 2, N + 3, N + 4‬‬

‫‪ ‬ضریب داشتن پرانتزها هیچ تاثیری در استفادهی مجدد از‬ ‫خروجی این دستور به این صورت است‪:‬‬
‫فرمتها ندارند (منظور از ضریب‪ ،‬ضریبی به جز یک‬ ‫‪˽˽˽5137˽˽5138‬‬
‫‪˽˽˽5139˽˽5140‬‬
‫میباشد)‪.‬‬ ‫‪˽˽˽5141‬‬

‫‪ ‬همیشه بیرونیترین پرانتزها مورد بررسی قرار میگیرند‪.‬‬ ‫و خروجی دستور‬

‫به مثالهای زیر توجه کنید‪.‬‬ ‫& ‪Print '(1X, I5, F10.3 / (1X, I10, F12.2))',‬‬
‫‪M, A, N, B, N + 1, B + 1, N + 2, B + 2‬‬
‫& ‪Real :: T = 1.123, U = 2.234, V = 3.345, W = 4.456,‬‬
‫‪X = 5.567, Y = 6.678, Z = 7.789‬‬
‫نیز به صورت زیر است‪:‬‬
‫& ‪a) Write (*, "(1X, F6.1, F6.2, F6.3)") T, U, V,‬‬
‫‪˽˽7623˽˽˽617.200‬‬
‫‪W, X, Y, Z‬‬
‫‪˽˽˽˽˽˽˽5137˽˽˽˽˽˽˽29.25‬‬
‫‪Output:‬‬
‫‪˽˽˽˽˽˽˽5138˽˽˽˽˽˽˽30.25‬‬
‫‪27‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪W, X, Y, Z‬‬ ‫‪1.1 2.23 3.345‬‬


‫‪Output:‬‬ ‫‪4.5 5.57 6.678‬‬
‫‪1.1 2.23 3.35 4.456‬‬ ‫‪7.8‬‬
‫‪5.57 6.68 7.789‬‬ ‫& ‪b) Write (*, "(1X, (F6.1, F6.2), F6.3)") T, U, V,‬‬
‫‪W, X, Y, Z‬‬
‫به کمک این توضیحات‪ ،‬خودتان خروجی مثال را به طور کامل تحلیل کنید‪.‬‬ ‫‪Output:‬‬
‫‪1.1 2.23 3.345‬‬
‫در این مثال و سه مثال بعد‪ ،‬به بحث استفاده از فرمت در خواندن پرداخته میشود‪.‬‬ ‫‪4.5 5.57 6.678‬‬
‫‪7.8‬‬
‫باید پذیرفت که فهم این بحث نسبت به بحث فرمت در خروجی‪ ،‬نیاز به زمان بیشتری‬ ‫& ‪c) Write (*, "(1X, F6.1, F6.2, (F6.3))") T, U, V,‬‬
‫‪W, X, Y, Z‬‬
‫دارد‪.‬‬ ‫‪Output:‬‬
‫‪1.1 2.23 3.345‬‬
‫مثال ‪ )8‬فرض کنید که به هر یک از متغیرهای زیر‪ ،‬به شکلی که نشان داده شده‪،‬‬ ‫‪4.456‬‬
‫‪5.567‬‬
‫بخواهیم مقادیری را نسبت دهیم‪:‬‬ ‫‪6.678‬‬
‫‪7.789‬‬
‫& ‪d) Write (*, "(1X, F6.1, (F6.2), (F6.3))") T, U, V,‬‬
‫‪A = 6.25, B = -1.9, C = 75.0, D = .182, E = 625.327‬‬
‫‪W, X, Y, Z‬‬
‫در صورتی که بخواهیم دادهها را به شکل زیر وارد نماییم‪:‬‬ ‫‪Output:‬‬
‫‪1.1 2.23 3.345‬‬
‫‪625-19750182625327‬‬ ‫‪4.456‬‬
‫‪5.567‬‬
‫باید از فرمت زیر برای خواندن استفاده کنیم‪:‬‬ ‫‪6.678‬‬
‫‪7.789‬‬
‫‪Read '(F3.2, 2F3.1, F3.3, F6.3(', A, B, C, D, E‬‬ ‫& ‪e) Write (*, "(1X, F6.1, 2(F6.2), (F6.3))") T, U, V,‬‬
‫‪W, X, Y, Z‬‬
‫‪Output:‬‬
‫همچنین اگر دادهها به صورت زیر وارد شوند‪:‬‬ ‫‪1.1 2.23 3.35 4.456‬‬
‫‪5.567‬‬
‫‪˽625˽-19˽750˽˽˽˽˽182˽˽625327‬‬
‫‪6.678‬‬
‫میتوان از این فرمت استفاده کرد‪:‬‬ ‫‪7.789‬‬
‫& ‪f) Write (*, "(1X, F6.1, 3(F6.2), 2(F6.3))") T, U, V,‬‬
‫‪Read '(F4.2, 2F4.1, 2F8.3)', A, B, C, D, E‬‬ ‫‪W, X, Y, Z‬‬
‫‪Output:‬‬
‫و درنهایت اگر دادهها به صورت زیر وارد شوند‪:‬‬ ‫‪1.1 2.23 3.35 4.46 5.567 6.678‬‬
‫‪7.789‬‬
‫‪˽6.25˽-1.9˽˽75. ˽.182˽625.327‬‬ ‫& ‪g) Write (*, "(1X, F6.1, (2(F6.2), (F6.3)))") T, U, V,‬‬

‫‪28‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل سوم (ورودی و خروجی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫‪ ‬بیایید با هم نحوهی خواندن متغیر ‪ A‬و ‪ B‬در هر سه مورد باال را بررسی کنیم‬ ‫فرمت میتواند به شکل زیر باشد‪:‬‬
‫و بقیه را به خودتان واگذار کنیم!‬ ‫‪Read '(4F5.0, F8.0)', A, B, C, D, E‬‬
‫در مثال اول‪ ،‬برای متغیر ‪ ،A‬فرمت ‪ F3.2‬در نظر گرفته شده است‪ .‬همانطور‬ ‫نکات‪:‬‬
‫که گفتیم‪ ،‬ابتدا به اندازهی عرض میدان فرمت یعنی ‪ w‬که سه میباشد‪ ،‬از‬
‫‪ ‬در واقع در این مثال‪ ،‬به بررسی خواندن اعداد اعشاری میپردازیم‪ .‬در‬
‫ورودی جدا میشود‪ .‬لذا ‪ 625‬از اعداد جدا میشود و چون نقطهی اعشار در‬
‫خواندن اعداد اعشاری‪ ،‬همانند خروجی از فرمت ‪ Fw.d‬استفاده میکنیم‪.‬‬
‫عرض میدان قرار ندارد و مقدار ‪ d‬برابر با دو میباشد‪ ،‬از سمت راست دو‬
‫توجه داشته باشید که در اینجا‪ ،‬اول از همه‪ ،‬به اندازهی مقدار ‪ w‬که همان‬
‫رقم به عنوان ارقام اعشار جدا شده که در نتیجه عدد ‪ 6.25‬برای متغیر ‪ A‬در‬
‫عرض میدان فرمت است‪ ،‬از دادههای ورودی انتخاب میشود (که شامل‬
‫نظر گرفته می شود‪ .‬سپس در ادامه چون فرمت متناظر متغیر ‪ B‬برابر ‪F3.1‬‬
‫اعداد‪ ،‬مثبت یا منفی و جاهای خالی میشود) و بالفاصله تمام جاهای خالی‪،‬‬
‫میباشد‪ ،‬بنابراین از ادامهی ورودی به اندازهی سه تا جدا میشود که نتیجه‬
‫شامل جاهای خالی اول‪ ،‬آخر و بین ارقام حذف میشوند‪ .‬حال سه حالت‬
‫آن‪ ،‬گرفتن ‪ -19‬است‪ .‬در اینجا هم چون نقطهی اعشار در عرض میدان‬
‫ممکن است رخ دهد‪:‬‬
‫نیست و مقدار ‪ d‬برابر یک است‪ ،‬از سمت راست یک رقم اعشار جدا‬
‫‪ -‬در حالت اول‪ ،‬نقطهی اعشار در عرض میدان وجود ندارد‪ .‬در‬
‫میشود و مقدار ‪ -1.9‬به متغیر ‪ B‬نسبت داده میشود‪.‬‬
‫اینصورت‪ ،‬به اندازهی مقدار ‪ ،d‬از سمت راست ارقامِ گرفته شده‬
‫در مورد دوم‪ ،‬برای متغیر ‪ A‬فرمت ‪ F4.2‬در نظر گرفته شده است‪ .‬پس به‬
‫جدا میشود و به عنوان ارقام اعشار در نظر گرفته میشود‪.‬‬
‫اندازهی عرض میدان که برابر چهار است‪ ،‬دادهها از ورودی گرفته میشوند‬
‫‪ -‬در حالت دوم‪ ،‬نقطهی اعشار در عرض میدان وجود دارد‪ .‬در این‬
‫که (همانطور که گفتیم) شامل جای خالی اولی و ‪ 625‬میشود‪ .‬بعد از‬
‫صورت دقیقا همان چیزی که از ورودی گرفته شده منظور میشود و‬
‫حذف جای خالی‪ ،‬چون نقطهی اعشار در عرض میدان وجود ندارد و مقدار‬
‫مقدار ‪ ،d‬هیچ تاثیری در جای نقطهی اعشار ندارد!‬
‫‪ d‬برابر دو میباشد‪ ،‬لذا از سمت راست دو رقم به عنوان ارقام اعشار جدا‬
‫‪ -‬در حالت سوم‪ ،‬شکلی از حالت نمایی در عرض میدان فرمت قرار‬
‫میشوند و مقدار ‪ 6.25‬به متغیر ‪ A‬اختصاص داده میشود‪ .‬در ادامه‪ ،‬چون‬
‫میگیرد‪ .‬یعنی در عرض میدان‪ E ،‬وجود دارد‪ .‬این حالت در کتابها‬
‫فرمت متناظر متغیر ‪ B‬برابر ‪ F4.1‬میباشد‪ ،‬از ادامهی ورودی به اندازهی‬
‫بررسی شده ولی به دالیلی من از بررسی آن در اینجا اجتناب‬
‫عرض میدان که چهار است‪ ،‬از دادهها گرفته میشود که شامل یک جای‬
‫میکنم‪.‬‬

‫‪29‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫نمیکند؛ ولی اگر اینبار از دستور‬ ‫خالی و ‪ -19‬میشود و به ترتیب توضیح داده شده‪ ،‬مقدار ‪ -1.9‬به متغیر ‪B‬‬
‫‪Read '(A2, A12)', Speech1, Speech2‬‬ ‫اختصاص داده میشود‪.‬‬
‫استفاده کنیم‪ ،‬محتوای متغیرها به این شکل خواهد بود‪:‬‬ ‫در مورد سوم‪ ،‬فرمت متناظر متغیر ‪ A‬برابر ‪ F5.0‬میباشد‪ .‬لذا به اندازهی‬

‫˽˽˽˽‪Speech1 = AB‬‬ ‫&‬ ‫‪Speech2 = an,app‬‬ ‫عرض میدان که پنج است‪ ،‬از دادههای ورودی انتخاب میشود که شامل یک‬
‫جای خالی و ‪ 6.25‬میشود‪ .‬بنابراین اینجا چون نقطهی اعشار در عرض میدان‬
‫نکات‪:‬‬
‫است‪ ،‬اصال به مقدار ‪ d‬توجهی نمیشود و همان ‪ 6.25‬برای ‪ A‬در نظر گرفته‬
‫‪ ‬دقت(!)‪ :‬این خیلی مهم است که توجه داشته باشید در بحث متغیرهای‬
‫میشود‪ .‬در آخر نیز مقدار ‪ -1.9‬به متغیر ‪ B‬با تبعیت از فرمت ‪F5.0‬‬
‫کاراکتر‪ ،‬دامنهی انتخابی از دادههای ورودی‪ ،‬بر اساس فرمتی که در درون‬
‫اختصاص داده میشود‪.‬‬
‫دستور خواندن (‪ )Read‬قرار دارد تعیین میشود و هیچ ارتباطی به طول‬
‫فکر میکنم با توضیحاتی که راجع به خواندن اعداد حقیقی داده شد‪ ،‬بررسی خواندن‬
‫متغیر کاراکتر ندارد‪ .‬بحث طول متغیر کاراکتر وقتی مطرح میشود که‬
‫دادههای صحیح برایتان بسیار ساده خواهد بود‪ .‬ولی برای اطمینان حتما خودتان مثالهای‬
‫دادههای انتخاب شده‪ ،‬میخواهند درون متغیر قرار بگیرند‪.‬‬
‫کتابهای مختلف را نگاه کنید‪.‬‬
‫‪ ‬در دستورات خواندن اول و دوم‪ ،‬همانطوری که گفتیم‪ ،‬فرمتهای ‪ A‬و‬
‫‪ A6‬تفاوتی نخواهند داشت‪ .‬زیرا فرمت ‪ A‬از همان طول خود متغیر به عنوان‬ ‫مثال ‪ )9‬چنانچه اعالن و دستور خواندن به شکل زیر باشد‬
‫خواندن دادهها استفاده میکند و در اینجا چون طول متغیرها برابر ‪ 6‬است‪،‬‬ ‫‪Character (6) :: Speech1, Speech2‬‬
‫‪Read '(2A)', Speech1, Speech2‬‬
‫لذا فرمت ‪ A‬و ‪ A6‬تفاوتی نخواهند داشت‪ .‬پس طبق نکتهای که گفته شد‪،‬‬
‫با وارد کردن دادهها به صورت‬
‫مطابق فرمت ‪ ،A6‬به اندازهی شش تا از دادههای ورودی برای متغیر‬
‫‪AB1''34;an,apple˽a˽day‬‬
‫‪ Speech1‬و به اندازهی شش تا از دادههای بعدی برای متغیر ‪Speech2‬‬
‫در نظر گرفته میشود و چون طول دادههای گرفته شده دقیقا با طول متغیر‬ ‫محتوای متغیرها به شکل زیر درمیآیند‪:‬‬

‫برابر است‪ ،‬دادهها عینا درون متغیر قرار میگیرند که نتیجه هم برایتان آورده‬ ‫‪Speech1 = AB1' '3‬‬ ‫&‬ ‫‪Speech2 = 4;an,a‬‬

‫شد‪.‬‬ ‫دستور خواندن باال‪ ،‬تفاوتی با دستور‬


‫‪Read '(A6)', Speech1, Speech2‬‬

‫‪32‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل سوم (ورودی و خروجی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫نکات‪:‬‬ ‫اما در دستور خواندن آخر‪ ،‬فرمت متناظر متغیر ‪ Speech1‬برابر ‪ A2‬است‪.‬‬
‫بنابراین به اندازهی دو تا از دادههای ورودی برای این متغیر در نظر گرفته‬
‫‪ ‬از هر دو فرمت ‪ X‬و ‪ T‬برای پریدن (‪ )Skip‬از روی تعدادی از دادهها‬
‫میشود؛ اما حاال که دادههای گرفته شده میخواهند درون متغیر جایگذاری‬
‫استفاده میشود؛ ولی وقتی از فرمت ‪ X‬استفاده میکنیم‪ ،‬کنترل روی دادهها‪،‬‬
‫شوند‪ ،‬چون تعداد دادهها از طول متغیر کمتر است (تعداد دادهها دو تا و طول‬
‫دقیقا از دادهی بعدی که فرمت ‪ X‬به آن میرسد شروع میشود‪ .‬در حالی که‬
‫متغیر شش است) لذا دادهها از چپ چیده میشوند‪ .‬فرمت متناظر متغیر‬
‫وقتی از فرمت ‪ T‬استفاده میکنیم‪ ،‬کنترل روی دادهها‪ ،‬از همان دادهای که‬
‫‪ Speech2‬نیز ‪ A12‬است‪ .‬پس از دادههای باقیمانده‪ ،‬تعداد دوازده تا گرفته‬
‫فرمت ‪ T‬به آن میرسد شروع میشود‪ .‬به همین دلیل است که در دو دستور‬
‫میشود‪ .‬ولی در هنگام جایگذاری‪ ،‬چون تعداد دادههای گرفته شده از طول‬
‫خواندن باال‪ ،‬فرمتهای ‪ 3X‬و ‪ T4‬که در ابتدا آورده شدهاند‪ ،‬معادل هم‬
‫متغیر بیش تر است‪ ،‬شش داده از سمت راست گرفته شده و در داخل متغیر‬
‫میباشند‪.‬‬
‫جایگذاری میشوند‪.‬‬
‫‪ ‬فرمت ‪ X‬از آخرین محلی که کنترل روی دادهها در آنجا بوده عمل میکند‬
‫مثال ‪] )12‬استفاده از فرمتهای ‪ X‬و ‪ T‬در خواندن دادهها و تفاوت آنها با یکدیگر[‬
‫ولی فرمت ‪ T‬همیشه از اول خط (‪ )Record‬عمل میکند‪ .‬لذا به همین علت‬
‫فرض کنید که بخواهیم به هر یک از متغیرهای زیر‪ ،‬به شکلی که نشان داده شده‪،‬‬
‫است که فرمتهای ‪ 6X‬و ‪ T12‬و همچنین فرمتهای ‪ 5X‬و ‪ T20‬در هر‬
‫دو دستور معادل هستند‪.‬‬ ‫مقادیری را نسبت دهیم‪:‬‬

‫‪ ‬دو نکتهی فوق برای استفاده از فرمتهای ‪ X‬و ‪ T‬در خروجی نیز صادق‬ ‫‪I = 4, J = 56, K = 137‬‬

‫هستند‪.‬‬ ‫و دادههای ورودی به شکل زیر میباشند‪:‬‬


‫‪ ‬همانطور که میدانید‪ ،‬برای پریدن از روی خطها (‪ ،)Record‬میتوانید از‬ ‫‪I˽=˽4˽˽˽J˽=˽56˽˽K˽=˽137‬‬

‫فرمت "‪ "/‬استفاده کنید‪.‬‬ ‫در این صورت میتوان از دستور خواندن‬

‫در آخر بحث فرمتهای خواندن‪ ،‬به این نکته اشاره میکنم که سعی کنید همیشه‬ ‫‪Read '(3X, I2, 6X, I3, 5X, I4)', I, J, K‬‬

‫برای چک کردن عملکرد برنامهی نوشته شده‪ ،‬پس از خواندن دادهها از ورودی‪ ،‬قبل از‬ ‫یا دستور‬

‫اینکه هیچ تغییری در داده های خوانده شده بدهید‪ ،‬از آنها خروجی بگیرید تا از صحیح‬ ‫‪Read '(T4, I2, T12, I3, T20, I4)', I, J, K‬‬

‫خوانده شدن دادهها اطمینان حاصل نمایید‪.‬‬ ‫استفاده کرد‪.‬‬

‫‪31‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫& ‪Real :: Temperature, Volume, SumOfTemps = 0.0,‬‬ ‫همچنین توجه داشته باشید که در خروجیها‪ ،‬برای اینکه شاکلهی مناسبی به‬
‫‪SumOfVols = 0.0, MeanTemperature, MeanVolume‬‬
‫‪! Open the File as Unit 15, Set up the Input and Output‬‬ ‫اطالعات خروجی بدهیم‪ ،‬چارهای نداریم جز اینکه از فرمت استفاده کنیم‪ .‬ولی پیشنهاد‬
‫‪! Formats and Display the Table Heading‬‬
‫& ‪Write (*, '(1X, A)', Advance = "No") "Enter Name of Data‬‬ ‫میشود به دلیل پیچیدگیهایی که در استفاده از فرمت در خواندن وجود دارد‪ ،‬تا جایی‬
‫"‪File:‬‬
‫‪Read*, FileName‬‬ ‫که امکان دارد‪ ،‬در خواندن دادهها از فرمت استفاده نشده و به پیشفرضها (یعنی استفاده‬
‫& ‪Open (Unit = 15, File = FileName, Status = "OLD",‬‬
‫)‪Iostat = OpenStatus‬‬ ‫از دستورات *‪ Read (*,*) ،Read‬و )* ‪ )Read (Unit,‬اکتفا شود؛ ولی به هر حال‬
‫‪If (OpenStatus .GT. 0) Stop‬‬
‫)‪100 Format (4X, F4.1, T13, F4.1‬‬
‫برای امتحان‪ ،‬باید به نکات ذکر شده مسلط باشید!‬
‫)‪110 Format (1X, A11, A10‬‬
‫)‪120 Format (1X, F8.1, F14.1‬‬ ‫مثال ‪] )11‬برنامه کاملی برای خواندن دادهها با تعداد نامعلوم[ فرض کنید که دستگاه‬
‫*‪Print‬‬
‫"‪Print 110, "Temperature", "Volume‬‬ ‫ثبت اطالعات یک فرآیند‪ ،‬اطالعات مربوط به زمان‪ ،‬دما‪ ،‬فشار و حجم را گرفته و آنها‬
‫"======" ‪Print 110, "===========",‬‬
‫‪! While There is More Data, Read Temperatures and Volumes,‬‬ ‫را در یک فایل ذخیره میکند‪ .‬هر رکورد اطالعات فایل‪ ،‬شامل موارد زیر است‪:‬‬
‫‪! Display Each in the Table, and Calculate the Necessary‬‬
‫‪! Sums‬‬ ‫‪ -‬زمان در ستونهای ‪ 1‬تا ‪ 4( 4‬رقم صحیح)‬
‫‪Do‬‬
‫& )‪Read (Unit = 15, FMT = 100, Iostat = InputStatus‬‬ ‫‪ -‬دما در ستونهای ‪ 5‬تا ‪ 4( 8‬رقم به صورت عدد اعشاری)‬
‫‪Temperature, Volume‬‬
‫‪If (InputStatus .GT. 0) Stop‬‬ ‫‪ -‬فشار در ستونهای ‪ 9‬تا ‪ 4( 12‬رقم به صورت عدد اعشاری)‬
‫‪If (InputStatus .LT. 0) Exit‬‬
‫‪Print 120, Temperature, Volume‬‬ ‫‪ -‬حجم در ستونهای ‪ 13‬تا ‪ 4 ( 16‬رقم به صورت اعشاری)‬
‫‪Count = Count + 1‬‬
‫‪SumOfTemps = SumOfTemps + Temperature‬‬ ‫اعداد اعشاری دما‪ ،‬فشار و حجم‪ ،‬بدون نقطهی اعشار نوشته میشوند؛ ولی نقطهی اعشار‬
‫‪SumOfVols = SumOfVols + Volume‬‬
‫‪End Do‬‬ ‫بین رقم سوم و چهارم آن فرض میشود‪.‬‬
‫‪MeanTemperature = SumOfTemps / Count‬‬
‫‪MeanVolume = SumOfVols / Count‬‬ ‫قرار است برنامهای بنویسیم که مقادیر دما و حجم را از فایل ثبت اطالعات بخواند و‬
‫‪Print*, "Average Temperature is:", MeanTemperature‬‬
‫‪Print*, "Average Volume is:", MeanVolume‬‬ ‫آنها را به شکل جدول نشان دهد‪ .‬همچنین مقادیر متوسط دما و فشار را نیز نشان دهد‪.‬‬
‫در صورتی که دادههای ورودی به شکل زیر در فایل ذخیره شده باشد‬ ‫‪Program Temperature_Volume_Reading‬‬
‫‪Implicit None‬‬
‫‪1200034203221015‬‬ ‫‪Integer :: Count = 0, OpenStatus, InputStatus‬‬
‫‪1300038803221121‬‬ ‫‪Character (20) :: FileName‬‬

‫‪32‬‬
‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل سوم (ورودی و خروجی) دانشگاه صنعت آب و برق (شهید عباسپور)‬

‫با عبارت ‪ File‬نیز آشنا هستید که به منظور وارد کردن نام فایل ورودی به‬ ‫‪1400044803241425‬‬
‫‪1500051303201520‬‬
‫کار گرفته میشود‪ .‬به این منظور هم میتوان یک رشته را مساوی با ‪File‬‬ ‫‪1600055503181665‬‬
‫‪1700061303191865‬‬
‫قرار داد‪ ،‬هم میتوان میتوان نام فایل را به یک متغیر کاراکتر نسبت داد و‬ ‫‪1800067503232080‬‬
‫‪1900072103282262‬‬
‫سپس آن متغیر کاراکتر را با عبارت ‪ File‬مساوی قرار داد که در این مثال‬ ‫‪2000076803252564‬‬
‫‪2100083503272869‬‬
‫همین روش به کار رفته است‪ .‬استفاده از این روش به ما این امکان را‬ ‫‪2200088903303186‬‬
‫می دهد که بدون تغییر در کدها‪ ،‬با هر دفعه اجرای برنامه‪ ،‬نام فایل جدیدی‬ ‫خروجی به شکل زیر درمیآید‪:‬‬
‫را وارد کنیم‪.‬‬ ‫‪Enter Name of Data File: fil5.dat‬‬
‫رشتههای مختلفی در جلوی عبارت ‪ Status‬میتوانند قرار بگیرند که‬ ‫˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽‬
‫‪Temperature˽˽˽˽Volume‬‬
‫مهمترین آنها عبارتند از "‪ "NEW" ،"OLD‬و "‪."REPLACE‬‬ ‫======˽˽˽˽===========‬
‫‪˽˽˽˽˽34.2˽˽˽˽˽˽˽˽˽101.5‬‬
‫‪ OLD‬بدین معنی است که فایل بر روی سیستم وجود دارد‪ NEW .‬بدین‬ ‫‪˽˽˽˽˽38.8˽˽˽˽˽˽˽˽˽112.1‬‬
‫‪˽˽˽˽˽44.8˽˽˽˽˽˽˽˽˽142.5‬‬
‫معنی است که فایل هنوز وجود ندارد و باید ایجاد گردد؛ بنابراین دستور‬ ‫‪˽˽˽˽˽51.3˽˽˽˽˽˽˽˽˽152.0‬‬
‫‪˽˽˽˽˽55.5˽˽˽˽˽˽˽˽˽166.5‬‬
‫‪ Open‬یک فایل خالی با نام داده شده ایجاد مینماید‪ REPLACE .‬نیز‬ ‫‪˽˽˽˽˽61.3˽˽˽˽˽˽˽˽˽186.5‬‬
‫‪˽˽˽˽˽67.5˽˽˽˽˽˽˽˽˽208.0‬‬
‫به معنای آن است که چنانچه فایل با نام داده شده وجود ندارد‪ ،‬آن را‬ ‫‪˽˽˽˽˽72.1˽˽˽˽˽˽˽˽˽226.2‬‬
‫ایجاد مینماید و چنان چه وجود دارد‪ ،‬فایل جدید را جایگزین فایل قبلی‬ ‫‪˽˽˽˽˽76.8˽˽˽˽˽˽˽˽˽256.4‬‬
‫‪˽˽˽˽˽83.5˽˽˽˽˽˽˽˽˽286.9‬‬
‫مینماید‪.‬‬ ‫‪˽˽˽˽˽88.9˽˽˽˽˽˽˽˽˽318.6‬‬
‫‪Average Temperature is:‬‬ ‫‪61.34‬‬
‫به عبارت ‪ Iostat‬درون ‪ Open‬نیز یک متغیر صحیح نسبت داده میشود‬ ‫‪Average Volume is: 196.11‬‬

‫که چنانچه فایل بدون هیچ مشکلی باز شود‪ ،‬به آن عدد صفر و در غیر‬ ‫نکات‪:‬‬
‫اینصورت عددی مثبت داده میشود‪.‬‬
‫‪ ‬به عباراتی که در درون دستور ‪ Open‬قرار گرفتهاند دقت کنید‪ .‬عبارت‬
‫جز موارد ‪ Unit‬و ‪ ،File‬بقیه ی موارد جزء مباحث درسی شما نیستند؛ ولی‬
‫‪ Unit‬که همان شمارهی فایل را مشخص میکند و با آن آشنایی دارید‪.‬‬
‫چون به نظر با اهمیت میآیند‪ ،‬شرح آنها آورده شد‪.‬‬

‫‪33‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪ ‬به خروجی برنامه هم دقت کنید که با استفاده از فرمت و دستورات کامال‬ ‫‪ ‬دستور ‪ Stop‬همانند دستور ‪ End‬که در آخر برنامه میآید عمل میکند‪ ،‬با‬
‫ساده ای‪ ،‬خروجی به شکل یک جدول درآمد‪ .‬شما هم همیشه سعی کنید به‬ ‫این تفاوت که ‪ Stop‬در هر جایی بین ابتدا و انتهای برنامه میتواند آورده‬
‫بهترین نحو از فرمتها در خروجی استفاده کنید تا خروجی شما کامال‬ ‫شود‪ .‬لذا در این برنامه‪ ،‬همانطور که دیده میشود‪ ،‬دستور ‪ Stop‬وقتی عمل‬
‫کاربردی‪ ،‬قابل فهم و البته زیبا باشد‪.‬‬ ‫میکند که مقدار متغیر ‪ OpenStatus‬در داخل دستور ‪ Open‬بزرگتر از‬
‫صفر شود (همانطور که توضیح داده شد‪ ،‬در درون ‪ ،Open‬وقتی باز کردن‬
‫بخش دوم – تمرینها‬
‫فایل با مشکل مواجه شود‪ ،‬مقدار متغیر جلوی ‪ Iostat‬بزرگتر از صفر‬
‫توجه‪ :‬همیشه در همهی فصول مسالهها (به جز یک مورد استثنا در فصل زیربرنامهها)‬ ‫میشود) یا مقدار متغیر ‪ InputStatus‬در داخل دستور ‪( Read‬به دلیل‬
‫را اول روی کاغذ حل کنید‪ .‬یعنی مثال اگر سوالی خروجی یک برنامه را میخواهد‪ ،‬اول‬ ‫وجود اشکال در فایل ورودی)‪ ،‬بزرگتر از صفر شود‪ .‬متاسفانه بحث ‪Stop‬‬
‫سعی کنید خروجی را روی کاغذ بنویسید؛ سپس کدها را در مترجم بزنید و با اجرای‬ ‫هم جز موارد درسی شما نیست!‬
‫برنامه‪ ،‬خروجی را ببینید و با خروجی خودتان مقایسه کنید‪ .‬یا مثال در تمام مسالههایی که‬ ‫‪ ‬دقت کنید که وقتی فایل ورودی دارای روال مشخصی باشد (در صورت‬
‫قرار است برنامه ی کامل بنویسید‪ ،‬ابتدا برنامه را کامل و با تمام جزئیات (هیچ وقت به‬ ‫مساله گفته شد که ستونهای هر خط‪ ،‬دارای چه محتوایی هستند)‪ ،‬استفاده از‬
‫خیال بلد بودن مسائل‪ ،‬خالصه نویسی نکنید‪ .‬این اصل خیلی مهمی است‪ ).‬روی کاغذ‬ ‫فرمت در خواندن هم بسیار آسانتر میشود‪ .‬اینجا نیز از فرمت در خواندن‬
‫بنویسید و سپس عینا کدهایی را که روی کاغذ نوشتهاید را در مترجم تایپ کنید و‬ ‫استفاده شد‪.‬‬
‫خطایابی کنید‪ .‬بعد از پیدا کردن خطاها‪ ،‬سعی کنید خطاها را روی کاغذ رفع کنید (!) و‬ ‫‪ ‬توجه کنید که نقطهی اعشار در دادههای ورودی وجود ندارد و به کمک‬
‫مجددا با اصالح اشتباهات‪ ،‬خطایابی کنید‪ .‬اینقدر این روال را ادامه دهید تا برنامه بدون‬ ‫فرمتها به دادهها نقطهی اعشار میدهیم‪ .‬این همان بحثی است که مفصال از‬
‫خطا شود‪ .‬در نهایت نیز با خروجی گرفتن از برنامه‪ ،‬ببینید که برنامهتان کار مورد نظر را‬ ‫آن حرف زده شد و در اینجا در یک مثال کاربردی از آن بحث استفاده‬
‫انجام میدهد یا نه‪ .‬در هر صورت‪ ،‬بیشتر از حد کار کردن یا کمتر از حد کار کردن با‬ ‫شد‪.‬‬
‫مترجم (هر دو)‪ ،‬مضر خواهد بود‪ .‬فراموش نکنید که امتحان میانترم و پایانترم شما‬ ‫‪ ‬در این مثال چون تعداد دادهها معلوم نیست‪ ،‬از دستور ‪ Iostat‬در خواندن‬
‫کاغذی است!‬ ‫استفاده شد و مجددا دقت کنید که از دستور ‪ Stop‬و ‪ Exit‬به چه نحوی‬

‫تمرین ‪ )1‬با توجه با اعالنهای زیر‬ ‫برای کنترل دادههای خوانده شده استفاده شد‪.‬‬

‫‪34‬‬
)‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل سوم (ورودی و خروجی) دانشگاه صنعت آب و برق (شهید عباسپور‬

e) Read 220, X, I, Y, J, C Integer :: Number = 12345


220 Format (F6.2 / I5 // F6.0, I6 / A) Real :: Alpha = 87.6543
f) Read '(A, I2, F5.2)', C, I, X Character (25) :: Form_1 = '(1X, I10, F10.2, "---")', &
g) Read '(A10, I10, F10.0)', C, I, X Title * 8 = "Exercise"
.‫) خروجی کدهای زیر را بنویسید‬3 ‫تمرین‬ .‫خروجی هریک از موارد زیر را بنویسید‬
a) Integer I
I = -123 a) Print '("Computer Science – Exercise", F4.1)', 3 * 2.1 &
Print '("I˽=˽", I6.5)', I - 1.1
b) Real :: A, B, Sum, Difference b) Print '(1X, A, F4.1)', "Computer Science", 5.2
A = 1.0020E6; B = 1.0001E6 c) Print 10, Title, 5.2
Sum = A + B 10 Format ("Computer Science", A2, F3.1
Difference = A - B d) Print20, Number, Number + 1, Alpha, Alpha + 1, Alpha + 2
Print 100, A, B, Sum, Difference 20 Format (1X, 2I7, F10.5, F10.3, F10.3)
100 Format (1X, "A˽=˽", ES14.6, "B˽=˽", E14.6, & e) Print 30, Number, Alpha, Number + 1, Alpha +1
"Sum˽=˽", E14.6, "Difference˽=˽", E14.6) 30 Format (1X, I5, F7.4 / 1X, I5, E12.5)
c) Integer I1, I2 f) Print Form_1, Number, Alpha, Number, Alpha
I1 = 10, I2 = 4 ** 2 g) Print '(1X, I5, A2, I6 / 1X, 13("="))', Number, "=" &
Print 200, I1 .GT. I2 , 12345
200 Format ("Result˽=˽", L6) h) Print 40, Number, Alpha, Number, Alpha
40 Format (/// 2(1X, I6 // 1X, F6.2)
‫ اطالعات مربوط به‬،‫) فرض کنید که دستگاه ثبت اطالعات یک فرآیند‬4 ‫تمرین‬ i) Print 50, Number, Alpha, Number, Alpha, Number, Alpha
50 Format (1X, I6, F7.2, (1X, I5, F6.1))
‫ هر رکورد‬.‫ فشار و حجم را گرفته و آنها را در یک فایل ذخیره میکند‬،‫ دما‬،‫زمان‬
،‫ به شکلی که نشان داده شده‬،‫) فرض کنید که به هر یک از متغیرهای زیر‬2 ‫تمرین‬
:‫ شامل موارد زیر است‬،‫اطالعات فایل‬
:‫بخواهیم مقادیری را نسبت دهیم‬
)‫ رقم صحیح‬4( 4 ‫ تا‬1 ‫ زمان در ستونهای‬-
X = 123.77, Y = 6.0, I = 77, J = 550, C = Fortran
)‫ رقم به صورت عدد اعشاری‬4( 8 ‫ تا‬5 ‫ دما در ستونهای‬-
‫ ورودی مناسب را به دست آورید‬،‫با توجه به هر یک از دستورات خواندن‬
)‫ رقم به صورت عدد اعشاری‬4( 12 ‫ تا‬9 ‫ فشار در ستونهای‬-
Integer I, J; Real X, Y; Character (8) :: C
)‫ رقم به صورت اعشاری‬4 ( 16 ‫ تا‬13 ‫ حجم در ستونهای‬- a) Read*, I, J, X, Y
b) Read '(I3, F7.0, 2X, I5, T20, F5.0)', I, J, X, Y
‫ بدون نقطهی اعشار نوشته میشوند؛ ولی نقطهی‬،‫ فشار و حجم‬،‫اعداد اعشاری دما‬ c) Read '(I5, F6.0)', I, X, J, Y
d) Read 200, X, Y, I, J
.‫اعشار بین رقم سوم و چهارم آن فرض میشود‬ 200 Format (F5.2, 1X, F1.0, T4, I2, T9, I3)

35
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪ -‬قیمت واحد (یک عدد ‪ 5‬رقمی بدون نقطهی اعشار که سه رقم اول آن‬ ‫قرار است برنامهای بنویسیم که مقادیر زمان‪ ،‬دما‪ ،‬فشار و حجم را از فایل ثبت اطالعات بخواند‬
‫قسمت صحیح و دو رقم آخر‪ ،‬قسمت اعشاری آنرا تشکیل میدهد) در‬ ‫و همهی آنها را به شکل جدولی مانند جدول زیر نشان دهد‪.‬‬

‫ستونهای ‪ 29‬تا ‪33‬‬ ‫‪Time‬‬ ‫‪Temperature‬‬ ‫‪Pressure‬‬ ‫‪Volume‬‬


‫‪12:00 PM‬‬ ‫‪34.2‬‬ ‫‪32.2‬‬ ‫‪101.5‬‬
‫‪ -‬موجودی آستانه (که سفارش مجدد کاال را بیان میکند) در ستونهای ‪34‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬
‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬
‫تا ‪36‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬
‫‪ -‬تعداد موجود در انبار در ستونهای ‪ 37‬تا ‪39‬‬ ‫‪10:00 PM‬‬ ‫‪88.9‬‬ ‫‪33.0‬‬ ‫‪318.6‬‬

‫‪ -‬سقف موجودی کاالی مورد نظر در انبار در ستونهای ‪ 42‬تا ‪42‬‬ ‫دقت کنید که‪:‬‬

‫‪ .1‬مثال فایل ورودی همانند فایل ورودی نمونه در مثال ‪ 11‬است‪.‬‬


‫نمونهی فایل ورودی به شرح زیر است‪.‬‬
‫‪ .2‬همانطور که در جدول هم میبینید‪ ،‬در این برنامه زمان از فرمت نظامی به فرمت‬
‫‪1011TELEPHOTO˽POCKET˽CAMERA˽5495˽15˽20˽25‬‬
‫معمولی تبدیل شده و سپس چاپ میشود‪ .‬یعنی مثال ‪ 0900‬به صورت ‪9:00 AM‬‬
‫‪1012MINI˽POCKET˽CAMERA˽˽˽˽˽˽2495˽15˽12˽20‬‬
‫و ‪ 1500‬به صورت ‪ 3:00 PM‬چاپ میشود‪.‬‬
‫‪1021POL.˽ONE-STEP˽CAMERA˽˽˽˽4995˽10˽20˽20‬‬
‫‪ .3‬تعداد خطهای فایل ورودی از قبل مشخص نیست‪.‬‬
‫دقت کنید که تعداد خطهای فایل از قبل مشخص نیست‪.‬‬
‫تمرین ‪ )5‬برنامهای بنویسید که شمارهی کاالیی را در فایلی به اسم ‪Inventor.txt‬‬
‫جستجو نماید و آن کاال را با شمارهی وارد شده بیابد‪ .‬چنانچه آن کاال یافت شد‪،‬‬
‫اطالعات مربوط به نام آن‪ ،‬تعداد موجود و قیمت واحد آن را در خروجی چاپ نماید‪.‬‬
‫همچنین در صورت یافت نشدن کاال‪ ،‬پیغام مناسبی مبنی بر یافت نشدن کاالی با آن‬
‫شماره در خروجی چاپ نماید‪ .‬هر رکورد اطالعات فایل‪ ،‬شامل موارد زیر است‪:‬‬

‫‪ -‬شمارهی کاال در ستونهای ‪ 1‬تا ‪4‬‬


‫‪ -‬نام کاال در ستونهای ‪ 5‬تا ‪28‬‬

‫‪36‬‬
37
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫البته از اشکال دیگر نیز میتوان برای اعالن آرایه استفاده کرد؛ ولی توصیه‬
‫فصل چهارم (آرایهها)‬
‫میشود از همین روش کلی (که بهترین روش هم هست) استفاده شود‪.‬‬

‫‪ ‬به سادهترین نحوههای مقداردهی دقت کنید‪.‬‬ ‫بخش اول – مثالها‬


‫‪ .1‬میتوان دادهها را درون (‪ )//‬قرار داد و به آرایه نسبت داد (مثل‬ ‫مثال ‪ )1‬در این برنامه یک آرایه مقداردهی شده و سپس جذر اعداد موجود در آرایه‬
‫کاری که در همین مثال انجام دادیم‪ .).‬در اینصورت باید دقت‬ ‫محاسبه و چاپ میشود‪.‬‬
‫شود که تعداد دادههای درون (‪ )//‬دقیقا باید با تعداد عناصر آرایه‬ ‫‪Program Square_Roots‬‬
‫‪Implicit None‬‬
‫برابر باشد؛ وگرنه برنامه با خطا مواجه میشود‪.‬‬ ‫‪! Declare Variables‬‬
‫‪Integer :: I‬‬
‫‪ .2‬به کمک دستور ‪ Data‬هم می توان به یک آرایه مقداردهی کرد‪.‬‬ ‫‪Real, Dimension (10) :: Value = (/1, 2, 3, 4, 5, 6, 7, 8 & ,‬‬
‫)‪9, 10/‬‬
‫مثال در همین مثال‪ ،‬با استفاده از دستور ‪ Data‬داریم‪:‬‬ ‫‪Real, Dimension (10) :: Square_Root‬‬
‫‪! Calculate the Square Roots of the Number‬‬
‫‪Data Value /1, 2, 3, 4, 5, 6, 7, 8, 9, 10/‬‬ ‫‪Do I = 1, 10‬‬
‫))‪Square_Root (I) = Sqrt (Value (I‬‬
‫در اینجا تعداد دادههای درون دستور ‪ Data‬میتواند کمتر از‬ ‫‪End Do‬‬
‫‪! Write out Each Number and Its Square Root‬‬
‫تعداد عناصر باشد؛ ولی برنامه با ‪ Warning‬مواجه میشود‪ .‬اما اگر‬ ‫‪Do I = 1, 10‬‬
‫تعداد دادهها بیشتر از تعداد عناصر آرایه باشد‪ ،‬برنامه با خطا مواجه‬ ‫)‪Write (*, 100) Value (I), Square_Root (I‬‬
‫& " = ‪100 Format (1X, "Value = ", F5.1, "Square Root‬‬
‫میشود‪.‬‬ ‫)‪, F10.4‬‬
‫‪End Do‬‬
‫‪End Program‬‬
‫ضمنا اگر چند عنصرِ پشت سر هم داشته باشیم که بخواهیم به آنها‬
‫مقدار یکسانی بدهیم‪ ،‬میتوانیم در دستور ‪ Data‬از ضریب استفاده‬ ‫نکات‪:‬‬
‫کنیم‪ .‬مثال میتوانیم داشته باشیم‪:‬‬ ‫‪ ‬شکل کلی اعالن یک آرایه به صورت زیر است‪:‬‬
‫‪Data Value /1, 2, 3, 4, 3 * 5, 6, 7, 8/‬‬ ‫]… ‪type, Dimension ([I1 :] I2 [, [ J1 :] J2, …]) :: Array1 [, Array2,‬‬
‫لذا دستور ‪ Data‬انعطاف پذیرتر از مورد اول است‪.‬‬

‫‪38‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها)‬

‫آرایه را میتوان با نوشتن نام آرایه در دستورات چاپ‪ ،‬در خروجی چاپ‬ ‫در بعضی موارد‪ ،‬مقادیری که می خواهیم به عناصر یک آرایه نسبت دهیم‪ ،‬از روال‬ ‫‪‬‬
‫کرد؛ مثال‪:‬‬ ‫خاصی پیروی میکنند و قاعدهمند میباشند‪ .‬در اینصورت شاید بتوان از حلقه برای‬
‫مقداردهی استفاده کرد‪ .‬مثال برای مقداردهی به متغیر ‪ Value‬در همین مثال‬
‫‪Print*, Value‬‬
‫میتوان از حلقه استفاده کرد‪:‬‬
‫همچنین هر عنصر دلخواه آرایه را نیز میتوان جداگانه چاپ کرد؛ مثال‪:‬‬
‫‪Do I = 1, 10‬‬
‫)‪Print*, Value (1), Value (2‬‬ ‫‪Value (I) = I‬‬
‫‪End Do‬‬
‫فقط دقت داشته باشید که در این مثال چون دستور چاپ درون حلقهی‬
‫استفاده از حلقهها برای مقداردهی‪ ،‬کامال بر مقداردهی عادی اولویت دارد؛‬
‫صریح قرار گرفته است‪ ،‬به تعداد دفعاتی که حلقه تکرار میشود به دستور‬
‫مخصوصا زمانی که تعداد دادهها زیاد باشند‪ .‬لذا تا جایی که میتوانید عناصر‬
‫‪ Write‬میرسیم؛ لذا در هر دفعه رسیدن به دستور ‪ Write‬یک رکورد‬
‫آرایهها را با حلقه مقداردهی کنید و مواردی را که با حلقه نمیتوان‬
‫عوض میشود و عناصر آرایههای ‪ Value‬و ‪ Square_Value‬در‬
‫مقداردهی کرد‪ ،‬به صورت عادی مقداردهی نمایید‪.‬‬
‫رکوردهای زیر هم چاپ میشوند‪ .‬اگر میخواستیم همهی عناصر در یک‬
‫رکورد چاپ شوند‪ ،‬میتوانستیم از فرمت "\" استفاده کنیم‪.‬‬ ‫همچنین به این نکته ی بسیار مهم توجه کنید که زمانی که تعداد دادهها زیاد‬
‫میشود‪ ،‬اصل بر آن است که دادهها از روی فایل خوانده شوند‪.‬‬
‫‪ ‬این مساله جزء مسائلی است که اگر آنرا با اطالعات فصول اول و دوم و‬
‫سوم حل میکردیم‪ ،‬روش حل و کدنویسی سادهتر میشد! شما سعی کنید‬ ‫‪ ‬در این مثال میتوانستیم اصال از آرایهی ‪ Square_Value‬استفاده نکنیم؛‬
‫این کار را انجام دهید‪.‬‬ ‫چراکه میدانیم در دستور ‪ Print‬یا ‪ Write‬میتوان عبارات را نیز چاپ کرد‬
‫(البته در فصل اول ذکر کردیم که اصول برنامه نویسی حکم میکند که‬
‫مثال ‪ )2‬میخواهیم برنامه ای بنویسیم که تعداد حداکثر ده عدد را از ورودی بگیرد و‬
‫همیشه عبارات درون متغیرها یا آرایهها ذخیره شوند و سپس محتوای آن‬
‫در خروجی تمام اعداد گرفته شده را چاپ کرده و بیشترین مقدار و کمترین مقدار‬
‫متغیرها یا آرایهها چاپ شوند)؛ اما حاال که از آن استفاده کردیم‪ ،‬باید حداقل‬
‫اعداد را نیز مشخص کند‪ .‬بنابراین برنامه اول تعداد دادههایی که کاربر میخواهد وارد‬
‫دارای ده عنصر باشد (و داشتن عناصر اضافی ایرادی را ایجاد نمیکند)‪.‬‬
‫کند را از ورودی میگیرد‪ .‬اگر تعداد دادهها کمتر یا مساوی ده بود‪ ،‬عملیات را انجام‬
‫میدهد و در غیر اینصورت خطای مناسبی چاپ خواهد شد‪.‬‬ ‫‪ ‬عناصر آرایههای تک بعدی (با هر تعداد عنصر) را به کمک یک حلقهی‬

‫‪Program Extremes‬‬ ‫صریح میتوان به راحتی چاپ کرد‪ .‬ضمن اینکه واضح است که تمام عناصر‬

‫‪39‬‬
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ ‫ محمدصادق عباسیان‬:‫تهیه و تنظیم‬

End Do Small Implicit None


!Write out List ! List of Parameters
Write (*, 110) Integer, Parameter :: Max_Size = 10 !Max Size of Data Set
110 Format ("The Values Are:") ! List of Variables
Out : Do J = 1, Nvals Integer, Dimension (Max_Size) :: Input !Input Values
If (J .EQ. Ilarge) Then Integer :: Ilarge !Largest Value
Write (*, "(1X, I6, 2X, A)") & Integer :: ISmall !Smallest Value
Input (J), "Largest" Integer :: J !Do Loop Index
Else If (J .EQ. Ismall) Then Integer :: Nvals !Number of Vals in Data Set
Write (*, "(1X, I6, 2X, A)") & Integer :: Temp !Temporary Vaiable
Input (J), "Smallest" ! Get Number of Values in Data Set
Else Write (*,*) "Enter Number of Values in Data Set:"
Write (*, "(1X, I6)") Input (J) Read (*,*) Nvals
End If ! Is the Number Less or Equal Than Max_Size
End Do Out Size : If (Nvals .LE. Max_Size) Then
Else Size !Get Input Values
!Nvals Greater Than Max_Size. Tell User In : Do J = 1, Nvals
!and Quit. Write (*, 100) "Enter Values", J
Write (*, 120) Nvals, Max_Size 100 Format (A, I3, ":")
120 Format (1X, "Too Many Input & Read (*,*) Input (J)
Values:", I6, ">", I2) End Do In
End If Size !Find the Largest Value
End Program Temp = Input (1)
Ilarge = 1
:‫نمونهی خروجی برای شش عدد به شکل زیر است‬ Large : Do J = 2, Nvals
If (Input (J) .GT. Temp) Then
Enter Number of Values in Data Set: Temp = Input (J)
6 Ilarge = J
Enter Values 1: End If
2 End Do Large
Enter Values 2: !Find the Smallest Value
4 Temp = Input (1)
Enter Values 3: Ismall = 1
6 Small : Do J = 2, Nvals
Enter Values 4: If (Input (J) .LT. Temp) Then
7 Temp = Input (J)
Enter Values 5: Ismall = J
5 End If

42
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها)‬

‫حلقهی دوم و سوم برای پیدا کردن بیشترین و کمترین مقدار به کار‬ ‫‪Enter Values 6:‬‬
‫‪3‬‬
‫میروند و مکانیزم مشابهی دارند‪ .‬مثال برای پیدا کردن بیشترین مقدار‪:‬‬ ‫‪The Values Are:‬‬
‫‪2 Smallest‬‬
‫‪4‬‬
‫ابتدا مقدار اولین عنصر آرایهی خوانده شده درون متغیر ‪ Temp‬و اندیس‬ ‫‪6‬‬
‫آن نیز (یعنی یک) در متغیر ‪ Ilarge‬ذخیره میشود‪ .‬سپس برای مقایسهی‬ ‫‪7 Largest‬‬
‫‪5‬‬
‫مقادیر عناصر آرایه با یکدیگر‪ ،‬برنامه وارد حلقه میشود‪ .‬چون مقدار اولیهی‬ ‫‪3‬‬

‫شمارندهی حلقه برابر دو میباشد‪ ،‬لذا با اولین بار ورود به حلقه‪ ،‬محتوای‬ ‫و نمونهی خروجی برای یازده عدد به شکل زیر است‪:‬‬
‫عنصر دوم آرایه با محتوای ‪ Temp‬مقایسه میشود‪ .‬چون محتوای عنصر اول‬ ‫‪Enter Number of Values in Data Set:‬‬
‫‪Too Many Input Values:‬‬ ‫‪11>10‬‬
‫در ‪ Temp‬قرار داده شده است‪ ،‬انگار محتوای عنصر دوم با محتوای عنصر‬
‫نکات‪:‬‬
‫اول مقایسه میشود‪ .‬این مقایسه به کمک یک بلوک ‪ If‬انجام میشود‪ .‬در‬
‫صورتی که محتوای عنصر دوم از محتوای ‪ Temp‬بیشتر باشد‪ ،‬محتوای‬ ‫‪ ‬این مثال یک نمونهی خوب از ترکیب حلقه‪ ،‬شرط‪ ،‬فرمتها و آرایههاست!‬
‫عنصر دوم درون ‪ Temp‬قرار داده میشود‪.‬‬ ‫مکانیزم عملکرد این برنامه بسیار جالب و خالقانه است! بهتر است یکبار با‬
‫هم روند برنامه را مرور کنیم‪.‬‬
‫برای بار دوم که برنامه وارد حلقه میشود‪ ،‬محتوای عنصر سوم با محتوای‬
‫‪ Temp‬مقایسه میشود که محتوای خود ‪ Temp‬بزرگترین مقدار بین‬ ‫بعد از خواندن تعداد اعداد از ورودی‪ ،‬توسط یک شرط تعداد اعداد بررسی‬
‫عنصر اول و دوم میباشد‪ .‬بنابراین اینبار بزرگترین مقدار بین عنصر اول و‬ ‫میشود‪ .‬در صورتی که تعداد اعداد کوچکتر یا مساوی ده باشد‪ ،‬پردازش‬
‫دوم و سوم درون ‪ Temp‬قرار میگیرد‪ .‬به همین ترتیب چون شمارندهی‬ ‫روی اعداد شروع شده و در غیر این صورت‪ ،‬با چاپ یک پیغام خطا برنامه‬
‫حلقه تا ‪ Nvals‬تغییر میکند‪ ،‬تمام عناصر آرایه با هم مقایسه میشوند!‬ ‫خاتمه مییابد‪.‬‬
‫نکته ی مهم اینجاست که به طور همزمان نیز با مقایسهی هر عنصر با عنصر‬ ‫اولین حلقه پس از وارد شدن به دستورات اجرایی شرط صرفا برای خواندن‬
‫قبلی‪ ،‬اندیس عنصر بزرگتر در متغیر ‪ Ilarge‬ذخیره میشود و ما هم در این‬ ‫دادهها میباشد‪ .‬فقط دقت کنید که تمام حلقههای برنامه با تعداد دادهها تنظیم‬
‫مثال با اندیس عنصری که بزرگترین مقدار را داراست کار میکنیم (تمام‬ ‫شدهاند؛ یعنی برای مقدار انتهایی شمارندهی حلقهها‪ ،‬متغیر ‪ Nvals‬در نظر‬
‫گرفته شده است‪.‬‬

‫‪41‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫استفاده کنیم‪ .‬ولی در اینجا آرایهی ‪ Input‬تعداد عناصرش را از متغیر‬ ‫تکنیک مساله همینجاست!)‪ .‬لذا در نهایت پس از خروج از حلقه‪ ،‬اندیس‬
‫‪ Max_Size‬میگیرد که این کار هم مانعی ندارد‪ .‬فقط به خاطر بسپارید که‬ ‫عنصرِ دارای بزرگترین مقدار در متغیر ‪ Ilarge‬ذخیره میشود‪.‬‬
‫در اینصورت متغیری که تعداد عناصر را مشخص میکند (مثل‬ ‫روال مشابه در پیدا کردن کوچکترین مقدار تکرار شده است که در نهایت‬
‫‪ Max_Size‬در اینجا) حتما باید به عنوان پارامتر اعالن شده باشد و در غیر‬ ‫پس از خروج از حلقهی سوم‪ ،‬اندیس عنصرِ دارای کوچکترین مقدار در‬
‫اینصورت خطاست‪.‬‬ ‫متغیر ‪ Ismall‬ذخیره میشود‪.‬‬
‫مثال ‪ )3‬در برنامهی زیر‪ ،‬یک آرایهی تکبعدی با تعداد ده عنصر‪ ،‬از یک تا ده‬ ‫در حلقهی آخر‪ ،‬به کمک یک شرط‪ ،‬تمام عناصر ماتریس چاپ میشوند؛‬
‫مقداردهی میشود و سپس ریشهی دوم و ریشهی سوم هر یک از عناصر محاسبه و به‬ ‫بدین ترتیب که شمارندهی حلقه روی تمام اندیسهای عناصرِ آرایه حرکت‬
‫کمک حلقهی ضمنی به شکل یک جدول در خروجی چاپ میشود‪.‬‬ ‫میکند و درون شرط‪ ،‬هرگاه شمارنده حلقه با متغیر ‪( Ilarge‬که اندیس‬
‫‪Program Square_and_Cube_Roots‬‬ ‫عنصر با بزرگترین مقدار است) برابر شد‪ ،‬محتوای عنصرِ با اندیس ‪Ilarge‬‬
‫‪Implicit None‬‬
‫‪! List of Parameters‬‬ ‫همراه با رشتهی "‪ "Largest‬چاپ میشود و هرگاه شمارندهی حلقه با‬
‫‪Integer, Parameter :: Max_Size = 10‬‬
‫‪! List of Variables‬‬ ‫متغیر ‪( Ismall‬که اندیس عنصر با کوچکترین مقدار است) برابر شد‪،‬‬
‫‪Integer :: J !Loop Index‬‬
‫‪Real , Dimension (Max_Size) :: Value !Array of Numbers‬‬ ‫محتوای عنصرِ با اندیس ‪ Ismall‬همراه با رشتهی "‪ "Smallest‬چاپ‬
‫‪Real , Dimension (Max_Size) :: Square_Root !Array of Square‬‬
‫‪!Roots‬‬ ‫میشود؛ در غیر این دو حالت نیز محتوای عناصر به تنهایی چاپ میشوند‪.‬‬
‫‪Real , Dimension (Max_Size) :: Cube_Root‬‬ ‫‪!Array of Cube‬‬
‫‪!Roots‬‬ ‫تکنیک حل این مساله (یعنی ذخیرهی اندیس یک سری از عناصر مورد نظر)‬
‫‪! Calculate the Square Root and Cube Roots‬‬
‫‪Do J = 1, Max_Size‬‬ ‫را حتما به خاطر داشته باشید‪.‬‬
‫)‪Value (J) = Real (J‬‬
‫))‪Square_Root (J) = Sqrt (Value (J‬‬ ‫‪ ‬بررسی کنید که اگر یک عدد تکراری (یا چند عدد تکراری) در اعداد‬
‫)‪Cube_Root (J) = Value (J) ** (1. / 3.‬‬
‫‪End Do‬‬ ‫ورودی وجود داشته باشد چه اتفاقی میافتد‪.‬‬
‫‪! Write out Each Number, Its Square Root and Its Cube Root‬‬
‫)‪Write (*, 100‬‬
‫& ‪100 Format (20X, "Table of Square and Cube Roots", //,‬‬
‫‪ ‬در حالی که میتوانستیم در اعالن آرایهی ‪ Input‬به سادگی از دستور اعالن‬
‫& ‪4X, "Number Square Root Cube Roots",‬‬
‫& ‪3X, "Number Square Root Cube Roots", /,‬‬ ‫‪Integer, Dimenion (10) :: Input‬‬

‫‪42‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها)‬

‫دستور ‪ Print‬یا ‪ Write‬این اتفاق میافتد‪ .‬بنابراین چون فقط یک دستور‬ ‫& ‪4X, "====== =========== ==========",‬‬
‫)"========== =========== ======" ‪3X,‬‬
‫چاپ داریم‪ ،‬اصال بحث هر بار رسیدن به دستور چاپ و عوض شدن رکورد‬ ‫& ‪Write (*, 110) (Value (J), Square_Root (J), Cube_Root (J),‬‬
‫)‪J = 1, Max_Size‬‬
‫مطرح نمیشود!‬ ‫))‪110 Format (2 (4X, F4.0, 7X, F6.4, 7X, F6.4‬‬
‫‪End Program‬‬
‫اما برای نوشتن حلقهی ضمنی‪ ،‬باید به نکات زیر توجه داشت‪:‬‬ ‫با اجرای کدها‪ ،‬خروجی به صورت زیر میباشد‪.‬‬
‫‪ .1‬در مقابل دستور چاپ‪ ،‬تمام مجموعهی حلقهی ضمنی‪ ،‬شامل‬ ‫‪Table of Square and Cube Roots‬‬

‫مواردی که باید چاپ شوند و شمارندهها‪ ،‬باید داخل یک پرانتز‬ ‫‪Number‬‬ ‫‪Square Root‬‬ ‫‪Cube Roots‬‬ ‫‪Number‬‬ ‫‪Square Root‬‬ ‫‪Cube Roots‬‬
‫======‬ ‫===========‬ ‫==========‬ ‫======‬ ‫===========‬ ‫==========‬
‫‪1.‬‬ ‫‪1.0000‬‬ ‫‪1.0000‬‬ ‫‪2.‬‬ ‫‪1.4142‬‬ ‫‪1.2599‬‬
‫قرار گیرد‪.‬‬ ‫‪3.‬‬ ‫‪1.7321‬‬ ‫‪1.4422‬‬ ‫‪4.‬‬ ‫‪2.0000‬‬ ‫‪1.5874‬‬
‫‪5.‬‬ ‫‪2.2361‬‬ ‫‪1.7100‬‬ ‫‪6.‬‬ ‫‪2.4495‬‬ ‫‪1.8171‬‬
‫‪7.‬‬ ‫‪2.6458‬‬ ‫‪1.9129‬‬ ‫‪8.‬‬ ‫‪2.8284‬‬ ‫‪2.0000‬‬
‫‪ .2‬در ابتدا مواردی که باید چاپ شوند آورده شده و سپس‬ ‫‪9.‬‬ ‫‪3.0000‬‬ ‫‪2.0801‬‬ ‫‪10.‬‬ ‫‪3.1623‬‬ ‫‪2.1544‬‬

‫شمارندهها آورده میشوند‪ .‬ضمنا هر کدام از موارد چاپ شونده و‬ ‫نکات‪:‬‬


‫هر کدام از شمارندهها با ویرگول از هم جدا میشوند‪.‬‬
‫‪ ‬به یاد دارید که گفته شد قاعدهی اصلی در ورودی و خروجی آن است که‬
‫‪ .3‬شمارندهی حلقههای ضمنی‪ ،‬همانند شمارندههای حلقههای‬ ‫هرگاه به دستورات ‪ Write ،Print‬یا ‪ Read‬برسیم‪ ،‬یک خط یا رکورد‬
‫صریح‪ ،‬شامل مقدار ابتدایی‪ ،‬مقدار انتهایی و گام میشود که آنها‬ ‫عوض میشود (مگر آنکه از فرمت "\"‪ ،‬دستور "‪ Advance = "No‬یا ‪...‬‬
‫هم با ویرگول از هم جدا میشوند‪.‬‬ ‫استفاده شود)‪ .‬اما در بعضی از موارد (خصوصا در بحث آرایهها) میخواهیم‬
‫‪ .4‬در صورتی که حلقههای ضمنیِ تو در تو داشته باشیم‪ ،‬مجموعهی‬ ‫که دادههای متفاوت در یک خط چاپ شوند‪ .‬لذا باید یک راه فرار از اصل‬
‫حلقهی تویی‪ ،‬خودش داخل یک پرانتز دیگر قرار میگیرد؛ مثال‬ ‫کلی ذکر شده پیدا کرد که آن راه فرار‪ ،‬استفاده از حلقهی ضمنی است (از‬
‫در دستور‬ ‫اینجا به بعد‪ ،‬توضیحات فقط روی خروجی داده میشوند ولی نکات راجع‬
‫)‪Write (*,*) ((I, J, J = 1, 3), I = 1, 2‬‬ ‫به ورودی هم صادق هستند)!‬
‫حلقه با شمارندهی ‪ J‬حلقهی تویی و حلقه با شمارندهی ‪ I‬حلقهی‬ ‫در حلقهی ضمنی‪ ،‬تعداد دلخواهی از دادهها چاپ میشوند‪ ،‬اما اینبار (بر‬
‫بیرونی میباشد و متغیرهای ‪ I‬و ‪ J‬در درون حلقهی تویی چاپ‬ ‫خالف زمانی که از حلقههای صریح استفاده میکنیم) فقط به کمک یک‬

‫‪43‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪ ‬در این مثال برای خروجی از دو دستور چاپ کمک گرفته شده است‪ .‬دستور‬ ‫میشوند‪ .‬قواعد چرخش در حلقههای تو در تو‪ ،‬دقیقا مشابه‬
‫چاپ اول فقط به منظور چاپ عنوان جدول و عنوان ستونهای جدول به کار‬ ‫قواعدی است که در فصل دوم ذکر شد‪.‬‬
‫رفته است‪ .‬اما در دستور چاپ دوم‪ ،‬عناصر آرایههای ‪،Value‬‬ ‫البته توجه کنید که خروجی حلقههای ضمنی آنقدرها هم ساده نیست! مثال‬
‫‪ Square_Root‬و ‪ Cube_Root‬به کمک یک حلقهی ضمنی چاپ‬ ‫خروجی دستورات‬
‫میشوند‪ .‬دقت کنید که در چاپ از فرمت استفاده شده و خود فرمت دارای‬
‫)‪Write (*, 100) ((I, J, J = 1, 3), I = 1, 2‬‬
‫یک گروه پرانتز شامل ضریب دو میباشد‪ .‬همچنین درون پرانتز نیز سه فرمتِ‬ ‫)‪100 Format (1X, I5, 1X, I5‬‬

‫اعداد حقیقی به کار گرفته شده که با در نظر گرفتن ضریب دو پشت پرانتز‪،‬‬ ‫به صورت زیر است‪:‬‬
‫در مجموع شش فرمت اعداد حقیقی داریم؛ ولی تعداد سی عدد در خروجی‬ ‫‪˽˽˽˽˽1˽˽˽˽1‬‬
‫‪˽˽˽˽˽1˽˽˽˽2‬‬
‫باید چاپ شود (هر کدام از آرایههای ‪ Square_Root ،Value‬و‬ ‫‪˽˽˽˽˽1˽˽˽˽3‬‬
‫‪˽˽˽˽˽2˽˽˽˽1‬‬
‫‪ Cube_Root‬دارای ده عنصر هستند)‪ .‬پس طبق توضیح نکتهی قبلی‪ ،‬هر‬ ‫‪˽˽˽˽˽2˽˽˽˽2‬‬
‫‪˽˽˽˽˽2˽˽˽˽3‬‬
‫بار با چاپ شش عدد‪ ،‬یک رکورد عوض میشود‪.‬‬
‫در ابتدا خروجی کمی عجیب به نظر میرسد؛ زیرا این سوال پیش میآید که‬
‫‪ ‬در فصل دوم مثالی آورده شد که خروجیاش به شکل یک جدول بود؛ ولی‬
‫چرا با اینکه از حلقهی ضمنی استفاده کردیم‪ ،‬پنج بار خط عوض شده است‪.‬‬
‫چون تا فصل دوم هنوز با فرمتها آشنا نشده بودیم‪ ،‬برای درست کردن‬
‫ولی باید توجه کرد که در این مثال از فرمت استفاده شده است و حالتی‬
‫شکل جدول مجبور بودیم از تعدادی فاصله درون رشتهها استفاده کنیم‪ .‬در‬
‫اتفاق افتاده که تعداد فرمتها‪ ،‬از تعداد متغیرهای چاپ شونده کمتر است‬
‫این مثال کامال مشخص است که فارغ از دردسرهایی که در آنجا داشتیم‪ ،‬به‬
‫(دوازده متغیر و دو فرمت داریم)؛ لذا طبق قواعد مفصلی که در فصل سوم‬
‫کمک فرمتها‪ ،‬به زیبایی شکل جدول را در خروجی درست کردیم‪ .‬شما‬
‫مطرح کردیم‪ ،‬هر بار که فرمتها به اتمام میرسند‪ ،‬یک رکورد عوض‬
‫هم باید قادر باشید جدولهایی مشابه این جدول را تهیه نمایید (حتما از این‬
‫میشود! بنابراین عوض شدن خطها ارتباطی به حلقههای ضمنی ندارد‪.‬‬
‫مثال‪ ،‬به عنوان مثال نمونهی فصل سوم هم استفاده نمایید‪.).‬‬
‫مواظب تلهها باشید!‬
‫مثال ‪ )4‬برنامهی زیر‪ ،‬یک آرایه را در خروجی بدین صورت چاپ میکند که یک‬
‫بار کل آرایه و دو بار زیرآرایههایی از آن را چاپ میکند‪.‬‬

‫‪44‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها)‬

‫شود‪ .‬ضمنا در صورتی که گام مشخص نشود‪ ،‬به صورت‬ ‫‪Program Array_IO‬‬
‫‪Implicit None‬‬
‫پیشفرض یک می باشد‪ .‬جدا کردن هر کدام از این سه مقدار به‬ ‫‪! List of Variables‬‬
‫)‪Real , Dimension (5) :: A = (/1., 2., 3., 20., 10./‬‬
‫کمک عالمت "‪ ":‬انجام میپذیرد‪ .‬به اعالنها و مثالهای زیر دقت‬ ‫)‪Integer, Dimension (4) :: Vec = (/4, 3, 4, 5/‬‬
‫‪! Output Entite Array‬‬
‫کنید (عناصری که انتخاب میشوند‪ ،‬رنگی شدهاند)‪.‬‬ ‫‪Write (*, 100) A‬‬
‫)‪100 Format (2X, 5F8.3‬‬
‫‪Integer, Dimension (6) :: A‬‬ ‫‪! Output Array Section Selected by a Triplet‬‬
‫‪Integer, Dimension (3, 3) :: B‬‬ ‫)‪Write (*, 100) A (2 :: 2‬‬
‫‪Integer :: C = 2, D = 5, E = 2‬‬ ‫‪! Output Array Section Selected by a Vector Subscript‬‬
‫)‪Integer, Dimension (3) :: F = (/2, 3, 5‬‬ ‫)‪Write (*, 100) A (Vec‬‬
‫)‪a) A (2 : 5‬‬ ‫‪End Program‬‬

‫خروجی این دستورات به صورت زیر است‪:‬‬


‫)‪b) A (2 : 2‬‬
‫‪1.000‬‬ ‫‪2.000‬‬ ‫‪3.000‬‬ ‫‪20.000‬‬ ‫‪10.000‬‬
‫‪2.000‬‬ ‫‪20.000‬‬
‫)‪c) A (2 : 5 : 2‬‬ ‫‪20.000‬‬ ‫‪3.000‬‬ ‫‪20.000‬‬ ‫‪10.000‬‬

‫نکات‪:‬‬
‫)‪d) A (2 : 5 : 5‬‬
‫‪ ‬همانطور که قبال گفته شد‪ ،‬در دستور چاپ اول‪ ،‬کل عناصر آرایهی ‪ A‬در‬
‫)‪e) B (1 : 2, 2 : 3‬‬ ‫یک خط چاپ میشوند‪.‬‬

‫اما در هر کدام از دستورات چاپ دوم و سوم‪ ،‬یک زیرآرایه از ماتریس ‪A‬‬
‫چاپ میشود‪ .‬در بحث زیرآرایهها به این نکات توجه کنید‪:‬‬
‫)‪f) B (1, 2 : 3‬‬
‫‪ .1‬در هر کدام از ابعاد یک آرایه‪ ،‬میتوان به جای اینکه تمام عناصر‬
‫آن بعد را انتخاب کرد‪ ،‬فقط تعدادی از عناصر را انتخاب نمود‪.‬‬
‫برای اینکار کافی است که در هر بعد‪ ،‬عنصر ابتدایی‪ ،‬عنصر‬
‫)‪g) B (1 : 3 : 2, 2 : 3‬‬
‫انتهایی و گام حرکت از عنصر ابتدایی به عنصر انتهایی مشخص‬

‫‪45‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪ .3‬به جای هر یک از مقادیر عنصر ابتدایی‪ ،‬عنصر انتهایی و گام‪،‬‬


‫متغیر نیز میتواند قرار بگیرد‪ .‬به مثالهای زیر دقت کنید‪.‬‬
‫)‪n) A (C : D : E‬‬ ‫)‪h) B (1 : 3 : 2, 1 : 3 : 2‬‬

‫)‪o) A (: : E‬‬

‫)‪i) B (1 : 3 : 3, 1 : 3 : 2‬‬
‫‪ .4‬به کمک یک آرایهی دیگر نیز میتوان یک زیرآرایه را مشخص‬
‫کرد‪ .‬به مثال زیر دقت کنید‪.‬‬
‫)‪p) A (F‬‬
‫‪ .2‬در صورتی که برای عنصر ابتدایی یا‪/‬و عنصر انتهایی عددی را در‬
‫یعنی مقادیر عناصر آرایهی ‪ F‬به عنوان اندیس عناصر آرایهی ‪A‬‬ ‫نظر نگیریم و فقط از عالمت "‪ ":‬استفاده کنیم‪ ،‬ابتدا یا‪/‬و انتهای‬
‫در نظر گرفته میشوند!‬ ‫زیرآرایه‪ ،‬به اول یا‪/‬و آخر خود آرایه محدود میشود‪ .‬به مثالهای‬

‫در صورتی که به چهار نکتهی فوق تسلط کامل پیدا کنید‪ ،‬دست شما در‬ ‫زیر دقت کنید‪.‬‬

‫انتخاب عناصر آرایهها بسیار باز خواهد بود‪.‬‬ ‫)‪j) A (2 :‬‬

‫مثال ‪ )5‬برنامهی زیر‪ ،‬تعداد نامعلومی عدد را از روی یک فایل میخواند‪ .‬در صورتی‬ ‫)‪k) A (: 5‬‬

‫که تعداد عددهای خوانده شده کوچکتر یا مساوی ده باشد آنها را از کوچک به‬
‫)‪l) A (2 : : 2‬‬
‫بزرگ مرتب مینماید و عددهای مرتب شده را در خروجی چاپ مینماید و در‬
‫صورتی که تعداد عددهای خوانده شده بیشتر از ده باشد‪ ،‬پیغام خطای مناسبی چاپ‬ ‫)‪m) A (: : 3‬‬
‫شده و برنامه به اتمام میرسد‪.‬‬
‫‪Program Sort‬‬
‫‪Implicit None‬‬
‫‪! List of Parameters‬‬
‫‪46‬‬
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ )‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها‬

End do Integer, Parameter :: Max_Size = 10


!Was the Array Size Exceed? If So, Tell User ! List of Variables
!and Quit Real , Dimension (Max_Size) :: A !Data Array to Sort
TooBig : If (Exceed) Then Logical :: Exceed = .False. !Logical Indicating That
Write (*, 1010) Nvals, Max_Size !Array Limits are Exceeded
1010 Format ("Maximum Array Size & Character (Len = 20) :: FileName !Input Data File Name
Exceed:",I6, ">", I2) Integer :: I !Loop Index
Else TooBig Integer :: Iptr !Pointer to Smallest Value
!Limit Not Exceed, So Sort Data Integer :: J !Loop Index
Outer : Do I = 1, Nvals - 1 Integer :: Nvals = 0 !Number of Data Values to Sort
!Find the Maximum Integer :: Status !I/O Status
!Values in A (I) Real :: Temp !Temporary Variable for Swapping
!Through A (Nvals) ! Get the Name of the File Containing the Input Data
Iptr = I Write (*, 1000)
Inner : Do J = I + 1, Nvals 1000 Format (1X, "Enter the File Name With the Data to be &
If (A (J) < A (Iptr)) Then Sorted:")
Iptr = J Read (*, "(A20)") FileName
End If ! Open Input Data File. Status is OLD Because the Input Data
End Do Inner ! Must Already Exist.
!Iptr Now Pointer to the Minimum Open (Unit = 9, File = FileName, Status = "OLD", Action = &
!Value So Swap A (Iptr) With A (I) "Read", Iostat = Status)
!If I /= Iptr ! Was the Open Successful?
Swap : If (I /= Iptr) Then FileOpen : If (Status == 0) Then !Successful
Temp = A (I) !The File Was Opened Successfully, So Read the
A (I) = A (Iptr) !Data to Sort from It, Sort the Data and Write
A (Iptr) = Temp !out Result.
End If Swap !First Read in Data
End Do Outer Do
!Write out the Sorted Data Read (9,*, Iostat = Status) Temp !Get Value
Write (*, "(A)") "The Sorted & If (Status /= 0) Exit !Exit on End of Data
Input Data Values Are:" Nvals = Nvals + 1 !Bump Count
Write (*, "(4X, F10.4)") (A (I), & Size : If (Nvals <= Max_Size) Then !Too
I = 1, Nvals) !Many
End If TooBig !Values
Else FileOpen A (Nvals) = Temp
!Fileopen Failed. Tell User Else
Write (*, 1050) Status Exceed = .True.
1050 Format (1X, "File Open Failed -- & End If Size

47
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫باشد‪ ،‬خروجی به صورت زیر خواهد بود‪:‬‬ ‫)‪Status =", I6‬‬


‫‪End If FileOpen‬‬
‫‪Enter the File Name With the Data to be Sorted:‬‬ ‫‪End Program‬‬
‫‪Data.txt‬‬
‫‪Maximum Array Size Exceed:‬‬ ‫‪11>10‬‬
‫فرض کنید که اعداد درون فایلی به نام ‪ Data.txt‬قرار داشته باشند‪ .‬در صورتی که‬
‫اعداد درون فایل به صورت‬
‫نکات‪:‬‬
‫‪0‬‬
‫‪ ‬در بسیاری از مسائل‪ ،‬نیاز به آن داریم که دادههایمان را از کوچک به بزرگ‬ ‫‪1.2‬‬
‫‪-3‬‬
‫یا از بزرگ به کوچک مرتب کنیم‪ .‬برای این کار الگوریتمهای متفاوتی‬ ‫‪1369‬‬
‫‪-5‬‬
‫طراحی شدهاند‪ .‬الگوریتم به کار گرفته شده در این مساله‪Selection ،‬‬
‫باشند‪ ،‬خروجی به صورت زیر خواهد بود‪:‬‬
‫‪ Sort‬نام دارد که روش کار آن برای مرتب کردن فهرستی از دادهها از‬
‫‪Enter the File Name With the Data to be Sorted:‬‬
‫کوچکترین عدد به بزرگترین عدد به این شرح است‪:‬‬ ‫‪Data.txt‬‬
‫‪The Sorted Input Data Values Are:‬‬
‫ابتدا باید بدانیم که به تعداد یکی کمتر از تعداد اعداد ورودی‪ ،‬عمل جستجو‬ ‫‪-5.0000‬‬
‫‪-3.0000‬‬
‫در فهرست اعداد انجام میشود (مثال اگر ده عدد وجود داشته باشد‪ ،‬برای‬ ‫‪0.0000‬‬
‫‪1.2000‬‬
‫مرتب کردن اعداد‪ ،‬نه بار بین اعداد عمل جستجو انجام میشود)‪ .‬در اولین‬ ‫‪1369.0000‬‬
‫دفعه‪ ،‬جستجو بین اولین تا آخرین اعداد درون فهرستِ اعداد انجام میشود و‬ ‫و در صورتی که فایل ورودی به صورت‬
‫کوچکترین عدد درون فهرست به مکان اول فهرست منتقل شده و عدد‬
‫‪0‬‬
‫موجود در مکان اول‪ ،‬به مکان آن عدد منتقل میشود‪ .‬در دفعهی دوم‪،‬‬ ‫‪1.2‬‬
‫‪-3‬‬
‫جستجو بین اعداد دوم تا آخر درون فهرست انجام میشود و کوچکترین‬ ‫‪1369‬‬
‫‪-5‬‬
‫عدد درون این فهرست به مکان دوم منتقل شده و عدد موجود در مکان دوم‪،‬‬
‫‪23‬‬
‫به مکان آن عدد منتقل میشود‪ .‬در دفعهی سوم بین اعداد سوم تا آخر لیست‬ ‫‪6.7‬‬
‫‪-0.02‬‬
‫جستجو انجام میشود و کوچکترین عدد درون این لیست به مکان سوم‬ ‫‪12‬‬
‫‪2010‬‬
‫منتقل شده و عدد موجود در مکان سوم‪ ،‬به مکان آن عدد منتقل میشود‪ .‬این‬ ‫‪19‬‬

‫‪48‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها)‬

‫‪ ‬از مثال برای خواندن دادهها از روی فایل‪ ،‬خواندن دادهها با تعداد نامعلوم‪،‬‬ ‫روال تا آنجا ادامه مییابد که عدد یکی مانده به آخر و آخر لیست با هم‬
‫حلقههای تو در تو و ترکیب حلقه و شرط استفاده کنید‪.‬‬ ‫مقایسه میشوند و عدد کوچکتر در مکان یکی مانده به آخر قرار میگیرد‪.‬‬
‫لذا در این صورت تمام اعداد با هم مقایسه شده و مرتب میشوند‪ .‬به مثال‬
‫مثال ‪ )6‬برنامهی سادهی زیر‪ ،‬تنها به منظور کار با آرایههای دو بعدی که به آنها‬
‫زیر برای مرتب کردن تعدادی عدد به این روش توجه کنید‪:‬‬
‫ماتریس هم گفته میشود در نظر گرفته شده است‪.‬‬
‫‪12‬‬ ‫‪3‬‬ ‫‪3‬‬ ‫‪3‬‬ ‫‪3‬‬
‫در اینجا تعدادی عدد درون یک فایل ورودی ذخیره شدهاند‪ .‬نمونهی فایل به شرح‬
‫زیر است (اعداد درون فایل مربوط به طول و عرض جغرافیایی تعدادی از نقاط میباشند‬ ‫‪3‬‬ ‫‪12‬‬ ‫‪4‬‬ ‫‪4‬‬ ‫‪4‬‬
‫و در این مثال کاربرد دادهها اهمیتی ندارد)‪:‬‬ ‫‪6‬‬ ‫‪6‬‬ ‫‪6‬‬ ‫‪6‬‬ ‫‪6‬‬
‫‪10.0‬‬
‫‪40.0‬‬ ‫‪4‬‬ ‫‪4‬‬ ‫‪12‬‬ ‫‪9‬‬ ‫‪9‬‬
‫‪70.0‬‬
‫‪20.0‬‬ ‫‪9‬‬ ‫‪9‬‬ ‫‪9‬‬ ‫‪12‬‬ ‫‪12‬‬
‫‪50.0‬‬
‫‪80.0‬‬
‫‪30.0‬‬ ‫اعداد‬ ‫مرحلهی ‪1‬‬ ‫مرحلهی ‪2‬‬ ‫مرحلهی ‪3‬‬ ‫مرحلهی ‪4‬‬
‫‪60.0‬‬
‫‪90.0‬‬ ‫برای مرتب کردن اعداد از بزرگ به کوچک نیز روال مشابه مورد استفاده‬
‫برنامه‪ ،‬اعداد را به کمک یک ماتریس از ورودی خوانده و تمام اعداد را با یک عدد‬ ‫قرار میگیرد‪.‬‬
‫ثابت به عنوان ضریب اصالح جمع کرده و در نهایت اعداد اصالح شده را چاپ‬ ‫این الگوریتم‪ ،‬آسانترین الگوریتم مرتبسازی تعدادی عدد است؛ ولی‬
‫مینماید‪.‬‬ ‫کامال واضح است که بسیار ابتدایی به نظر رسیده و ناکارآمد میباشد‪ .‬البته‬
‫‪Program C1002‬‬ ‫استفاده از این الگوریتم برای مرتبسازی اعداد بالمانع است‪ .‬به هر حال‬
‫‪! Variables used‬‬
‫‪! Height: used to hold the heights above sea level‬‬ ‫توصیه میشود هرگز برای مرتبکردن تعداد بیش از هزار عدد‪ ،‬از این‬
‫‪! Long: used to represent the longitude‬‬
‫‪! Lat: used to represent the latitude‬‬ ‫الگوریتم استفاده نشود‪.‬‬
‫‪! Both restricted to integer values.‬‬
‫‪! Correct: holds the correction factor‬‬ ‫‪ ‬کدها را با الگوریتم ذکر شده بررسی کنید‪.‬‬
‫‪Implicit None‬‬

‫‪49‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪ .1‬تفاوتهایی که برای حالتهای ‪ a‬و ‪ b‬در آرایههای تکبعدی‬ ‫‪Integer, Parameter :: Size = 3‬‬
‫‪Integer :: Lat, Long‬‬
‫گفته شد‪ ،‬اینجا هم صادق هستند‪.‬‬ ‫‪Real, Dimension (1 : Size, 1 : Size) :: Height‬‬
‫‪Real, Parameter :: Correct = 10.0‬‬
‫)"‪Open (1, File = "Data.txt‬‬
‫‪ .2‬به صورت پیشفرض‪ ،‬ماتریس به صورت ستونی مقداردهی‬ ‫‪Do Lat = 1, Size‬‬
‫میشود (این یک اصل کلی است؛ یعنی در خواندن و چاپ‬ ‫‪Do Long = 1, Size‬‬
‫)‪Read (1, *) Height (Lat, Long‬‬
‫پیشفرض به صورت ستونی است‪ .).‬پس در مقداردهیهای باال‪،‬‬ ‫‪End Do‬‬
‫‪End Do‬‬
‫مقدار عناصر ماتریس به شکل زیر درمیآید‪:‬‬ ‫‪Do Lat = 1, Size‬‬
‫‪Do Long = 1, Size‬‬
‫‪Mat (1, 1) = 1; Mat (2, 1) = 2; Mat (3, 1) = 3‬‬ ‫‪Height (Lat, Long) = Height (Lat, Long) + Correct‬‬
‫‪End Do‬‬
‫‪Mat (1, 2) = 4; … ; Mat (3, 3) = 9‬‬ ‫‪End Do‬‬
‫"‪Print*, "Corrected data is‬‬
‫اما در اینجا به استفاده از تابع ذاتی ‪ Reshape‬که حالت کلی دو مورد فوق‬ ‫‪Do Lat = 1, Size‬‬
‫میباشد میپردازیم‪ .‬شکل کلی دستور ‪ Reshape‬به صورت‬ ‫‪Do Long = 1, Size‬‬
‫)‪Print*, Height (Lat, Long‬‬
‫‪End Do‬‬
‫)]‪Result = Reshape (source, shape [, pad] [, order‬‬ ‫‪End Do‬‬
‫‪End Program C1002‬‬
‫میباشد که در آن‪:‬‬
‫نکات‪:‬‬
‫‪ :Source‬باید یک آرایه باشد که به عناصر آرایهی ‪ Result‬مقداردهی‬
‫میکند‪ .‬در صورتی که از ‪ Pad‬استفاده نشود‪ ،‬باید تعداد تمام عناصر‬ ‫‪ ‬برای مقداردهی به ماتریسها‪ ،‬همانند آرایههای تکبعدی میتوان مقداردهی‬
‫‪ Source‬بزرگتر یا مساوی تعداد تمام عناصر ‪ Result‬باشد‪.‬‬ ‫کرد‪ .‬یعنی با توجه به اعالن‬
‫‪Integer, Dimension (3, 3) :: Mat‬‬
‫‪ :Shape‬یک آرایهی تکبعدی و از نوع صحیح‪ ،‬با حداکثر هفت عنصر‬
‫میتوان به صورتهای زیر مقداردهی کرد‪:‬‬
‫میباشد (چراکه حداکثر تعداد ابعاد ‪ Result‬میتواند هفت باشد)‪ .‬این آرایه‬
‫& = ‪a) Integer, Dimension (3, 3) :: Mat‬‬
‫تعیینکنندهی شکل (‪ )Shape‬آرایهی ‪ Result‬میباشد و تمام عناصر آن‬ ‫)‪(/1, 2, 3, 4, 5, 6, 7, 8, 9/‬‬
‫باید مثبت باشند‪.‬‬ ‫‪b) Data Mat /1, 2, 3, 4, 5, 6, 7, 8, 9/‬‬

‫منتها اگر از این روشها استفاده میکنید‪ ،‬فراموش نکنید‪:‬‬


‫‪52‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها)‬

‫در اینجا هم بهتر است تا جایی که امکان دارد برای مقدار دهی از حلقه‬ ‫‪ :Pad‬یک آرایه همنوع با ‪ Source‬میباشد‪ .‬در صورتی که تعداد کل‬
‫استفاده شود‪ .‬مثال دستورات زیر‪ ،‬دقیقا مانند مقداردهیهایی که در نکتهی‬ ‫عناصر آرایهی ‪ Result‬بیشتر از تعداد کل عناصر ‪ Source‬باشد‪ ،‬از ‪Pad‬‬
‫اول آورده شد عمل میکنند (بررسی کنید)‪.‬‬ ‫برای مقداردهی به عناصر مقداردهی نشده استفاده میشود‪.‬‬
‫‪K = 0‬‬ ‫‪ :Order‬یک آرایه از نوع صحیح و دارای شکل (‪ )Shape‬مشابه ‪Shape‬‬
‫‪Do I = 1,‬‬ ‫‪3‬‬
‫= ‪Do J‬‬ ‫‪1, 3‬‬ ‫( ‪1,‬‬ ‫(یعنی مورد دوم) میباشد‪ .‬عناصر این آرایه باید جایگشتی از‬
‫= ‪K‬‬ ‫‪K + 1‬‬
‫‪Mat‬‬ ‫‪(J, I) = K‬‬ ‫‪ )2, 3, …, n‬باشند که در آن ‪ n‬همان اندازه(‪)Size‬ی ‪( Shape‬یعنی‬
‫‪End Do‬‬
‫‪End Do‬‬ ‫( ‪1,‬‬ ‫مورد دوم) میباشد‪ .‬در صورتی که ‪ Order‬حذف شود‪ ،‬پیشفرض‬
‫‪ ‬نحوهی استفاده از حلقههای صریح و ضمنی در ورودی و خروجی ماتریسها‬ ‫‪ )2, 3, …, n‬است‪.‬‬
‫بسیار مهم است‪ .‬با توجه به اعالن و مقداردهی اولیه‪ ،‬به خروجی دستورات‬ ‫به مثالهای زیر که عینا از ‪ Help‬آورده شدهاند دقت کنید‪:‬‬
‫چاپ زیر دقت کنید‪.‬‬
‫‪Reshape ((/3, 4, 5, 6, 7, 8/), (/2, 3/)) has the value‬‬
‫‪Integer, Dimension (3, 3) :: Mat‬‬ ‫] ‪[ 3 5 7‬‬
‫‪Data Mat /1, 2, 3, 4, 5, 6, 7, 8, 9/‬‬ ‫‪[ 4 6 8 ].‬‬
‫‪a) Print*, Mat‬‬ ‫))‪Reshape ((/3, 4, 5, 6, 7, 8/), (/2, 4/), (/1, 1/), (/2, 1/‬‬
‫‪Output:‬‬ ‫‪has the value‬‬
‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪4‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪7‬‬ ‫‪8‬‬ ‫‪9‬‬ ‫] ‪[ 3 4 5 6‬‬
‫‪b) Do I = 1, 3‬‬ ‫‪[ 7 8 1 1 ].‬‬
‫‪Do J = 1, 3‬‬
‫)‪Print*, Mat (I, J‬‬ ‫‪The following shows another example:‬‬
‫‪End Do‬‬ ‫)‪Integer AR1 (2, 5‬‬
‫‪End Do‬‬ ‫& ‪AR1 = Reshape ((/1, 2, 3, 4, 5, 6/), (/2, 5/), (/0, 0/),‬‬
‫‪Output:‬‬ ‫))‪(/2,1/‬‬
‫‪1‬‬ ‫‪! returns‬‬ ‫‪1 2 3 4 5‬‬
‫‪4‬‬ ‫!‬ ‫‪6 0 0 0 0‬‬
‫‪7‬‬
‫)‪Integer AR1 (2, 5‬‬
‫‪2‬‬
‫& )‪AR1 = Reshape ((/1, 2, 3, 4, 5, 6/), (/2, 5/), (/1, 2, 3/‬‬
‫‪5‬‬
‫))‪, (/2, 1/‬‬
‫‪8‬‬
‫‪! returns‬‬ ‫‪1 2 3 4 5‬‬
‫‪3‬‬
‫!‬ ‫‪6 1 2 3 1‬‬
‫‪6‬‬

‫‪51‬‬
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ ‫ محمدصادق عباسیان‬:‫تهیه و تنظیم‬

f) Do I = 1, 3 9
Print*, (Mat (J, I), J = 1, 3) c) Do I = 1, 3
End Do Do J = 1, 3
Output: Print*, Mat (J, I)
1 2 3 End Do
4 5 6 End Do
7 8 9 Output:
g) Do J = 1, 3 1
Print*, (Mat (I, J), I = 1, 3) 2
End Do 3
Output: 4
1 4 7 5
2 5 8 6
3 6 9 7
h) Print*, ((Mat (I, J), I = 1, 3), J = 1, 3) 8
Output: 9
1 2 3 4 5 6 7 8 9 d) Do J = 1, 3
i) Print*, ((Mat (I, J), J = 1, 3), I = 1, 3) Do I = 1, 3
Output: Print*, Mat (I, J)
1 4 7 2 5 8 3 6 9 End Do
j) Do I = 1, 3 End Do
Do J = 1, 3 Output:
Print "(I2\)", Mat (I, J) 1
End Do 2
End do 3
Output: 4
˽1˽4˽2˽7˽5˽8˽3˽6˽9 5
k) Print "(I2)", ((Mat (I, J), I = 1, 3), J = 1, 3) 6
Output: 7
˽1 8
˽2 9
˽3 e) Do I = 1, 3
˽4 Print*, (Mat (I, J), J = 1, 3)
˽5 End Do
˽6 Output:
˽7 1 4 7
˽8 2 5 8
˽9 3 6 9

52
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ )‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها‬

4 3 .‫در صورت استفاده از حلقهها در خواندن هم باید بسیار دقت کنید‬


Enter Temperatures at the First Location:
Then Those at the Second Location and So on...:
62.0 68.7 65.5 ‫ تعدادی عدد را به عنوان دما از ورودی میگیرد و آنها را به‬،‫) برنامهی زیر‬7 ‫مثال‬
64.5 68.9 68.8
66.3 69.4 70.4 ‫صورت یک جدول چاپ مینماید؛ بدین صورت که چند ایستگاه مختلف اندازهگیری‬
65.8 69.1 68.5
Location
‫ دماها در چند زمان مختلف اندازهگیری شدهاند؛ ولی تعداد‬،‫داریم که در هر ایستگاه‬
Time 1 2 3 ‫ایستگاهها و تعداد دفعات اندازهگیری در هر ایستگاه از قبل مشخص نیست؛ لذا کاربر‬
1 62.0 68.7 65.5
2 64.5 68.9 68.8 .‫تعداد آنها را قبل از وارد کردن اعداد دماها وارد میکند‬
3 66.3 69.4 70.4
4 65.8 69.1 68.5 Program Table_of_Temperatures
Implicit None
:‫نکات‬ Real, Allocatable, Dimension (:,:) :: Temperature
Integer :: NumTimes, NumLocs, AllocateStatus ,Time, Location
‫ مجبور هستیم‬،‫ در صورتی که تعداد عناصر یک آرایه از قبل مشخص نباشد‬ Print*, "Enter Number of Times and Locations Temperatures &
Recorded:"
‫ شکل کلی‬.‫) اعالن کنیم‬Allocatable( ‫که آرایه را از نوع تخصیصپذیر‬ Read*, NumTimes, NumLocs
Allocate (Temperature (NumTimes, NumLocs), &
:‫این اعالن به صورت زیر است‬ Stat = AllocateStatus)
If (AllocateStatus .NE. 0) Stop
Type, Allocatable, Dimension (: [, :, …]) :: Array1 [, Array2, …] Print*, "Enter Temperatures at the First Location:"
Print*, "Then Those at the Second Location and So on...:"
‫ را میتوان با‬Dimension( ) ‫ و‬Allocatable ‫البته جای کلیدواژههای‬ Read*, ((Temperature (Time, Location), &
Location = 1, NumLocs), Time = 1, NumTimes)
.‫هم عوض کرد‬ Print 10, (Location, Location = 1, NumLocs)
10 Format (1X, T13, "Location", /, 1X, "Time", 10I6)
‫ باید عمل تخصیص به آرایه انجام‬،‫ در طول برنامه و قبل از استفاده از آرایه‬ Do Time = 1, NumTimes
Print "(1X, I3, 2X, 10F6.1)", Time, &
‫ همچنین به‬.‫ انجام میپذیرد‬Allocate ‫ این کار به کمک دستور‬.‫شود‬ (Temperature (Time, Location), Location = 1, NumLocs)
End Do
‫ میتوان از موفق بودن‬،Allocate ‫ در درون دستور‬Stat ‫کمک عبارت‬ Deallocate (Temperature)
End
‫تخصیص به آرایه اطمینان حاصل کرد؛ بدین صورت که اگر عمل تخصیص‬
:‫نمونهی اجرای برنامه به شرح زیر است‬
Enter Number of Times and Locations Temperatures Recorded:

53
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫غیراینصورت باید از یک آرایهی تکبعدی استفاده کنید که تعداد عناصر آن دقیقا با‬ ‫با موفقیت انجام شود‪ ،‬به متغیر جلوی عبارت ‪ Stat‬مقدار صفر داده میشود و‬
‫تعداد ابعاد ‪ Array‬برابر میباشد (نه بیشتر و نه کمتر)‪.‬‬ ‫در غیر این صورت‪ ،‬مقدار دیگری داده میشود‪.‬‬
‫‪Consider the following:‬‬ ‫‪ ‬بهتر است پس از عدم نیاز به آرایهی تخصیصپذیر‪ ،‬فضای اختصاص یافته به‬
‫)‪Real ARRAY_A (1:3, 5:8‬‬
‫)‪Real ARRAY_B (2:8, -3:20‬‬ ‫آن‪ ،‬به کمک دستور ‪ Deallocate‬آزاد شود‪.‬‬
‫‪Lbound (ARRAY_A) is (1, 5). Lbound (ARRAY_A, Dim = 2) is 5.‬‬
‫‪Lbound (ARRAY_B) is (2, -3).‬‬
‫در اینجا به بررسی برخی از توابع ذاتی آرایهها میپردازیم‪ .‬در هر بخش‪ ،‬پس از‬
‫‪The following shows another example:‬‬ ‫توضیحات الزم‪ ،‬مثالهایی از ‪ Help‬آورده شدهاند‪.‬‬
‫)‪Real ARRAY (2:6, 8:14‬‬
‫‪Integer LB (2), LBD‬‬
‫)‪LB = Lbound (ARRAY‬‬ ‫]‪! returns [2 8‬‬ ‫)]‪1) result = Lbound (array [, dim‬‬
‫‪LBD = Lbound (ARRAY, Dim = 2) ! returns 8‬‬
‫‪ :Array‬باید یک آرایه باشد و نمیتواند آرایهی تخصیصپذیری باشد که هنوز‬
‫)]‪2) result = Ubound (array [, dim‬‬
‫عمل تخصیص به آن انجام نشده است‪.‬‬
‫‪Consider the following:‬‬
‫)‪Real ARRAY_A (1:3, 5:8‬‬
‫)‪Real ARRAY_B (2:8, -3:20‬‬
‫‪ :Dim‬یک عدد صحیح از ‪ 1‬تا ‪ n‬بوده که ‪ n‬تعداد ابعاد آرایه میباشد و در صورت‬
‫‪Ubound (ARRAY_A) is (3, 8). Ubound (ARRAY_A, Dim = 2) is 8.‬‬ ‫استفاده‪ ،‬مشخص کنندهی آن است که تابع ‪ Lbound‬روی کدام بعد از آرایه عمل‬
‫‪Ubound (ARRAY_B) is (8, 20).‬‬
‫کند‪.‬‬
‫‪The following shows another example:‬‬
‫)‪Real ar1 (2:3, 4:5, -1:14), vec1 (35‬‬
‫)‪Integer res1 (3), res2, res3 (1‬‬ ‫‪ :Result‬همواره از نوع صحیح است‪ .‬در صورتی که از ‪ Dim‬استفاده شده باشد‪،‬‬
‫)‪res1 = Ubound (ar1‬‬ ‫]‪! returns [3, 5, 14‬‬
‫‪res2 = Ubound (ar1, Dim = 3) ! returns 14‬‬
‫یک عدد بوده و در غیر اینصورت‪ ،‬یک آرایهی تک بعدی است که تعداد عناصر آن‪،‬‬
‫)‪res3 = Ubound (vec1‬‬ ‫‪! returns 35‬‬ ‫برابر با تعداد ابعاد ‪ Array‬میباشد‪ .‬مقدار هر عنصرش نیز برابر با حد پایینی اندیس هر‬
‫)]‪3) result = Size (array [, dim‬‬ ‫بعد ‪ Array‬به صورت متناظر میباشد‪.‬‬
‫‪ :Result‬در صورتی که از ‪ Dim‬استفاده شده باشد‪ ،‬برابر با تعداد عناصر بعد ذکر‬
‫لذا فرض کنید که میخواهید از این تابع استفاده کنید و خروجی آنرا ذخیره کنید‪ .‬اگر‬
‫شده بوده و در غیر این صورت‪ ،‬برابر تعداد کل عناصر آرایه میباشد‪.‬‬
‫از ‪ Dim‬استفاده کنید‪ ،‬می توانید خروجی را در یک متغیر عادی ذخیره کنید؛ در‬
‫)‪If B is declared as B (2:4, -3:1), then Size (B, Dim = 2‬‬
‫‪has the value 5 and Size (B) has the value 15.‬‬

‫‪54‬‬
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ )‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها‬

B = Shape (A); C = Shape (MASK) The following shows another example:


If ((B (1) .EQ. C (1)) .AND. (B (2) .EQ. C (2)) & Real array (3:10, -1:3)
.AND. (B (3) .EQ. C (3))) Then Integer I
conform = .TRUE. I = Size (array, Dim = 2) ! returns 5
Else I = Size (array) ! returns 40
conform = .FALSE.
End If 4) result = Shape (source)
End If
Write (*,*) conform ! prints F
‫ یک آرایه یا عدد میباشد و نمیتواند آرایهی تخصیصپذیری باشد که‬:Source
End .‫هنوز عمل تخصیص به آن انجام نشده است‬
5) [name :] Where (mask-expr1)
‫ یک آرایهی تکبعدی است که تعداد عناصر آن برابر با تعداد ابعاد‬:Result
[where-body-stmt] ...
‫ به صورت‬Source ِ‫ برابر با تعداد عناصرِ هر بعد‬،‫ بوده و مقدار هر عنصر آن‬Source
[Elsewhere (mask-expr2) [name]
.‫متناظر میباشد‬
[where-body-stmt] ...]
[Elsewhere [name] Shape (2) has the value of a rank-one array of size zero.
If B is declared as B (2:4, -3:1), then Shape (B) has the
[where-body-stmt] ...] value (3, 5).

End Where[name] The following shows another example:


Integer VEC (2)
‫ دقیقا از اسمش پیداست؛ یعنی این تابع یک سری‬Where ‫عملکرد تابع ذاتی‬ Real array (3:10, -1:3)
VEC = Shape (array)
‫ هرجا که آن عبارات‬.‫) را در عناصر آرایه بررسی میکند‬mask-expr( ‫عبارات منطقی‬ Write (*,*) VEC ! prints 8 5
End
‫) اجرا‬Where-body-stmt( ‫ یک سری دستورات مربوطه‬،‫منطقی محقق شوند‬ !
! Check if a mask is conformal with an array
.‫میشوند‬
Real, Allocatable :: A (:,:,:)
Logical, Allocatable :: MASK (:,:,:)
‫ نمیتواند فاصله وجود داشته باشد؛ ولی‬Where ‫ و‬Else ‫دقت کنید که بین کلمات‬ Integer B(3), C(3)
Logical conform
.‫ بالمانع است‬Where ‫ و‬End ‫وجود فاصله بین‬ Allocate (A (5, 4, 3))
Allocate (MASK (3, 4, 5))
! Check if MASK and A allocated. If they are, check
! that they have the same shape (conform).
If (Allocated (A) .AND. Allocated (MASK)) Then
55
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ ‫ محمدصادق عباسیان‬:‫تهیه و تنظیم‬

‫ در واقع به صورت‬triplet-spec ‫قسمت‬ )... ‫ و‬Select Case ،Do ،If ‫ (مانند ساختارهای‬Where ‫واضح است که ساختار‬

subscript-name = subscript-1 : subscript-2 [:stride] .‫به صورت اختیاری دارای نام نیز میتواند باشد‬

.‫ یک متغیر از نوع صحیح میباشد‬subscript-name ‫میباشد که در آن‬ The following shows an example using a WHERE statement:
Integer A, B, C
‫ اندیس پایان و گام‬،‫ به ترتیب اندیس شروع‬stride ‫ و‬subscript-2 ،subscript-1 Dimension A (5), B (5), C (5)
Data A /0, 1, 1, 1, 0/
.‫ هستند‬subscript-name ‫حرکت روی اندیسها برای‬ Data B /10, 11, 12, 13, 14/
C = -1
،‫ نیز از اسمش پیداست؛ یعنی به کمک این تابع‬Forall ‫نحوهی عملکرد تابع ذاتی‬ Where (A .NE. 0) C = B / A
The resulting array C contains: -1, 11, 12, 13, and -1.
‫ یک‬،‫ مشخص شدهاند‬triplet-spec ‫برای تمام عناصری که اندیسهایشان در قسمت‬
The following is an example of the WHERE construct:
‫ البته میتوان در قسمت‬.‫) اجرا میشوند‬forall-body-stmt( ‫سری دستورات مربوطه‬ Dimension PRESSURE (1000), TEMP (1000), PRECIPITATION (1000)
Where (PRESSURE .GE. 1.0)
‫ در اینصورت‬.‫ نیز از یک عبارت منطقی به صورت اختیاری استفاده کرد‬mask-expr PRESSURE = PRESSURE + 1.0
TEMP = TEMP - 10.0
.‫ دستورات اجرا میشوند‬،‫ بودن عبارت منطقی برای عناصر مورد نظر‬True ‫با‬ Elsewhere
PRECIPITATION = .TRUE.
Real, Dimension (N, N) :: A Endwhere
Forall (I = 1:N) A (I, I) = 1

Consider the following:


Another example:
Forall (I = 1:N, J = 1:N, A(I, J) .NE. 0.0) B (I, J) &
Real a(20)
= 1.0 / A (I, J)
. . .
Where (a > 0.0)
Where (A /= 0.0) B = 1.0 / A
a = Log (a)
It is also equivalent )‫ (معادل‬to: !Log is invoked only for positive elements
Forall (I = 1:N, J = 1:N) End Where
Where (A (I, J) .NE. 0.0) B (I, J) = 1.0 / A (I, J) 6) [name :] Forall (triplet-spec [,triplet-spec] ...[, mask-expr])
End Forall
forall-body-stmt
The following example shows a FORALL construct: [forall-body-stmt] ...
Forall (I = 3:N + 1, J = 3:N + 1)
C (I, J) = C (I, J + 2) + C (I, J - 2) + C (I + 2, J) & End Forall [name]
+ C (I - 2, J)

56
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ )‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها‬

Product (C, Mask = C .LT. 0.0) returns the product of the D (I, J) = C (I, J)
negative elements of C. End Forall

A is the array 7) result = Sum (array [, dim] [, mask])


[ 1 4 7 ]
[ 2 3 5 ]. ‫ تابع‬،‫ در صورت استفاده از آن‬.‫ یک عبارت منطقی و مناسب با آرایه میباشد‬:Mask
Product (A, Dim = 1) returns the value (2, 12, 35), which is
the product of all elements in each column. 2 is the product
.‫ باشد اجرا میشود‬True ‫ روی عناصری که عبارت منطقی برایشان‬Sum
of 1 * 2 in column 1. 12 is the product of 4 * 3 in column
Sum ((/2, 3, 4/)) returns the value 9 (sum of 2 + 3 + 4).
2, and so forth.
Sum ((/2, 3, 4/), Dim = 1) returns the same result.
Product (A, Dim = 2) returns the value (28, 30), which is
Sum (B, Mask = B .LT. 0.0) returns the arithmetic sum of the
the product of all elements in each row. 28 is the product
negative elements of B.
of 1 * 4 * 7 in row 1. 30 is the product of 2 * 3 * 5 in row
2.
C is the array
[ 1 2 3 ]
The following shows another example:
[ 4 5 6 ].
Integer array (2, 3)
Sum (C, Dim = 1) returns the value (5, 7, 9), which is the
Integer AR1(3), AR2(2)
sum of all elements in each column. 5 is the sum of 1 + 4 in
array = Reshape ((/1, 4, 2, 5, 3, 6/),(/2,3/))
column 1. 7 is the sum of 2 + 5 in column 2, and so forth.
! array is 1 2 3
Sum (C, Dim = 2) returns the value (6, 15), which is the sum
! 4 5 6
of all elements in each row. 6 is the sum of 1 + 2 + 3 in
row 1. 15 is the sum of 4 + 5 + 6 in row 2.
AR1 = Product (array, Dim = 1) ! returns [ 4 10 18 ]
AR2 = Product (array, Mask = array .LT. 6, Dim = 2)
The following shows another example:
! returns [ 6 20 ]
Integer array (2, 3), I, J (3)
End
array = Reshape ((/1, 2, 3, 4, 5, 6/), (/2, 3/))
‫بخش دوم – تمارین‬ ! array is 1 3 5
! 2 4 6
I = Sum ((/ 1, 2, 3 /)) ! returns 6
.‫ یک اعالن مناسب بنویسید‬،‫) برای هریک از موارد زیر‬1 ‫تمرین‬ J = Sum (array, Dim = 1) ! returns [3 7 11]
Write(*,*) I, J
‫ هستند و هریک از‬5 ‫ تا‬-5 ‫آرایهای که اندیسهای آن اعداد صحیح از‬ .i End

.‫عناصر آن دارای مقدار قرینهی اندیس خود میباشد‬ 8) result = Product (array [, Dim] [, mask])
Product ((/2, 3, 4/)) returns the value 24 (the product of 2
* 3 * 4). Product ((/2, 3, 4/), Dim = 1) returns the same
result.

57
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ ‫ محمدصادق عباسیان‬:‫تهیه و تنظیم‬

Array (I, J) = 0 ‫ است و هر یک از عناصر‬22 ‫ تا‬1 ‫آرایهای که اندیسهای آن اعداد صحیح از‬ .ii
Else
Array (I, J) = 1 ‫ و هریک از عناصر با اندیس فرد دارای‬.True. ‫با اندیس زوج دارای‬
End If
End Do .‫ میباشد‬.False.
End Do
c) Do I = 1, 3 ‫ هستند و هریک از عناصر آن مقدار‬359 ‫ تا‬1 ‫آرایهای که اندیسهای آن از‬ .iii
Do J = 1, I
Array (I, J) = 0 .‫کسینوسهایپربولیک زاویهی اندیس خود را دارا میباشد‬
End Do
Do J = I + 1, 3 .‫ اعالنهای زیر را در نظر بگیرید‬،‫) برای هر یک از موارد‬2 ‫تمرین‬
Array (I, J) = 2
End Do Integer, Dimension (3, 3) :: Array
End Do Integer, Dimension (6) :: Number
d) Do I = 1, 3 Integer :: I, J
Do J = 1, 3
Read*, Array (I, J) :‫ ورودی به شرح زیر است‬،‫همچنین برای مواردی که نیاز به ورودی دارند‬
End Do
End Do 1 2 3 4 5 6 7 8 9
e) Read*, Array
f) Read*, ((Array (I, J), J= 1, 3), I = 1, 3) ‫ اگر خطایی وجود دارد آنرا رفع نمایید و سپس بیان کنید که به هر‬،‫در هر مورد‬
g) Read*, ((Array (J, I), I = 1, 3), J = 1, 3)
h) Read*, ((Array (I, J), I = 1, 3), J = 1, 3) .‫کدام از عناصر آرایه چه مقداری نسبت داده میشود‬
i) Do I = 1, 3
Read*, (Array (I, J), J = 1, 3) a) Do I = 1, 3
End Do Do J = 3, 1, -1
Read*, Number If (I == J) Then
Do I = 1, 3 Array (I, J) = 0
Do J = 1, 3 Else
Array (I, J) = Number (I) + Number (J) Array (I, J) = 1
End Do End If
End Do End Do
j) Read*, Number, (Array (I, J), J = 1, 3) End Do
Do I = 1, 2 b) Do I = 1, 3
Do J = 1, 3 Do J = 1, 3
Array (Number (I + 1), Number (J)) = & If (I < J) Then
Number (I + J) Array (I, J) = -1
End Do Else If (I == J)

58
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها)‬

‫تمرین ‪ )6‬یک کارخانهی خودروسازی‪ ،‬دادههای مربوط به سر و صدای شش مدل‬ ‫‪End Do‬‬

‫خودرو را در سرعتهای مختلف بر حسب دسیبل جمعآوری نموده و در جدول زیر‬ ‫تمرین ‪ )3‬خروجی برنامهی زیر را به دقت بنویسید‪.‬‬

‫که در یک فایل قرار دارد‪ ،‬ذخیره نموده است‪.‬‬ ‫‪Program Test‬‬


‫‪Implicit None‬‬
‫)‪Speed (Mile/Hour‬‬ ‫‪Integer, Parameter :: N = 5, M = 10‬‬
‫‪Car Model‬‬ ‫‪20‬‬ ‫‪30‬‬ ‫‪40‬‬ ‫‪50‬‬ ‫‪60‬‬ ‫‪70‬‬ ‫‪80‬‬ ‫‪Integer, Dimension (N : M, M - M : M + N) :: Info‬‬
‫‪1‬‬ ‫‪88‬‬ ‫‪90‬‬ ‫‪94‬‬ ‫‪102‬‬ ‫‪111‬‬ ‫‪122‬‬ ‫‪134‬‬ ‫)‪Write(*, 100) Shape (Info‬‬
‫‪2‬‬ ‫‪75‬‬ ‫‪77‬‬ ‫‪80‬‬ ‫‪86‬‬ ‫‪94‬‬ ‫‪103‬‬ ‫‪113‬‬ ‫)‪100 Format (1X, "The shape of the array is:", I6‬‬
‫‪3‬‬ ‫‪80‬‬ ‫‪83‬‬ ‫‪85‬‬ ‫‪94‬‬ ‫‪100‬‬ ‫‪111‬‬ ‫‪121‬‬ ‫)‪Write(*, 110) Size (Info‬‬
‫‪4‬‬ ‫‪68‬‬ ‫‪71‬‬ ‫‪76‬‬ ‫‪85‬‬ ‫‪96‬‬ ‫‪110‬‬ ‫‪125‬‬ ‫)‪110 Format (1X, "The size of the array is:", I6‬‬
‫‪5‬‬ ‫‪77‬‬ ‫‪84‬‬ ‫‪91‬‬ ‫‪98‬‬ ‫‪105‬‬ ‫‪112‬‬ ‫‪119‬‬ ‫)‪Write(*, 120) Lbound (Info‬‬
‫‪6‬‬ ‫‪81‬‬ ‫‪85‬‬ ‫‪90‬‬ ‫‪96‬‬ ‫‪102‬‬ ‫‪109‬‬ ‫‪120‬‬ ‫)‪120 Format (1X, "The lower bound of the array is:", I6‬‬
‫)‪Write(*, 130) Ubound (Info‬‬
‫برنامهای بنویسید که دادههای این فایل را خوانده و اعمال زیر را انجام دهد‪:‬‬ ‫)‪130 Format (1X, "The upper bound of the array is:", I6‬‬
‫‪End Program‬‬
‫‪ .1‬جدول به همین صورتی که در فایل ورودی قرار دارد در خروجی چاپ‬ ‫تمرین ‪ )4‬برنامهای بنویسید که ضرایب یک چند جملهای درجهی ‪ n‬به شکل‬
‫شود‪.‬‬
‫را از ورودی بگیرد و مقدار آنرا در یک‬
‫‪ .2‬متوسط سر و صدای خودروها بر حسب مدلشان محاسبه و چاپ شود‪.‬‬
‫نقطهی خاص محاسبه نماید‪ .‬بنابراین ورودیها ‪ ،n‬ضرایب و نقطهای که مقدار‬
‫‪ .3‬متوسط سر و صدای خودروها بر حسب سرعتها محاسبه و چاپ شود‪.‬‬
‫چندجملهای در آن محاسبه میشود بوده و خروجی مقدار چندجملهای میباشد‪.‬‬

‫تمرین ‪ )5‬برنامهای بنویسید که دو عدد بسیار بزرگ‪ ،‬مثال ‪ 322‬رقمی را با هم جمع‬


‫نموده و حاصل را چاپ نماید‪ .‬برای اینکار دو آرایه در نظر بگیرید که ارقام دو عدد در‬
‫عناصر آنها ذخیره میشوند‪.‬‬

‫برنامه را برای ضرب دو عدد نیز بنویسید!‬

‫‪59‬‬
62
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ ‫ محمدصادق عباسیان‬:‫تهیه و تنظیم‬

If (Response /= "Y" .AND. Response /= "y") Exit


End Do )‫فصل پنجم (زیربرنامهها‬
Contains
Subroutine PrintDegrees (Degrees, Minutes, Seconds)
Integer, Intent (In) :: Degrees, Minutes, Seconds ‫) پرداخته شده و‬Subroutine( ‫در این فصل ابتدا به زیربرنامههای از نوع سابروتین‬
Print 10, Degrees, Minutes, Seconds, &
Real (Degrees) + Real (Minutes) / 60.0 + &
‫)ها پرداخته میشود؛ چراکه تابع حالت سادهتری از سابروتین‬Function(‫سپس به تابع‬
Real (Seconds) / 3600.0 ‫ در انتها نیز‬.‫ به معنای تسلط بر تابع میباشد‬،‫میباشد و تسلط به سابروتین‬
10 Format (1X, I3, "Degrees", I3, "Minutes", I3, &
"Seconds" / 1X, "is equivalent to" / 1X, F7.3, "Degrees") .‫)ها مورد بررسی قرار میگیرند‬Module(‫ماژول‬
End Subroutine PrintDegrees
End Program Angle
‫ سابروتینها‬-1
:‫نمونهی اجرای برنامه به شرح زیر است‬
Enter degrees, minutes, and seconds: 29, 32, 05 ‫) و یک سابروتین‬Main Program( ‫) برنامهی زیر از یک برنامهی اصلی‬1 ‫مثال‬
29Degrees 32Minutes 5Seconds
is equivalent to
‫ دقیقه و ثانیه دریافت‬،‫ برنامه مقدار یک زاویه را به صورت درجه‬.‫تشکیل شده است‬
29.535Degrees ‫ درجه و‬100 ‫میکند و معادل آنرا بر حسب درجه محاسبه و چاپ مینماید؛ مثال مقدار‬
More angles (Y or N)? y .‫ تبدیل میشود‬100.510 ‫ به‬،‫ ثانیه‬36 ‫ دقیقه و‬30
Enter degrees, minutes, and seconds: 47, 28, 05
47Degrees 28Minutes 51Seconds Program Angle
is equivalent to Implicit None
47.481Degrees Integer :: NumDegrees !Degrees in the angle measurement
Integer :: NumMinutes !Minutes in the angle measurement
More angles (Y or N)? n Integer :: NumSeconds !Seconds in the angle measurement
Press any key to continue Character (1) :: Response !User response to more-data
!question
:‫نکات‬ ! Read and convert angles until user signals no more data
Do
‫ هر بخش شامل موارد بسیار‬.‫مطالب زیر را با حوصله و تحمل مطالعه فرمایید‬ Write (*, "(1X, A)", Advance = "No") &
"Enter degrees, minutes, and seconds: "
‫ در هرجا که کلمهی زیربرنامه آورده‬.‫مهمی میشود که به آنها نیاز خواهید داشت‬ Read*, NumDegrees, NumMinutes, NumSeconds
Call PrintDegrees (NumDegrees, NumMinutes, NumSeconds)
.‫ منظور هر دو مورد تابع و سابروتین میباشد‬،‫شده است‬ Write (*, "(/ 1X, A)", Advance = "No") &
"More angles (Y or N)? "
Read*, Response

61
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – پنجم (زیربرنامهها)‬

‫هستند)‪ .‬مسالهی قابل توجه در مورد آرگومانهای حقیقی و ساختگی‬ ‫‪ ‬شکل کلی اعالن یک سابروتین به صورت‬
‫زیربرنامه ها این است که این دو نوع آرگومان باید تناظر یک به یک داشته‬ ‫])]‪[prefix] Subroutine Subroutine name [([d-arg-list‬‬
‫باشند؛ یعنی‪:‬‬ ‫…‬
‫)‪(Decleration Section‬‬
‫‪ .1‬تعداد آرگومانهای حقیقی و ساختگی یک زیربرنامه باید در‬
‫…‬
‫حالت عادی برابر باشند‪.‬‬ ‫)‪(Executive Section‬‬
‫]‪End Subroutine [Name‬‬
‫‪ .2‬نوع آرگومانهای حقیقی و ساختگی باید متناظرا یکسان باشد‪.‬‬
‫مثال اگر اولین آرگومان حقیقی یک زیر برنامه از نوع ‪Real‬‬ ‫میباشد که در آن‪:‬‬

‫است‪ ،‬اولین آرگومان ساختگی آن زیربرنامه نیز باید از نوع ‪Real‬‬ ‫‪ :Prefix‬اختیاری بوده و شامل یکی از موارد ‪ Pure ،Recursive‬و‬
‫باشد‪.‬‬ ‫‪ Elemental‬میشود که البته در ادامه‪ ،‬فقط مورد ‪ Recursive‬مورد‬
‫‪ ‬آرگومانهای سابروتین میتوانند دادهها را از برنامهی اصلی به سابروتین‬ ‫بررسی قرار خواهد گرفت‪.‬‬
‫منتقل کنند یا دادهها را از سابروتین به برنامهی اصلی منتقل کنند و یا اینکه‬ ‫‪ :Name‬نام سابروتین میباشد‪.‬‬
‫میتوانند هر دو کار را انجام دهند‪ .‬این امر به کمک دستور ‪ Intent‬مشخص‬ ‫‪ :d-arg-list‬فهرست آرگومانهای سابروتین میباشد‪.‬‬
‫میشود‪ .‬این دستور را در اعالن متغیرها میتوان به سه صورت زیر به کار‬ ‫‪ ‬همانطور که مشخص است‪ ،‬اعالن سابروتین با واژهی ‪ Subroutine‬شروع‬
‫گرفت‪:‬‬ ‫شده و با ‪ End Subroutine‬پایان مییابد‪ .‬هر سابروتین باید دارای نام باشد‬
‫‪ :Intent (In) -‬متغیرهایی که به این صورت تعریف میشوند‪،‬‬ ‫که نام سابروتین‪ ،‬از قراردادهای نام متغیرها پیروی میکند‪.‬‬
‫مقدار (یا مقادیر) آنها از برنامهی اصلی گرفته شده و نمیتواند در‬ ‫‪ ‬سابروتین میتواند دارای یک یا چند آرگومان برای برقراری ارتباط با‬
‫داخل زیربرنامه تغییر کند‪.‬‬ ‫برنامهی اصلی باشد که به آنها آرگومانهای ساختگی ( ‪Dummy‬‬
‫‪ :Intent (Out) -‬متغیرهایی که به این صورت تعریف میشوند‪،‬‬ ‫‪ )Arguments‬گفته میشود؛ چراکه هیچ حافظهای به آنها اختصاص داده‬
‫مقدار (یا مقادیری) را از زیربرنامه به برنامهی اصلی منتقل‬ ‫نمیشود‪ .‬اسامی آرگومانهای حقیقی و ساختگی‪ ،‬میتوانند یکسان و یا‬
‫متفاوت باشند (در مثال فوق‪ ،‬نام آرگومانهای حقیقی و ساختگی متفاوت‬

‫‪62‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫هستند؛ لذا به علت این یکپارچگی‪ ،‬مجموعهی برنامهی اصلی و‬ ‫میکنند‪ .‬آرگومان حقیقی متناظر با این متغیرها باید متغیر بوده و‬
‫تمام زیربرنامهها ناچارا باید در یک فایل قرار داشته باشند و یکجا‬ ‫نمیتواند عبارت‪ ،‬عدد یا رشته باشد‪.‬‬
‫ترجمه شوند (بدیهی است که این مساله یک عیب محسوب‬ ‫‪ :Intent (InOut) -‬متغیرهایی که به این صورت تعریف‬
‫میشود)‪.‬‬ ‫میشوند‪ ،‬میتوانند مقدار (یا مقادیری) را از برنامهی اصلی وارد‬
‫در این رویکرد‪ ،‬برنامه ی اصلیِ دیگری نمیتواند از زیربرنامههای‬ ‫زیر برنامه کنند یا مقدار (یا مقادیری) را از زیربرنامه به برنامهی‬
‫داخلی یک برنامه استفاده کند‪.‬‬ ‫اصلی منتقل کنند‪.‬‬
‫همچنین تمام متغیرها و خصوصیات برنامهی اصلی‪ ،‬به زیربرنامهها‬ ‫‪ ‬همانطور که در شکل کلی اعالن سابروتین مشخص است‪ ،‬سابروتین‬
‫منتقل میشود‪ .‬مثال اگر متغیری در برنامهی اصلی اعالن شود‪،‬‬ ‫میتواند هبچ آرگومانی نداشته باشد‪.‬‬
‫میتوان از آن بدون اعالن در زیربرنامهها استفاده نمود‪ .‬یا مثال اگر‬ ‫‪ ‬زیربرنامه به صورت مستقل نمی تواند اجرا شود و حتما باید به یک برنامهی‬
‫از دستور ‪ Implicit None‬در برنامهی اصلی استفاده شود‪،‬‬ ‫اصلی متصل شود‪ .‬نحوهی اتصال زیربرنامه به برنامهی اصلی‪ ،‬با دو رویکرد‬
‫خاصیت این دستور در زیربرنامهها هم وجود خواهد داشت‪.‬‬ ‫متفاوت میسر است‪:‬‬
‫‪ .2‬رویکرد خارجی‪ :‬در این رویکرد‪ ،‬برنامهی اصلی و هریک از‬ ‫‪ .1‬رویکرد داخلی‪ :‬در این رویکرد‪ ،‬برنامهی اصلی در ابتدا قرار‬
‫زیربرنامهها‪ ،‬با دستور ‪ End‬تمام شده و دستور ‪ Contains‬بین‬ ‫گرفته و زیربرنامهها بعد از اتمام برنامهی اصلی آورده میشوند‪.‬‬
‫آنها قرار نگرفته و لذا یکپارچکی رویکرد داخلی وجود ندارد‪ .‬با‬ ‫زیربرنامهها از برنامهی اصلی با دستور ‪ Contains‬جدا میشوند‬
‫توجه با این مساله‪ ،‬برنامهی اصلی و هریک از زیربرنامهها میتوانند‬ ‫(به کدهای مثال ‪ 1‬توجه کنید)‪ .‬بنابراین هیچ قسمتی از برنامهی‬
‫در یک فایل مجزا قرار داشته باشند و به تبع آن به صورت مجزا‬ ‫اصلی را نمیتوان بعد از ‪ Contains‬آورد‪.‬‬
‫ترجمه شوند‪.‬‬ ‫هر کدام از زیربرنامهها دارای دستور ‪ End‬بوده و در نهایت‬
‫در این رویکرد‪ ،‬میتوان از یک زیربرنامه‪ ،‬به دفعات دلخواه در‬ ‫مجموعهی برنامهی اصلی و همهی زیربرنامهها نیز دارای یک‬
‫برنامههای مختلف استفاده نمود که این مورد مزیت بسیار با‬ ‫دستور ‪ End‬میباشند‪ .‬این بدان معناست که مجموعهی برنامهی‬
‫اهمیتی میباشد‪.‬‬ ‫اصلی و تمام زیربرنامهها‪ ،‬دارای یک شروع و خاتمهی کلی‬

‫‪63‬‬
)‫دانشگاه صنعت آب و برق (شهید عباسپور‬ )‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – پنجم (زیربرنامهها‬

If (Response /= "Y" .AND. Response /= "y") Exit ،‫الزم به ذکر است که در این رویکرد بر خالف رویکرد داخلی‬
End Do
End .‫خصوصیات برنامهی اصلی به زیربرنامهها منتقل نمیشود‬
Subroutine PrintDegrees (Degrees, Minutes, Seconds)
Integer, Intent (In) :: Degrees, Minutes, Seconds ‫قابل توجه است که رویکرد خارجی بر رویکرد داخلی ارجحیت دارد و توصیه‬
Print 10, Degrees, Minutes, Seconds, &
Real (Degrees) + Real (Minutes) / 60.0 + & .‫میشود حتیالمقدور از این رویکرد استفاده شود‬
Real (Seconds) / 3600.0
10 Format (1X, I3, "Degrees", I3, "Minutes", I3, & ‫ به صورت زیر‬Call ‫ به کمک دستور‬،‫ فراخوانی سابروتین در برنامهی اصلی‬
"Seconds" / 1X, "is equivalent to" / 1X, F7.3, "Degrees")
End :‫انجام میپذیرد‬
Call Subroutine name [(Actual variables list)]
‫ وتر آنرا‬،‫) سابروتینی بنویسید که از روی اضالع یک مثلث قائمالزاویه‬2 ‫مثال‬
‫ کنترل به اولین دستور‬،‫هر جای برنامهی اصلی که این دستور آورده شود‬
.‫محاسبه نماید‬
،‫اجرایی درون سابروتین منتقل شده و پس از انجام دستورات سابروتین‬
Subroutine Cal_Hypotenuse (Side1, Side2, Hypotenuse)
Implicit None ‫ در برنامه ی اصلی باز‬Call ‫کنترل به اولین دستور اجرایی پس از دستور‬
Real, Intent (In) :: Side1, Side2
Real, Intent (Out) :: Hypotenuse .‫میگردد‬
Real :: Temp
Temp = Side1 ** 2 + Side2 ** 2 :‫ داریم‬،‫ را با رویکرد خارجی کدنویسی کنیم‬1 ‫اکنون اگر بخواهیم مثال‬
Hypotenuse = Sqrt (Temp)
End Subroutine Program Angle
Implicit None
Integer :: NumDegrees !Degrees in the angle measurement
:‫نکات‬ Integer :: NumMinutes !Minutes in the angle measurement
Integer :: NumSeconds !Seconds in the angle measurement
‫ مثال حاال که‬.‫ بسیار مهم است که بتوان زیربرنامهها را به تنهایی نوشت‬ Character (1) :: Response !User response to more-data
‫ میتوانیم به دفعات از آن در برنامههای مختلف‬،‫زیربرنامهی فوق را نوشتیم‬ !question
! Read and convert angles until user signals no more data
‫ لذا نوشتن زیربرنامهها بدون‬.‫(نوشته شده با رویکرد خارجی) استفاده کنیم‬ Do
Write (*, "(1X, A)", Advance = "No") &
.‫برنامهی اصلی یک امر مهم است که نیاز به تمرین دارد‬ "Enter degrees, minutes, and seconds: "
Read*, NumDegrees, NumMinutes, NumSeconds
Call PrintDegrees (NumDegrees, NumMinutes, NumSeconds)
Write (*, "(/ 1X, A)", Advance = "No") &
"More angles (Y or N)? "
Read*, Response

64
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫]‪End Function [Name‬‬ ‫‪ ‬متغیر ‪ Temp‬در این مثال در داخل سابروتین تعریف شده است‪ .‬این متغیر‬
‫نکات‪:‬‬ ‫در سابروتین مورد استفاده قرار گرفته و در دسترس برنامهی اصلی نمیباشد‪.‬‬
‫به این متغیرها‪ ،‬متغیر محلی (‪ )Local‬گفته میشود‪.‬‬
‫‪ ‬تفاوت اساسی تابع و سابروتین در این است که تابع میتواند چندین مقدار را‬
‫در رویکرد داخلی‪ ،‬متغیرهایی که در برنامهی اصلی اعالن میشوند‪ ،‬در‬
‫از برنامهی اصلی دریافت کند‪ ،‬ولی فقط یک جواب را میتواند به‬
‫زیربرنامهها قابل استفاده میباشند‪ .‬به این متغیرها متغیر جهانی (‪)Global‬‬
‫برنامهی اصلی برگرداند‪ .‬در حالی که همانطور که مشاهده شد‪ ،‬سابروتین‬
‫گفته میشود‪ .‬در بخش اول مثال ‪ 1‬که رویکرد حل مساله داخلی بود‪،‬‬
‫میتواند چندین مقدار را از ورودی گرفته و چندین مقدار را به برنامهی‬
‫متغیرهای ‪ NumDegrees ،NumMinutes ،NumSeconds‬و‬
‫اصلی برگرداند‪ .‬بنابراین هرگاه نیاز به برگرداندن بیش از یک جواب به‬
‫‪ Response‬متغیرهای جهانی هستند و میتوانند در زیربرنامه‪ ،‬بدون اعالن‬
‫برنامهی اصلی باشد‪ ،‬چارهای جز استفاده از سابروتین نیست‪.‬‬
‫استفاده شوند (مجددا تاکید میشود که فقط در رویکرد داخلی متغیرهای‬
‫‪ ‬در توابع باید نوع (‪ )Type‬جواب تابع را مشخص نمود‪ .‬به یکی از دو روش‬
‫برنامه ی اصلی جهانی هستند)‪ .‬در صورتی که از هر یک از این متغیرها در‬
‫زیر‪ ،‬این کار امکانپذیر است‪:‬‬
‫زیربرنامه استفاده شود‪ ،‬مقدار متغیر در زیربرنامه‪ ،‬همان مقداری است که در‬
‫‪ .3‬نوع جواب را میتوان در اعالن تابع‪ ،‬قبل از کلمهی ‪Function‬‬
‫برنامهی اصلی دارد‪.‬‬
‫آورد؛ مثال‪:‬‬
‫اگر در زیربرنامه‪ ،‬متغیری همنام با متغیر برنامهی اصلی اعالن شود‪ ،‬ارتباط با‬
‫)‪Integer Function Sum (A, B‬‬
‫برنامهی اصلی قطع شده‪ ،‬و متغیر دیگر مقدار خود در برنامهی اصلی را دارا‬
‫‪ .4‬در قسمت اعالن متغیرها (‪ )Decleration Section‬نیز میتوان‬
‫نبوده‪ ،‬و باید در زیربرنامه به آن مقداری را منتسب نمود‪.‬‬
‫نوع جواب را تعیین کرد؛ مثال‪:‬‬
‫‪ -2‬توابع‬
‫)‪Function Sum (A, B‬‬
‫‪Integer :: Sum‬‬ ‫شکل کلی اعالن یک تابع به صورت زیر است‪:‬‬
‫فقط باید یکی از دو روش فوق را برای مشخص نمودن نوع تابع انتخاب‬ ‫])‪[Type] Function Function name ([d-arg-list]) [Result (r-name‬‬
‫…‬
‫کرد‪.‬‬ ‫)‪(Decleration Section‬‬
‫…‬
‫)‪(Executive Section‬‬
‫‪65‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – پنجم (زیربرنامهها)‬

‫) ‪Function Ang (Vect1, Vect2‬‬ ‫ضمنا اگر از هیچ یکی از دو روش فوق استفاده نشود‪ ،‬برای جواب تابع‪،‬‬
‫‪Implicit None‬‬
‫‪! Function result‬‬ ‫اعالن ضمنی صورت میپذیرد‪ .‬توجه کنید که جواب تابع‪ ،‬توسط نام تابع به‬
‫‪Real :: Ang‬‬
‫‪! Dummy arguments‬‬ ‫برنامهی اصلی برمیگردد‪.‬‬
‫‪Real, Dimension (3), Intent (In) :: Vect1, Vect2‬‬
‫‪! Local variables‬‬ ‫‪ ‬اگر از ‪ Result‬استفاده شود‪ ،‬باید یک نام را درون پرانتز‪ ،‬جلوی آن آورد‪.‬‬
‫‪Real :: Cosang, Norm‬‬
‫& ‪Cosang = Vect1 (1) * Vect2 (1) + Vect1 (2) * Vect2 (2) +‬‬ ‫در این صورت‪ ،‬جواب تابع توسط این نام به برنامهی اصلی برمیگردد‪.‬‬
‫)‪Vect1 (3) * Vect2 (3‬‬
‫))‪Cosang = Cosang / (Norm (Vect1) * Norm (Vect2‬‬ ‫را در‬ ‫مثال ‪ )3‬تابعی بنویسید که مقدار یک سهمی به شکل‬
‫)‪Ang = Acos (Cosang‬‬
‫نقطه ‪ x‬محاسبه و چاپ نماید‪.‬‬
‫‪End Function Ang‬‬
‫‪! Norm returns the Norm of the Vector V‬‬ ‫)‪Real Function Quadf (X, A, B, C‬‬
‫)‪Function Norm (V‬‬ ‫‪Implicit None‬‬
‫‪Implicit None‬‬ ‫‪! Declare Calling Arguments‬‬
‫‪Real :: Norm‬‬ ‫‪Real, Intent (In) :: X, A, B, C‬‬
‫‪! Dummy arguments‬‬ ‫‪! Evaluate Expression‬‬
‫‪Real, Dimension (3) :: V‬‬ ‫‪Quadf = A * X ** 2 + B * X + C‬‬
‫)‪Norm = Sqrt (V (1) ** 2 + V (2) ** 2 + V (3) ** 2‬‬ ‫‪End Function‬‬
‫‪End Function Norm‬‬ ‫مثال ‪ )4‬برنامهی زیر از دو تابع تشکیل شده است‪ .‬توضیحات الزم دربارهی برنامه‪،‬‬
‫نکات‪:‬‬
‫توسط ‪ Comment‬داده شده است‪ .‬رویکرد برنامه خارجی است‪.‬‬
‫‪ ‬همانطور که در سابروتین دیده شد‪ ،‬فراخوانی سابروتین به کمک دستور‬ ‫‪Program angv1v2‬‬
‫‪ Call‬صورت می پذیرد؛ ولی در تابع‪ ،‬به منظور فراخوانی آن‪ ،‬باید نام تابع به‬ ‫‪Implicit None‬‬
‫‪real, Dimension (3) :: v1, V2‬‬
‫همراه آرگومانهایش آورده شود‪ .‬مثال در همین مثال‪ ،‬در خط دوازدهم‪ ،‬تابع‬ ‫‪Real :: Ang‬‬
‫‪! define two vectors V1 and V2‬‬
‫‪ Ang‬فراخوانده شده است‪ .‬هرجا که نام یک تابع آورده شود‪ ،‬کنترل به‬ ‫‪V1(1) = 1.0‬‬
‫‪V1(2) = 0.0‬‬
‫اولین دستور اجرایی تابع رفته و پس از اتمام دستورات اجرایی تابع‪ ،‬مجددا به‬ ‫‪V1(3) = 2.0‬‬
‫‪V2(1) = 1.5‬‬
‫برنامهی اصلی باز میگردد‪.‬‬ ‫‪V2(2) = 3.7‬‬
‫‪V2(3) = 2.0‬‬
‫)‪Print*, "Angle = ", Ang (V1, V2‬‬
‫‪End Program Angv1v2‬‬
‫‪! Ang computes the angle between 2 vectors Vect1 and Vect2‬‬

‫‪66‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫ضمنا میتوان حدود را به کمک آرگومان منتقل نکرده‪ ،‬و آنها را‬ ‫‪ ‬در این مثال مالحظه میشود که در یک تابع‪ ،‬از تابع دیگری استفاده (نه‬
‫مستقیما نوشت؛ ولی این کار به هیچ عنوان توصیه نمیشود (چرا؟)‪.‬‬ ‫اعالن) شده است‪ .‬این کار هیچ مانعی (در هر دو رویکرد داخلی یا خارجی)‬
‫‪Program Test‬‬ ‫ندارد‪ .‬مشابه اینکار برای آرگومانهای سابروتین نیز انجامپذیر است‪.‬‬
‫‪Implicit None‬‬
‫‪Integer, Dimension (4) :: A, B‬‬ ‫‪ -3‬انتقال آرایه به زیربرنامه‬
‫)‪A = (/1, 2, 3, 4/‬‬
‫)‪Call sub1 (A, B‬‬ ‫مثال ‪ )5‬برنامهی زیر یک آرایهی مقداردهیشده را به یک سابروتین منتقل میکند‪.‬‬
‫‪Print*, B‬‬
‫‪End‬‬ ‫سپس به صورت عملیات کل روی آرایه‪ ،‬به عناصر آرایهی مذکور یکی اضافه شده‪ ،‬و‬
‫!‬
‫)‪Subroutine Sub1(Num1, Num2‬‬ ‫مقادیر جدید درون یک آرایهی دیگر قرار میگیرند‪ .‬در نهایت آرایهی حاصله‪ ،‬به‬
‫‪Integer, Dimension (4), Intent(in) :: Num1‬‬
‫‪Integer, Dimension (4), Intent (out) :: Num2‬‬ ‫برنامهی اصلی منتقل میشود‪ .‬رویکرد برنامه خارجی است‪.‬‬
‫‪Num2 = Num1 + 1‬‬
‫‪Program Test‬‬
‫‪End‬‬
‫‪Implicit None‬‬
‫‪ -4‬انتقال متغیرهای کاراکتری به زیر برنامه‬ ‫‪Integer, Parameter :: N = 4‬‬
‫‪Integer, Dimension (N) :: A, B‬‬
‫مثال ‪ )6‬در برنامهی زیر یک رشته به زیربرنامه منتقل شده و درون آن چاپ میشود‪.‬‬ ‫)‪A = (/1, 2, 3, 4/‬‬
‫)‪Call sub1 (A, B, N‬‬
‫‪Program Assumed_Char‬‬ ‫‪Print*, B‬‬
‫‪Implicit None‬‬ ‫‪End‬‬
‫‪Character (Len=5) :: Name‬‬ ‫!‬
‫"‪Name = "Tanja‬‬ ‫)‪Subroutine Sub1(Num1, Num2, M‬‬
‫)‪Call Print_String (Name‬‬ ‫‪Integer, Intent (In) :: M‬‬
‫‪End Program Assumed_Char‬‬ ‫‪Integer, Dimension (M), Intent(in) :: Num1‬‬
‫)‪Subroutine Print_String (Name‬‬ ‫‪Integer, Dimension (M), Intent (out) :: Num2‬‬
‫‪Implicit None‬‬ ‫‪Num2 = Num1 + 1‬‬
‫‪! Dummy arguments‬‬ ‫‪End‬‬
‫‪Character (Len = *), Intent (In) :: Name‬‬
‫‪Print*, Name‬‬ ‫نکات‪:‬‬
‫‪End Subroutine Print_String‬‬
‫‪ ‬همانطور که مالحظه میشود‪ ،‬در این مثال حد باالیی آرایههای‬
‫نکات‪:‬‬
‫ساختگی‪ ،‬از طریق آرگومان سابروتین به سابروتین منتقل شده است‪ .‬به‬
‫همین صورت میتوان حد پایینی را نیز به زیربرنامه منتقل کرد‪.‬‬
‫‪67‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – پنجم (زیربرنامهها)‬

‫])]‪[prefix] Subroutine Subroutine name [([d-arg-list‬‬ ‫‪ ‬همانطور که مشخص است میتوان طول متغیر ساختگی را برابر ستاره قرار‬
‫…‬
‫داد‪ .‬در این صورت متغیر ساختگی‪ ،‬طولش را از آرگومان حفیفی دریافت‬
‫)‪(Decleration Section‬‬
‫…‬ ‫میکند‪.‬‬
‫)‪(Executive Section‬‬ ‫از فصل اول به خاطر دارید که در حالت عادی‪ ،‬فقط زمانی که متغیر‬
‫‪[Contains‬‬
‫]‪Internal Procedures‬‬ ‫کاراکتری از نوع پارامتر بود‪ ،‬میتوانستیم طولش را برابر ستاره قرار دهیم؛ لذا‬
‫]]‪End [Subroutine [Name‬‬ ‫این حالت نیز مانند پارامتر یک استثنای دیگر است‪.‬‬
‫توجه کنید که زیربرنامههای داخلی یک زیربرنامهی خارجی‪ ،‬فقط برای همان‬ ‫‪ ‬میتوان طول را برابر یک عدد قرار داد که همانند انتقال آرایهها‪ ،‬این کار‬
‫زیربرنامه قابل دسترس هستند‪.‬‬ ‫توصیه نمیشود‪.‬‬
‫‪ -6‬زیربرنامههای بازگشتی‬ ‫‪ -5‬اعالن یک زیربرنامه درون یک زیربرنامهی دیگر‬
‫همانطور که در مثال ‪ 4‬گفته شد‪ ،‬استفاده از تابع یا آرگومان سابروتین در هر دو‬
‫مثال ‪] )7‬توصیه می شود که پس از حل چند مثال ساده در این مبحث به مطالعهی این‬
‫رویکرد داخلی و خارجی بالمانع است‪ .‬اما فقط در صورتی که زیربرنامهی خارجی‬
‫مثال بپردازید‪ .‬در غیر این صورت این مثال باعث سردرگمی شما خواهد شد؛ چراکه حل‬
‫داشته باشیم‪ ،‬خود زیربرنامه میتواند دارای یک یا چند زیربرنامهی داخلی باشد‪.‬‬
‫این مثال به طور نسبی پیچیده میباشد‪ [.‬ربع اول یک دستگاه مختصات را در نظر‬
‫شکل انجام این کار برای تابع به صورت زیر است‪:‬‬
‫بگیرید‪ .‬میخواهیم برنامهای بنویسیم که ابتدا مختصات دو نقطه در این دستگاه را از‬
‫])‪[Type] Function Function name ([d-arg-list]) [Result (r-name‬‬
‫ورودی بگیرد‪ .‬سپس به شرط اینکه حرکت فقط به سمت راست و باال مجاز است‪،‬‬
‫…‬
‫تعداد مسیرهای بین این دو نقطه را بشمرد‪ .‬مثال فرض کنید مختصات نقاط وارد شده‪،‬‬ ‫)‪(Decleration Section‬‬
‫(‪ )1, 1‬و (‪ )4, 2‬باشد‪ .‬یعنی نقاط در دستگاه مختصات به شکل زیر باشند‪:‬‬ ‫…‬
‫)‪(Executive Section‬‬
‫‪[Contains‬‬
‫]‪Internal Procedures‬‬
‫]]‪End [Function [Name‬‬
‫به طور مشابه نیز برای سابروتین این کار قابل انجام است‪:‬‬

‫‪68‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫‪ ‬الگوریتم حل مساله به این شکل است (برای فهم بهتر‪ ،‬باید مواردی که بیان‬ ‫‪3‬‬

‫میشود را مرحله به مرحله روی شکل ارائهشده در صورت مساله دنبال‬ ‫‪2‬‬
‫‪1‬‬
‫کنید)‪:‬‬
‫‪0‬‬
‫فرض کنید که نقطهی شروع را )‪ ،A (x, y‬و نقطهی پایان را )'‪B (x', y‬‬ ‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪4‬‬ ‫‪5‬‬

‫اسمگذاری کنیم‪.‬‬ ‫در این صورت‪ ،‬تعداد مسیرهای بین این دو نقطه با شرط مذکور چهارمسیر میباشد‪.‬‬
‫به جای آنکه تعداد مسیرهای بین ‪ A‬و ‪ B‬را بشماریم‪ ،‬تعداد مسیرهای بین دو‬
‫کدهای زیر‪ ،‬حل این مساله به کمک تابع بازگشتی را نشان میدهند‪.‬‬
‫حالت زیر را میشماریم‪:‬‬
‫‪Program Path Counter‬‬
‫‪ A(x+1, y) .1‬و ‪B‬‬ ‫‪Implicit None‬‬
‫‪ A(x, y+1) .2‬و ‪B‬‬ ‫‪Integer :: Startrow, Startcolumn, EndRow, EndColumn‬‬
‫و سپس کل مسیرهای بین ‪ A‬و ‪ B‬برابر با جمع مسیرهای موارد ‪ 1‬و ‪ 2‬میشود‬ ‫"‪Print*, "Enter the starting coordinates (row and column):‬‬
‫‪Read*, StartRow, StartColumn‬‬
‫(به خط هجده و نوزده دقت کنید‪ .‬متغیر ‪ NumRows‬حاوی فاصلهی بین‬ ‫"‪Print*, "Enter the ending coordinates (row and column):‬‬
‫& ‪Read*, "There are",‬‬
‫عرض نقاط و متغیر ‪ NumColumns‬حاوی فاصلهی بین طول نقاط است)‪.‬‬ ‫& ‪Number_of_Paths (EndRow-StartRow,‬‬
‫"‪EndColumn-StarColumn), "Paths‬‬
‫هدف از این کار نزدیک کردن نقاط به یکدیگر و در نتیجه کم کردن تعداد‬ ‫‪Contains‬‬
‫& ‪Recursive Function‬‬
‫مسیرهای بین دو نقطه است‪.‬‬ ‫)‪Number_of_Paths (NumRows, NumColumns) Result (Num‬‬
‫مجددا برای شمردن مسیرهای حالت ‪ 1‬و ‪ ،2‬هر یک را به دو حالت تقسیم‬ ‫‪Integer :: Num‬‬
‫‪Integer, Intent (In) :: NumRows, NumColumns‬‬
‫میکنیم‪.‬‬ ‫‪If ((NumRows == 0) .OR. (NumColumns == 0)) Then‬‬
‫‪Num = 1‬‬
‫این کار آنقدر ادامه مییابد تا بین هر کدام از زیرحالتها‪ ،‬تعداد مسیرها یک‬ ‫‪Else‬‬
‫& )‪Num = Number_of_Paths (NumRows – 1, NumColumns‬‬
‫شود (به خط پانزدهم و شانزدهم از کدها دقت کنید)‪.‬‬ ‫)‪+ Number_of_Paths (NumRows, NumColumns + 1‬‬
‫‪End If‬‬
‫‪ ‬تنها در زیربرنامههای بازگشتی میتوان خود زیربرنامه را صدا زد و این کار‬ ‫‪End Function‬‬
‫‪End‬‬
‫در زیربرنامههای عادی مجاز نیست‪ .‬مشاهده میشود که همانطور که در‬
‫نکات‪:‬‬

‫‪69‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – پنجم (زیربرنامهها)‬

‫‪ ‬مالحظه می کنید که سابروتین در سابروتین بازگشتی نیز به کمک دستور‬ ‫برنامهی اصلی تابع به وسیلهی نام تابع صدا زده میشود‪ ،‬در تابع بازگشتی نیز‬
‫‪ Call‬فراخوانی میشود‪.‬‬ ‫تابع به کمک نامش صدا زده میشود‪.‬‬
‫در انتهای این بخش تصریح میشود که مبحث زیربرنامههای بازگشتی از‬ ‫‪ ‬فراموش نکنید که استفاده از کلمهی ‪ Recursive‬اجباری است‪.‬‬
‫مفهومیترین مباحث برنامهنویسی میباشد که درک آن نیاز به صرف زمان در دیدن‬ ‫‪ ‬استفاده از ‪ Result‬در توابع بازگشتی الزامی است‪.‬‬
‫مثالهای مختلف و حل آنها میباشد‪.‬‬ ‫مثال ‪ )8‬برنامهی زیر که شامل یک سابروتین بازگشتی میباشد‪ ،‬یک عدد را دریافت‬
‫در صورت تسلط به بازگشت‪ ،‬میتوان مسائل بسیاری که حل آنها به روش مستقیم‬ ‫نموده و درصورتی که عدد بزگترمساوی یک و کوچکترمساوی هشت باشد‪ ،‬از عدد‬
‫طوالنی و دشوار میباشد را سادهتر حل نمود‪ .‬به عنوان مثال‪ ،‬سعی کنید که مثال ‪ 7‬را‬ ‫یک تا عدد وارد شده را پشت سر هم در خروجی چاپ مینماید‪ .‬در صورتی که عدد‬
‫بدون استفاده از بازگشت و به روش مستقیم حل کنید‪.‬‬ ‫در بازه ی مذکور نباشد‪ ،‬فقط سطر خالی در خروجی چاپ میشود‪.‬‬
‫‪ -7‬ماژولها‬ ‫‪Read*, N‬‬
‫)‪Call S (N‬‬
‫*‪print‬‬
‫فرترن ‪ 92/95‬دارای ساختاری به نام ماژول است که میتواند شامل چندین متغیر یا‬
‫‪End‬‬
‫زیربرنامهی داخلی گردد؛ لذا با دسترسی به ماژول‪ ،‬میتوان به چندین متغیر یا زیربرنامه‬ ‫)‪Recursive Subroutine S (Num‬‬
‫‪Integer, Intent (In) :: Num‬‬
‫دسترسی پیدا کرد‪.‬‬ ‫‪If (1<= Num .And. Num <= 8) Then‬‬
‫)‪Call S (Num - 1‬‬
‫ماژول فقط شامل دو قسمت دستورات اعالن و زیربرنامههای داخلی میشود‬ ‫‪Write (*, '(I1)', Advance = "NO") Num‬‬
‫‪Else‬‬
‫که شکل کلی آن به صورت زیر است‪:‬‬ ‫*‪Print‬‬
‫‪End If‬‬
‫‪Module Module_name‬‬ ‫‪End‬‬
‫‪! Specification statements‬‬ ‫نکات‪:‬‬
‫‪Contains‬‬
‫‪! Internal procedures‬‬ ‫‪ ‬برنامهی فوق را حتما خودتان با مقادیر مختلف اجرا کنید‪.‬‬
‫]‪End Module [Module_name‬‬ ‫‪ ‬پس از اجرا با مقادیر مختلف‪ ،‬جای سطور هشت و نه را با هم عوض کرده و‬
‫مثال ‪ )9‬به برنامهی زیر توجه کنید و خطوط برنامه را دنبال کنید‪.‬‬ ‫مجددا برنامه را با مقادیر مختلف اجرا کنید‪ .‬تفاوت ایجاد شده حائز اهمیت‬
‫‪Module ConvertT‬‬ ‫میباشد‪.‬‬
‫‪Implicit None‬‬

‫‪72‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫تهیه و تنظیم‪ :‬محمدصادق عباسیان‬

‫هستند‪ .‬در صورتی که بخواهیم متغیرها خصوصی باشند‪ ،‬باید از کلمهی‬ ‫‪Real, Parameter, Private :: Factor = 0.555555556‬‬
‫‪Integer, Parameter, Private :: Offset = 32‬‬
‫‪ Private‬استفاده کنیم‪ .‬در این مثال هر دو متغیر اعالنشده از نوع خصوصی‬ ‫‪Contains‬‬
‫)‪Function CtoF (TinC) Result (TinF‬‬
‫هستند‪.‬‬ ‫‪! Funtion result‬‬
‫‪Real :: TinF‬‬
‫‪ ‬در بخش زیربرنامههای داخلی از دو تابع به نامهای ‪ CtoF‬و ‪ TinC‬اعالن‬ ‫‪! Dummy argument‬‬
‫‪Real, Intent (In) :: TinC‬‬
‫شدهاند که در دسترس برنامههای اصلی و زیربرنامههای استفادهکننده از‬ ‫‪TinF = (TinC / Factor) + Offset‬‬
‫‪End Function CtoF‬‬
‫ماژول قرار میگیرند‪.‬‬ ‫)‪Function FtoC (TinF) Result (TinC‬‬
‫‪ ‬مشاهده میشود که در برنامهی اصلی از ماژول اعالنشده استفاده شده است‪.‬‬ ‫‪!Function result‬‬
‫‪Real :: TinC‬‬
‫برای این که بتوان از یک ماژول در یک برنامه یا زیربرنامه استفاده کرد‪ ،‬باید‬ ‫‪! Dummy argument‬‬
‫‪Real :: TinF‬‬
‫از دستور ‪ Use‬که شکل کلی آن به صورت‬ ‫‪TinC = (TinF - Offset) * Factor‬‬
‫‪End Function FtoC‬‬
‫‪Use Module-name‬‬ ‫‪End Module Convert‬‬
‫میباشد در ابتدای برنامه یا زیربرنامه (قبل از دستورات اعالن) استفاده‬ ‫!‬
‫‪Program Convert_Temperature‬‬
‫نمود‪.‬‬ ‫‪Use ConvertT‬‬
‫‪Implicit None‬‬
‫در هر دستور ‪ Use‬فقط میتوان یک ماژول را مرتبط کرد‪.‬‬ ‫"‪Print*, "20 Celcius = ", CtoF (20.0), " Fahrenheit‬‬
‫"‪Print*, "100 Fahrenheit = ", FtoC (100.0), " Celcius‬‬
‫‪ ‬در صورتی که ماژول‪ ،‬برنامه و زیربرنامهها درون یک فایل قرار داشته باشند‪،‬‬ ‫‪End Program Convert_Temperature‬‬

‫حتما باید ماژول را قبل از برنامه و زیربرنامهها آورد‪.‬‬ ‫نکات‪:‬‬


‫‪ ‬در قسمت اعالن (‪ ،)Specification Statements‬دو متغیر از نوع‬
‫پارامتر به نامهای ‪ Factor‬و ‪ Offset‬اعالن شدهاند‪ .‬در قسمت اعالنهای‬
‫ماژول‪ ،‬متغیرها میتوانند دارای دو حالت عمومی و خصوصی باشند‪.‬‬
‫متغیرهای عمومی در دسترس برنامهها و زیربرنامههایی که از ماژول استفاده‬
‫میکنند قرار میگیرند؛ ولی متغیرهای خصوصی فقط در دسترس ماژول (یا‬
‫در واقع زیربرنامههای ماژول) هستند‪ .‬به صورت پیشفرض متغیرها عمومی‬

‫‪71‬‬
‫دانشگاه صنعت آب و برق (شهید عباسپور)‬ ‫جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – پنجم (زیربرنامهها)‬

‫مراجع‬
‫]‪ [1‬صالح‪ ،‬محمود؛ فرترن ‪ 92‬برای رشتههای علوم و مهندسی‪ ،‬انتشارات دانشگاه امامحسین‬

‫]‪ [2‬ناصرقدسی‪ ،‬امید و ممتاز‪ ،‬امید؛ ‪ ،Fortran 90/95‬انتشارات ناقوس‬

‫]‪ [3‬موسویندوشنی‪ ،‬سیدسعید؛ برنامهنویسی به زبان ‪ Fortran 90/95‬برای رشتههای علوم و مهندسی‪ ،‬انتشارات دانشگاه صنعت آب و برق‬

‫‪[4] Van Mourik, Tanja; Fortran 90/95 Programming Manual, fifth revision‬‬
‫‪[5] Chivers, Ian D. and Sleightholme, Jane; Introduction to Programming with Fortran, Springer‬‬
‫‪[6] Adams, Jeanne C. and Brainerd, Walter S. and Martin, Jeanne T. and Smith, Brian T. and Wagener, Jerrold L.; Fortran 90‬‬
‫‪Handbook, McGraw-Hill‬‬

‫‪72‬‬

You might also like