Jozve
Jozve
باشید که فقط در صورتی که یک متغیر کاراکتر به عنوان پارامتر اعالن شده قسمت زیربرنامهها ()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فرترن نام برنامه ،توضیحات اولیه برای توضیح راجع به عملکرد برنامه ،دستورات
میتوان آنها را پیدا کرد که در اینجا چند نمونه را آوردهام: کامل همراه با خروجیهای مناسب برای برقراری ارتباط با کاربر و
توضیحات جامع راجع به هر قسمت کدنویسی میشود.
-توابع سینوس ،کسینوس و تانژانت با آرگومان ورودی بر حسب
درجه: در تمام مسائلی که برایشان برنامه مینویسید (اعم از مسـائل ریاضـی،
6
و Hبرابر با کشش افقی کابل در نقطهی زیرین محاسبه میشود که در آن دقت کنید که آرگومان تمامی توابع فوق باید حقیقی ( )Realباشد.
کابل میباشد .برنامهای بنویسید که مقادیر H ،Wو xرا از ورودی بگیرد و مقدار y
بخش دوم – تمارین
متناظر را محاسبه و چاپ نماید.
(و تمرین )1همانطور که میدانید ،فاصلهی بین دو نقطه به مختصات )
تمرین )4قرار است یک تانکر نفت به شکل یک استوانه که دارای کالهک
( در دستگاه مختصات دکارتی از رابطهی زیر به دست میآید: )
مخروطی است ،ساخته شود .ارتفاع مخروط برابر با شعاع استوانه است و ظرفیت کل
تانکر (شامل قسمت استوانهای) برابر با 522متر مکعب است .برای ساختن هر متر مربع از (√ ) ( )
بدنهی استوانهی این تانکر 322دالر و برای ساختن هر متر مربع از بدنهی مخروط422 ، را از ورودی برنامهای بنویسید که طول و عرض دو نقطه یعنی
دالر هزینه میشود .برنامهای بنویسید که شعاع قاعدهی استوانه را گرفته و با توجه به گرفته و فاصلهی آنها از یکدیگر را محاسبه و به شکل مناسبی چاپ نماید.
حجم مخزن ،ارتفاع استوانه و نیز هزینهی ساخت تانکر را محاسبه نماید .برنامهی خود را تمرین )2پریود یک پاندول از رابطهی
برای مقادیر مختلف شعاع (از شعاع 4متر شروع کنید) اجرا کنید و هر بار مقدار کمی به
شعاع اضافه و یا کم کنید تا تعیین شود که چه شعاعی از مخزن ،کمترین هزینهی ساخت
( √ )) (
را دارد.
L ،طول پاندول به سانتیمتر و aزاویهی محاسبه میشود که در آن
a
جابجایی است .برنامهای بنویسید که مقدار Lو aرا از ورودی بگیرد و پریود را محاسبه
و به شکل مناسبی نمایش دهد .برنامه را برای مقادیر زیر اجرا کنید.
7
را در نظر بگیرید .برنامهای تمرین )5معادلهی
بنویسید که ضرایب این معادله را از ورودی بگیرد و در خروجی فرم کلی معادله را به
نحوی که میسر است چاپ نماید!
تمرین )6تیر سادهی ABبه طول ،Lتحت بارگذاری زیر مفروض است .برنامهای
بنویسید که مقادیر L ،Pو aرا از ورودی بگیرد و مقدار حداکثر لنگر خمشی را
محاسبه و چاپ نماید (پیشنیاز :استاتیک!).
a
P
A B
L
8
دانشگاه صنعت آب و برق (شهید عباسپور) تهیه و تنظیم :محمدصادق عباسیان
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
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
.3از یک حلقه ،همزمان برای گرفتن دادهها و توقف گرفتن دادهها استفاده تمرین )3فرمول زیر ،مقدار بار مجاز ( Lبر حسب پوند بر اینچ مربع) را برای یک
شود؛ به طوری که اگر عددی منفی به عنوان ورودی ،وارد شود ،عملیات ستون با ضریب الغری Sتعیین میکند.
خواندن دادهها متوقف گردد.
مثال )6مطابق شکل ،یک شیء 222پوندی ،از انتهای یک میلهی صلب افقی 8 {
( )
فوتی با وزن ناچیز آویزان شده است .میله توسط یک لوال به دیوار متصل شده و به
وسیلهی یک کابل 8فوتی که به نقطهای باالتر به دیوار متصل شده ،نگه داشته شده برنامه ای بنویسید که ضریب الغری یک ستون را از ورودی بگیرد و مقدار بار مجاز
19
جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل دوم (ساختارهای کنترلی) دانشگاه صنعت آب و برق (شهید عباسپور)
d
200 lb
√
به دست میآید که در آن Wوزن شیء LC ،طول کابل LP ،طول میله و dفاصله از
دیوار تا نقطهی اتصال کابل به میله است.
برنامهای بنویسید که میزان تنش در کابل را برای مقادیر مختلف dاز یک فوت تا
هفت فوت ،با گام 0.1فوت محاسبه و چاپ نماید .ضمنا برنامه باید تنش حداکثر بین
مقادیر محاسبه شده و مقدار dمتناظر با تنش حداکثر را پیدا کرده و چاپ نماید.
مثال )7یک کارخانهی قالبسازی در حال حاضر 222قالب در ماه تولید میکند و
به ازای هر قالب 322 ،دالر سود میبرد .مخارج ثابت این کارخانه که به مقدار تولید آن
بستگی ندارد 22222 ،دالر در ماه است .همچنین کارخانه ماهانه 2222دالر بابت تحقیق
و توسعه هزینه میکند .چنانچه کارخانه هزینهی تحقیق و توسعه را nبرابر نماید ،تولید
22
21
دانشگاه صنعت آب و برق (شهید عباسپور) تهیه و تنظیم :محمدصادق عباسیان
نکات: توجه :مثالها و تمارین این فصل بسیار مهم هستند و توصیه میکنم اگر هیچ کدام از
فصول این جزوه را مطالعه نمی کنید ،به هیچ عنوان از این فصل غافل نشوید .جزئیات به
به نحوهی بررسی فرمتها دقت کنید .در صورتی که به روش بررسی
کار رفته در این مثالها و تمارین مواردی هستند که به یقین در امتحان حائز اهمیت
فرمتها مسلط شوید ،مطمئنا در پیچیدهترین فرمتها هم دچار خطا نخواهید
خواهند بود.
شد .در مورد اول ،بهدلیل وجود 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
دانشگاه صنعت آب و برق (شهید عباسپور) تهیه و تنظیم :محمدصادق عباسیان
نمیشود. میشوند ،عینا در خروجی چاپ میشوند .ضمنا استفاده از فرمت 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
دانشگاه صنعت آب و برق (شهید عباسپور) تهیه و تنظیم :محمدصادق عباسیان
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
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
فرمت " "/استفاده کنید. در این صورت میتوان از دستور خواندن
در آخر بحث فرمتهای خواندن ،به این نکته اشاره میکنم که سعی کنید همیشه 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
)جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – فصل سوم (ورودی و خروجی) دانشگاه صنعت آب و برق (شهید عباسپور
35
دانشگاه صنعت آب و برق (شهید عباسپور) تهیه و تنظیم :محمدصادق عباسیان
-قیمت واحد (یک عدد 5رقمی بدون نقطهی اعشار که سه رقم اول آن قرار است برنامهای بنویسیم که مقادیر زمان ،دما ،فشار و حجم را از فایل ثبت اطالعات بخواند
قسمت صحیح و دو رقم آخر ،قسمت اعشاری آنرا تشکیل میدهد) در و همهی آنها را به شکل جدولی مانند جدول زیر نشان دهد.
-سقف موجودی کاالی مورد نظر در انبار در ستونهای 42تا 42 دقت کنید که:
36
37
دانشگاه صنعت آب و برق (شهید عباسپور) تهیه و تنظیم :محمدصادق عباسیان
البته از اشکال دیگر نیز میتوان برای اعالن آرایه استفاده کرد؛ ولی توصیه
فصل چهارم (آرایهها)
میشود از همین روش کلی (که بهترین روش هم هست) استفاده شود.
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
)دانشگاه صنعت آب و برق (شهید عباسپور محمدصادق عباسیان:تهیه و تنظیم
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
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
نکات:
)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
دانشگاه صنعت آب و برق (شهید عباسپور) تهیه و تنظیم :محمدصادق عباسیان
)o) A (: : E
)i) B (1 : 3 : 3, 1 : 3 : 2
.4به کمک یک آرایهی دیگر نیز میتوان یک زیرآرایه را مشخص
کرد .به مثال زیر دقت کنید.
)p) A (F
.2در صورتی که برای عنصر ابتدایی یا/و عنصر انتهایی عددی را در
یعنی مقادیر عناصر آرایهی Fبه عنوان اندیس عناصر آرایهی A نظر نگیریم و فقط از عالمت " ":استفاده کنیم ،ابتدا یا/و انتهای
در نظر گرفته میشوند! زیرآرایه ،به اول یا/و آخر خود آرایه محدود میشود .به مثالهای
در صورتی که به چهار نکتهی فوق تسلط کامل پیدا کنید ،دست شما در زیر دقت کنید.
مثال )5برنامهی زیر ،تعداد نامعلومی عدد را از روی یک فایل میخواند .در صورتی )k) A (: 5
که تعداد عددهای خوانده شده کوچکتر یا مساوی ده باشد آنها را از کوچک به
)l) A (2 : : 2
بزرگ مرتب مینماید و عددهای مرتب شده را در خروجی چاپ مینماید و در
صورتی که تعداد عددهای خوانده شده بیشتر از ده باشد ،پیغام خطای مناسبی چاپ )m) A (: : 3
شده و برنامه به اتمام میرسد.
Program Sort
Implicit None
! List of Parameters
46
)دانشگاه صنعت آب و برق (شهید عباسپور )جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها
47
دانشگاه صنعت آب و برق (شهید عباسپور) تهیه و تنظیم :محمدصادق عباسیان
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/
در اینجا هم بهتر است تا جایی که امکان دارد برای مقدار دهی از حلقه :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
)دانشگاه صنعت آب و برق (شهید عباسپور )جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها
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
)دانشگاه صنعت آب و برق (شهید عباسپور )جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – چهارم (آرایهها
در واقع به صورت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
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
.عناصر آن دارای مقدار قرینهی اندیس خود میباشد 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خروجی برنامهی زیر را به دقت بنویسید.
59
62
)دانشگاه صنعت آب و برق (شهید عباسپور محمدصادق عباسیان:تهیه و تنظیم
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
71
دانشگاه صنعت آب و برق (شهید عباسپور) جزوهی مبانی برنامهسازی کامپیوتر(فرترن) – پنجم (زیربرنامهها)
مراجع
] [1صالح ،محمود؛ فرترن 92برای رشتههای علوم و مهندسی ،انتشارات دانشگاه امامحسین
] [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