معرفی و تاريخچه فرترن


همانطور که در اغلب کتابهای مکانيک ديده ايد، در اغلب برنامه های مهندسی از اين زبان استفاده می گردد. زبان برنامه نويسی فرترن با وجود سادگی از قدرت و سرعت بالايی برخوردار است، بطوريکه می توان از آن برای نوشتن برنامه های CFD استفاده کرد. فرترن اغلب با قابليت فوق العاده در مورد اعداد معرفی می گردد و همانطور که از اسمش (FORmula TRANslation) پيداست، برای انجام محاسبات رياضی در کارهای علمی خلق شده است. در گذشته اين زبان دارای محدوديتهايی بوده که در نسخه های جديد اين مشکلات حل شده است و اين زبان به يک زبان بسيار قوی تبديل شده است. اغلب کتابخانه های لازم برای انجام انواع محاسبات در اين زبان وجود دارد. اين زبان در استاندارد فرترن 90 از قابليت نوشتن برنامه های محاسبات موازی برای کامپيوتر های چند پردازنده ای پشتيبانی می کند که آينده روشنی را برای محاسبات سنگين CFDنشان می دهد. اين زبان جزء اولين زبانهای خلق شده برای کامپيوتر می باشد که در IBM نوشته شده است. قابليت محاسبات سريع با سادگی در برنامه نويسی باعث محبوبيت آن بين مهندسان و دانشمندان شده است. زبان فرترن در حال حاضر دارای قابليت برنامه نويسی شيء گرا شده است.


معمولاً از فرترن 77 و 90 استفاده می گردد که نسخه 90 آن محبوبيت عمومی تری دارد. در اين متن از استاندارد های برنامه نويسی فرترن 90 استفاده می کنيم و در موارد لازم در مورد فرترن 77 هم بحث خواهيم کرد.


تاريخچه[2]


·1954 Fortran I


·1958 Fortran II


·1958 Fortran IV


·1966 Fortran 66 standard


·1978 Fortran 77 standard


·1991 Fortran 90 standard


·1996 Fortran 95 standard




چرا فرترن؟

زبان اصلی برنامه نويسی در کاربردهای علمی فرترن است. اغلب کدهای قديمی با اين زبان نوشته شده است. بنابراين لازم است که يک دانشجوی مهندسی با اين زبان آشنايی داشته باشد. سالها پيش به نظر می رسيد که با پيشرفت و محبوبيت عمومی زبانهايی مانند C زبان فرترن منسوخ گردد، اما با گذشت سالها اين زبان همچنان استفاده فراوان دارد. اين ماندگاری مديون کتابخانه ها و کدهای 40 ساله اين زبان است. در هر حال استانداردهای جديد اين زبان قدرت زيادی به اين زبان داده است. اين زبان همچنان بعنوان مهمترين زبان برای مهندسان و دانشمندان بشمار می آيد. فرترن برای انجام محاسبات رياضی با سرعت و قابليت بالا طراحی شده است. البته زبان فرترن هنوز در ايجاد محيط گرافيکی کمبود دارد و اگر بخواهيد برای فرترن يک رابط گرافيکی کاربر(Graphical User Interface) بنويسيد، بايد خود را درگير فراخوانی توابع ويندوز(API ها!) کنيد. انتخاب راحت تر استفاده از يک زبان ساده مانند Visual Basic يا Delphi برای ايجاد رابط گرافيکی کاربر است. در اين روش GUI را در اين زبانها می سازيم و موتور اصلی برنامه برای کار با معادلات و انجام محاسبات را در FORTRAN می نويسيم و بعد آنرا با فرمت DLL (Dynamic Link Library) در اختيار برنامه قرار می دهيم. اينکار را در مراحل پيشرفته تر آموزش (سطح متوسط) به شما آموزش خواهم داد.

برنامه Ansys که بين مهندسان مکانيک محبوبيت دارد با زبان فرترن نوشته شده است.



فرترن 90

فرترن 90 فراتر از يک ويرايش جديد از استاندارد فرترن می باشد و برنامه نويسی را بسيار آسانتر کرده است. اين ويرايش کدهای فرترن 77 را نيز پشتيبانی می کند. فرترن 90 يک زبان برنامه نويسی انعطاف پذير و قوی است, اين زبان امکانات برنامه نويسی شيء گرا را داراست. امکانات دسترسی به امکانات سيستمی مانند تخصيص حافظه, استفاده از اشاره گرها و بسياری امکانات ديگر به آن اضافه شده است؛ بعبارت ديگر فرترن 90 بيشتر شبيه به C++ است تا فرترن 77! ارتقاء قابليتهای عددی, استفاده از دستورات حالت موازی (چند پردازنده ای) که يک پيشرفت شايان ذکر در برنامه نويسی علمی و نوشتن کدهای موازی می باشد. اين روند در فرترن 95 دنبال شده است و انتظار می رود در ويرايش های جديدتر اين زبان امکانات گسترده تری برای برنامه نويسی علمی به اين زبان اضافه گردد.


برنامه Ansys که بين مهندسان مکانيک محبوبيت دارد با زبان فرترن نوشته شده است.

فرترن 90
فرترن 90 فراتر از يک ويرايش جديد از استاندارد فرترن می باشد و برنامه نويسی را بسيار آسانتر کرده است. اين ويرايش کدهای فرترن 77 را نيز پشتيبانی می کند. فرترن 90 يک زبان برنامه نويسی انعطاف پذير و قوی است, اين زبان امکانات برنامه نويسی شيء گرا را داراست. امکانات دسترسی به امکانات سيستمی مانند تخصيص حافظه, استفاده از اشاره گرها و بسياری امکانات ديگر به آن اضافه شده است؛ بعبارت ديگر فرترن 90 بيشتر شبيه به C++ است تا فرترن 77! ارتقاء قابليتهای عددی, استفاده از دستورات حالت موازی (چند پردازنده ای) که يک پيشرفت شايان ذکر در برنامه نويسی علمی و نوشتن کدهای موازی می باشد. اين روند در فرترن 95 دنبال شده است و انتظار می رود در ويرايش های جديدتر اين زبان امکانات گسترده تری برای برنامه نويسی علمی به اين زبان اضافه گردد.

مقدمه کار با Digital Visual Fortran
در اين بخش اطلاعات لازم جهت نوشتن برنامه در محيط Visual Fortran ارائه شده است. محيط Visual Fortranهمان محيط Visual StudioMicrosoftاست. اگر قبلاً تجربه کار با اين محيط را داريد می توانيد مطالب را از بخش بعدی ادامه دهيد.
برای نوشتن برنامه فرترن ابتدا يک پروژه می سازيم. مراحل زير را دنبال کنيد. ساده ترين راه برای اين کار استفاده از منوی فايل است. از منوی اصلی File و New را انتخاب کنيد.
1- File > New
از صفحه نمايش داده شده ، برگه Projects را انتخاب کنيد. در اين برگه آيکون (Icon), Fortran Consol Applicationرا انتخاب کنيد. فراموش نکنيد برای پروژه در قسمت Project Name، يک نام انتخاب کنيد.
2- Project(tab) > Fortran Consol Application
این تصویر تغییر سایز داده شده است. اینجا را کلیک کنید تا با سایز اصلی آنرا مشاهده کنید. سایر اصلی این تصویر 564در 410 و حجم آن 53KB.
روی OKکليک کنيد. صفحه ای که نوع پروژه را از شما می پرسد، ظاهر می گردد؛ روی Finish کليک کنيد تا برنامه شما ايجاد شود. صفحه ای شامل اطلاعات پروژه شما نمايش داده خواهد شد؛ روی OKکليک کنيد. پروژه شما ايجاد شده است. اما اين پروژه خالی است. حالا بايد برنامه اصلی را به اين پروژه اضافه کنيم.
برای اضافه کردن فايل برنامه فرترن به اين پروژه دوباره از منوی اصلی استفاده می کنيم.
3- File > New
برگه Files را انتخاب کنيد. در اين برگه آيکون Fortran Free Format Source Fileرا انتخاب کنيد (اين قالب استاندارد فرترن 90 می باشد) . فراموش نکنيد برای اين فايل در قسمت File Name، يک نام انتخاب کنيد. تا حد ممکن نام فايلها را با دقت انتخاب کنيد تا در آينده با خواندن نام فايل بتوانيد به محتوای آن پی ببريد. همچنين توجه کنيد که چک باکس Add to project تيک خورده باشد.
4- Files(tab) > Fortran Free Format Source File


روی کليد OKکليک کنيد. فايل برنامه شما ساخته شده است. حال نوبت به نوشتن اولين برنامه فرترن می رسد. لطفاً برنامه زير را در اين فايل بنويسيد.
PROGRAM hello_fortran
! This is comment in fortran file
CHARACTER::A
WRITE(*,*) 'Hello dear user, Fortran is so easy'
READ(*,*) A
END PROGRAM hello_fortran
فايل را ذخيره کنيد(File > Save or CTRL+S).
برای اجرای اين برنامه ابتدا آنرا ترجمه (Compile) می کنيم. برای اينکار از منو اصلی Build > Build Hello.exeرا انتخاب می کنيم يا کليد F7 را می زنيم. اگر خطايی در برنامه وجود داشته باشد، تعداد و منبع خطا در پنجره زيرين نمايش داده خواهد شد. با دابل-کليک روی خطا، منبع خطا در برنامه نشان داده خواهد شد. اگر خطايی وجود نداشته باشد. برنامه ترجمه شده و فايل اجرايی hello.exe ساخته می شود. و در پنجره وضعيت پيامی به شکل زير نمايش داده می شود.
Hello.exe - 0 error(s), 0 warning(s)
برای اجرای برنامه می توانيد به محل ذخيره برنامه رفته در پوشه Debug برنامه اجرايی را يافته و اجرا کنيد يا کليد F5 را بزنيد. يا از آيکون go استفاده کنيد (اين آيکون شبيه يک برک کاغذ است که در سمت راست آن يک فلش رو به پايين وجود دارد).

استانداردهای کد نويسی
برای سازگاری و خوانايی بيشتر در برنامه نويسی بهتر است که قوانين زير را رعايت کنيد.
1-همة کلمات کليدی اين زبان را با حروف بزرگ و همه چيز ديگر را با حروف کوچک بنويسيد (اين زبان بين حروف کوچک و بزرگ فرقی نمی داند!). البته اين ساختار آنچنان مناسب نمی باشد و می تواند خوانايی برنامه را کاهش دهد و دليل استفاده از آن قدمت اين روش است. در هر حال استفاده از اين روش در برنامه نويسی مدرن کار درستی نيست.
2-از دندانه دار کردن در متن اصلی برنامه و همچنين بلوکهای ديگر استفاده کنيد.
3-اسم برنامه ها، زير برنامه ها و توابع را در انتهای آنها ذکر کنيد.

ساختار برنامه فرترن
ساختار برنامه در فرترن 90 به ساختار زبانهای برنامه نويسی ديگر شباهت زيادی دارد و به شکل زير است.
PROGRAM program_name
! Comment and program information
Declaration of variables and/or external functions
Program body
END PROGRAM program_name
Declaration and body of user-made functions
مثال ساده ای از اين ساختار را در بخش قبلی ديده ايد. ساختار برنامه در فرترن 77 کمی متفاوت و پيچيده تر است! در فرترن 77، کل صفحه به ستونهايی تقسيم می گردد و هر بخش از برنامه محل مشخصی دارد. برنامه فرترن 77 بايد از قوانين زير پيروی کند:

  • تمام دستورات فرترن بايد بين ستون 7 تا 72 از فايل قرار داشته باشند.
  • فاصله خالی برای مترجم برنامه معنايی ندارد ولی برای خوانايی برنامه بايد از آنها استفاده کرد!
  • دستوراتی که در ستون 1 تا 5 آنها خالی است اما در ستون 6 کاراکتری غير از صفر قرار دارد به عنوان ادامه دستورات خط قبل به حساب می آيند (حداکثر تا 19 خط مجاز است!).
  • شماره خط دستورات بايد بين ستون 1 تا 5 نوشته شوند و حداکثر می تواند يک عدد 5 رقمی باشد (فرترن به شماره خط نيازی ندارد و فقط برای ارجاع از دستوراتی مانند GOTO استفاده می گردد.
  • توضيحات برنامه در ستون اول خود C دارند.
  • خوب است که حداکثر با دو دندانه در برنامه بخشهای مختلف را مشخص کنيد.

با توجه به توضيحات بالا ساختار برنامه فرترن 77 به شکل زير است.
PROGRAM program_name
C Comment and program information
Declare of variables and/or external functions
Body of program
END PROGRAM program_name
Declaration an body of user-made functions
می توان مثال قبل را برای فرترن 77 به شکل زير نوشت:
PROGRAM hello_fortran
C This is comment in fortran file
CHARACTER::A
WRITE(*,*) 'Hello dear user, Fortran is so easy'
READ(*,*) A
END PROGRAM hello_fortran
متغيرها
پيشنهاد می گردد که همة متغيرهای برنامه در ابتدای برنامه تعريف (تعيين نوع) گردند. برای اينکه هيچ متغيری از قلم نيفتد، از دستور IMPLICIT NONE در ابتدای برنامه استفاده کنيد. اين دستور به مترجم برنامه خواهد گفت که اگر در برنامه به متغير تعريف نشده ای برخورد، اعلام خطا کند. البته فرترن به تعيين نوع نيازی ندارد! اما اين کار خطاهای برنامه نويسی شما را کاهش خواند داد. زبانهای برنامه نويسی زيادی در اولين استفاده از متغير برای آن متغير نوعی در نظر می گيرند و نيازی نيست که برنامه نويس نوع متغيرها را مشخص کند زبان فرترن نيز چنين است. تعريف متغير توسط برنامه نويس يا مترجم برنامه در برنامه نويسی حرفه ای برای مدت زيادی مورد بحث بود تا اينکه ناسا يکی از سنسورهای سفينه فضايی ونوس را بعلت يک تعريف متغير اشتباه توسط مترجم برنامه (مترجم نوع ديگری را برای متغير در نظر گرفته بود) از دست داد. بنابراين تعريف متغير توسط برنامه نويس بعنوان يک روش مناسب انتخاب شد. خوشبختانه در بسياری از زبانهای برنامه نويسی مدرن تعريف متغير توسط برنامه نويس اجباری است. فرترن برای داشتن سازگاری از تعريف داخلی متغير توسط مترجم پشتيبانی می کند.

نام گذاری متغيرها
قوانين نامگذاری متغيرها :

  • حداکثر طول نام متغيرها 34 کاراکتر است.
  • فقط امکان استفاده از حروف کوچک و بزرگ انگليسی(a...zA...Z,)، اعداد(0,1,..,9) و کاراکتر زير-خط ( _ ) وجود دارد.
  • توجه داشته باشيد که بزرگی يا کوچکی حروف برای فرترن فرقی ندارد.
  • اولين کاراکتر يک اسم بايد حرف باشد.
  • از کلمات کليدی در نامگذاری استفاده نکنيد.

انواع داده ها
شما در برنامه متغيرها را برای انواع مختلفی از داده ها بکار می بريد. انواعی از داده ها که در فرترن 77 پيشتيبانی می گردند به شرح زير است:

  • نوع INTEGER برای اعداد صحيح
  • نوع REAL برای اعداد اعشاری (تقريباً 8 رقم)
  • نوع DOUBLE برای اعداد اعشاری با دقت بيشتر (تقريباً 16 رقم معنی دار) [اين اعداد را مضاعف می ناميم]
  • نوع CHARACTER برای يک کاراکتر يا رشته ای از کاراکترها
  • نوع LOGICAL برای مقادير منطقی
  • نوع COMPLEX برای اعداد مختلط به عنوان يک جفت با دقت REAL، اغلب توابع فرترن 77 بر روی اعداد مختلط قابل استفاده هستند.

ثابت های هم به همين شکل بکار می روند مثلاً 1234 يک عدد ثابت صحيح است، 1234.0 يا 1.234E3 يک ثابت اعشار و 1.234D3 عدد اعشار با دقت مضاعف است. اعداد مختلط به شکل (3.14,-1E5) نمايش داده می شوند و کاراکترها بين دو کوتيشن قرار می گيرند ‘AbBa’يا ‘S’. ثابتهای منطقی فقط می توانند دو مقدار .TRUE. و .FALSE.را داشته باشند (به نقاط ابتدايی و انتهايی هر يک توجه کنيد).
اگر اعداد بسيار کوچک يا بسيار بزرگ باشند، ممکن است سيستم آنها را صفر در نظر گرفته و مشکل تقسيم بر صفر در محاسبات پيش آيد يا اينکه سيستم دچار سر ريز گردد. اين خطاها بسيار رايج هستند و اشکال گزارش شده به سيستم بستگی خواهد داشت.

تعريف متغيرها
برای تخصيص حافظه لازم به متغيرها، مترجم برنامه (Compiler) بايد نام، نوع و اندازه هر متغير را بداند. اگر از دستور IMPILICIT NONE استفاده گردد، لازم است که تمام متغيرها تعريف گردند. در غير اينصورت نوع متغير با حرف اول آن مشخص می گردد.
·a..h وo..z برای متغيرهای اعشار
·i,j,k,l,m,n برای متغيرهای صحيح
تعريف متغير با دستور زير صورت می گيرد (اين تعريف در برنامه نويسی بسيار پسنديده است):
Variable_type::variable_name [=initial value] REAL:: alpha, beta, c=10.0
INTEGER:: count, hours, minutes=36
اگر بخواهيد مقدار ثابتی را تعريف کنيد از دستور PARAMETER استفاده می گردد
PARAMETER ({list of names=value}) PARAMETER (pi=3.141592)
عبارات ساده
عبارات و عمليات محاسباتی
عملگرهايی مانند + ، - ، / (همان ÷ است) و * (همان × است) را می شناسيد. عملگر توان در فرترن به شکل ** است. اولويت محاسبه در عبارات

  • پرانتز – اگر در عبارات، پرانتز وجود داشته باشد. اول داخلی ترين پرانتز محاسبه خواهد شد و به همين ترتيب عبارات داخل پرانتز اولويت اول را دارند.
  • توان
  • ضرب و تقسيم
  • جمع و منها

A*B**n-C/D و (A*(B**n)-(C/D برای مثال عبارت و يکسان هستند.
اگر دو عبارت از اولويت يکسانی برخوردار باشند، محاسبه از چپ به راست خواهد بود. برای مثال عبارت و يکسان هستند. لازم است بدانيد که حاصل عمليات بين دو اعشار، اعشار است و حاصل عمليات بين دو عدد صحيح، عدد صحيح است؛ حاصل عمليات بين عدد اعشار و عدد صحيح، عدد اعشار است. به عنوان مثال حاصل 1/5 برابر 0 صحيح است، حاصل1./5. برابر 0.2اعشار است و حاصل 1d0/1d5 برابر 0.2 مضاعف است. بطور کلی می توان گفت که در محاسبه عبارات اگر تبديل نوع لازم باشد، متغيرها به متغير با بالاترين دقت تبديل می گردند. در استفاده از اعداد دقت کنيد، عدد 4 صحيح است، عدد 4. اعشار و عدد 4d0 مضاعف است.
برابر قرار دادن مقدار يک متغير با يک عبارت يکی از ساده ترين عبارات هر زبان برنامه نويسی است.
variable = expression
برای مثال عبارت رياضی در فرترن بصورت نوشته می شود و کامپيوتر بعد از محاسبه عبارت سمت راست، مقدار آنرا در متغير aقرار می دهد. کاربرد پرانتز در عبارات رياضی به خوانايی بيشتر برنامه و جلوگيری از اشتباه کمک می کند.

مقايسه متغيرها
مقايسه متغيرها به کامپيوتر قدرت تصميم گيری داده است. متأسفانه فرترن 77 از عباراتی مانند <, > و ... را به اين شکل پشتيبانی نمی کند و بجای آنها مقايسه را با عباراتی چون .EQ.انجام می دهد.
.EQ. equal to
.GE. greater or equal to
.GT. greater than
.LE. less than or equal to
.LT. less than
.NE. not equal to
اين مشکل در فرترن 90 حل شده است و فرترن 90 علامتهای <، >، >=، <=، == و <> را هم پشتيبانی می کند. برای مثال عبارت (A .EQ. B) معادل (A==B) و يک عبارت منطقی است، اين عبارت در صورتی صحيح است که مقدار متغيرها با هم برابر باشد. در هر حال حاصل يک عبارت مقايسه ای يک مقدار منطقی خواهد بود که می تواند درست يا اشتباه باشد.

عبارات منطقی
دستورات منطقی اين زبان عبارتند از:
.NOT. logical negative
.AND. logical and
.OR. logical or
.EQV. logical equivalence
.NEQV. logical non-equivalence (exclusive or)
T: TRUE, F:FALSE
x
y
.NOT. x
x .AND. y
x .OR. y
x .EQV. y
x .NEQV. y
F
F
T
F
F
T
F
T
F
F
F
T
F
T
F
T
T
F
T
F
T
T
T
F
T
T
T
F

کاراکتر و رشته
در فرترن 77 رشته ها بايد اندازه ای ثابت و از پيش تعيين شده داشته باشند. تعريف رشته در فرترن 77 به اين شکل است:
CHARACTER name*length
همچنين می توان آرايه ای از رشته ها تعريف کرد:
CHARACTER array (size)*length
برای نوشتن رشته های ثابت تعداد لازم نيست و بجای آن از*استفاده می گردد.
CHARACTER format_scope*(*)
PARAMETER(format_scope=’this is constant character!’)

دو عمليات ساده با رشته های کاراکتری در فرترن 77 عبارتند از استخراج بخشی از رشته يا پيوند دو رشته به يکديگر. استخراج بخشی از رشته با قرار دادن علامت : بين شروع و پايان بخش مورد نظر صورت می گيرد. برای ترکيب رشته ها از علامت // استفاده می گردد.
substring= string(start position: end position)
برای کاراکترهای شروع و پايان, می توان عدد شروع يا پايان را ننوشت.
CHARACTER first_word*8, second_word*5, third_word*20
first_word=’FORTRAN’
second_word=first_word(:3)
third_word=second_word // first_word(4:)
متغير third_word پس از اجرای اين دستورات برابر رشته کاراکتری FORTRAN خواهد بود( فاصله بعلت اندازه متغير second_word است).

توابع رشته ای
در توابع داخلی فرترن، توابع رشته ای نيز وجود دارد. برای مثال تابع LEN اندازه رشته می دهد، توابع CHAR و ICHAR بترتيب برای تبديل عدد صحيح به کاراکتر و تبديل کاراکتر به عدد صحيح به کار می روند. INDEX برای يافتن يک رشته در رشته ديگر کاربرد دارد. توابع مقايسه رشته ها مانند LGE، LGT، LLE و LLT و بسيارس از توابع ديگر وجود دارند که در صورت نياز امکان مطالعه آنها را خواهيد داشت.

ورودی و خروجی
در اغلب برنامه ها نياز داريم که اطلاعات ورودی را از صفحه کليد يا فايل بخوانيم و اطلاعات خروجی را در صفحه نمايش نشان دهيم يا آنها را در فايل خروجی ذخيره کنيم.
دستور READ
اين دستور برای دريافت ورودی از صفحه کليد بکار می رود و ساختار آن به شکل زير است.
READ *, {input list} or
RAED([UNIT=] unit type, [FMT=] format) {input list}
unit type عددی است که نوع ورودی را مشخص می کند، مثلاً 5 برای صفحه کليد، اين عدد اغلب برای خواندن ورودی از فايل بکار می رود. format برای دريافت ورودی معمولاً * است، اما کاربرد اصلی آن برای خواندن ورودی فرمت شده از فايل است.
READ (*,*) a,b,c
دستورWRITE
اين دستور برای نمايش خروجی در صفحه نمايش يا فرستادن خروجی به پرينتر يا فايل خروجی بکار می رود.
PRINT *,{output list}
WRITE([UNIT=] unit type, [FMT=] format) {output list}
مانند دستور READ، unit typeنوع خروجی را مشخص می کند و format فرمت خروجی را تعيين می کند.
WRITE(*,*) ‘The total is:’, total
اين دستور ابتدا رشته The total is: و در ادامه مقدار متغيرtotalرا روی صفحه نمايش نشان خواهد داد.
تعيين قالب ورودی و خروجی - دستور FORMAT
اين دستور قالب بندی داده را تعيين می کند و در دستورات ورودی و خروجی بکار می رود. اين دستور به دو صورت به کار می رود. يک روش استفاده مستقيم اين دستور در بخش format در دستورات ورودی و خروجی است. روش دوم قرار دادن يک شماره خط قبل از اين دستور (شماره خط در فرترن 77 بين خط 1 تا 5 قرار می گيرد.) و ارجاع اين شماره در دستورات ورودی و خروجی است. ساختار اين دستور به شکل زير است.
FORMAT (format sequence)
يا اگر داخل دستوراتی چون WRITE قرار گيرد به شکل زير خواهد بود.
FMT= (‘format sequence’)
ساختار استفاده شده در اين دستور مشخص کننده تعداد ارقام خروجی و شکل نمايش آنهاست.
همانطور که در مثالهای قبلی متوجه شده ايد؛ اگر قالب بندی آزاد انتخاب گردد، می توان بجای اين بخش در دستورات ورودی و خروجی از * استفاده کرد.
ترتيب قالب بندی format sequence
برای مشخص کردن قالب بندی در دستور FORMAT، قالب هر متغير بايد مشخص گردد. اين قالب بندی شامل نوع متغير و تعداد ارقام آن و نوع نمايش ارقام می باشد.
Data description
Data type
Iw, Iw.m
Integer
Ew.d, Ew.dEe, Fw.d,Gw.d, Gw.dEe
Floating Point
Lw
Logical
A, Aw
Character
در اين جدول حروف بزرگ مشخص کننده نوع متغير هستند:
I :
متغير صحيح
F :
متغير اعشار با اعشار مشخص
E :
نمايش علمی عدد اعشار
G :
مانند F، به دقت عدد بستگی دارد
L :
متغير منطقی
A:
متغير کاراکتری!
و حروف کوچک قالب متغير را مشخص می کنند
w:
تعداد کل ارقام
m:
حداقل تعداد ارقامی که بايد نمايش داده شود
d:
تعداد ارقام بعد از مميز (دقت)
e:
تعداد ارقام توان
تعدادی از کاراکترهای کنترلی که کاربرد بيشتری دارند
/
انتفال به خط بعدی
‘Any string’
رشته ای را به خروجی انتقال می دهد
nX
مکان نما را n خانه به راست هدايت می کند
برای مثال:
WRITE(UNIT=*,FMT=10) 'The frequency is', f, 'Hz'
10FORMAT(1X, A, F10.5, A(
ابتئا مکان نما يک خانه به راست حرکت می کند، رشته کاراکتری نمايش داده می سود، مقدار متغير f با حداکثر 15 رقم و با دقت 5 رقم اعشار نمايش داده شده و دوباره رشته کاراکتر چاپ می گردد. می توان از کلمات کليدی UNIT و FMT صرفنظر کرد و فقط مقدار آنها را نوشت.
WRITE(*,10) 'The frequency is', f, 'Hz'
10FORMAT(1X, A, F10.5, A(
مثال برنامه نويسی:
شايد از آموختن تئوری کمی خسته شده باشيد، حال وقت آن است که آنچه را که آموخته ايم استفاده کنيم. می خواهيم برنامه ای بنويسيم که ريشه های حقيقی يک معادله درجه 2 را پيدا کند. ضرايب معادله درجه 2 را از ورودی خواهيم خواند.

  • رياضيات مسئله:

می دانيم که هر معادله درجه 2 به شکل دارای دو ريشه است. در صورتی اين ريشه ها حقيقی هستند که باشد. در اينصورت ريشه های حقيقی معادله از رابطه زير بدست می آيند.

  • دياگرام برنامه:
    • شروع
    • ضرايب ورودی معادله را بخوان
    • دلتا را محاسبه کن
    • اگر دلتا بزرگتر يا مساوی صفر است


4-1. ريشه ها را محاسبه کن
4-2. ريشه ها را چاپ کن
_ در غير اينصورت
4-3. چاپ کن "معادله ريشه حقيقی ندارد"


    • پايان




  • برنامه:

PROGRAM Equation_solver_fortran
!This is program calculate the real roots of second order equation
IMPLICIT NONE ! this is important to get used to this statment
! Variable decleration
CHARACTER::end_key
REAL::a,b,c
REAL::Delta, x1, x2
! Main Porgram
WRITE(*,*) ‘Please enter the equation coefficients a*x^2+b*x+c’
WRITE(*,*) ‘a: ?’
READ(*,*) a
WRITE(*,*) ‘b: ?’
READ(*,*) b
WRITE(*,*) ‘c: ?’
READ(*,*) c

Delta=b**2-4*a*c
IF (Delta >= 0) THEN
x1=(b+SQRT(Delta))/(2*a)
x2=(b-SQRT(Delta))/(2*a)
WRITE(*,*) ‘ The real roots are : ‘, x1, x2
ELSE
WRITE(*,*) ‘ This equation has no real root!’
ENDIF
READ(*,*) end_key
END PROGRAM Equation_solver_fortran
اگر در نوشتن برنامه اشتباهی نکرده باشيد، برنامه اجرا خواهد شد. تبريک می گويم، شما اولين برنامه مهندسی خود را نوشته ايد. در خواندن برنامه بالا نبايد مشکلی داشته باشيد. فقط ممکن است ساختار IF..THEN..ELSEو تابع SQRT() برايتان تازگی داشته باشد و همانطور که حدس زده ايد، ساختار IF..THEN..ELSEساختار تصميم گيری و تابع SQRT() تابع جذر می باشد که در بخشهای بعدی در مورد آن بحث خواهيم کرد.
برنامه نويسی شما فقط محدود به تفکر شما در مورد برنامه هاست. هر آنچه که فکر کنيد را می توانيد بنويسيد. حتی برنامه های پيچيده هوش مصنوعی نيز با همين دستورات ساده قابل نوشتن است. در هر حال اگر بدانيد چه می خواهيد برنامه نويسی بسيار لذت بخش خواهد بود. آموختن يک زبان برنامه نويسی مانند يادگرفتن استفاده از يک ابزار است. هر چه ابزار قويتری داشته باشيد کارها ساده تر انجام خواهد گرفت، زبان فرترن يک ابزار برنامه نويسی مهندسی بسيار کارآمد است.

ورودی و خروجی فايل
کار کردن با فايلها در فرترن بسيار ساده است. ورودی وخروجی فايل هم مانند ورودی از صفحه کليد يا خروجی به نمايشگر با دستور READ و WRITE صورت می گيرد. در اين حالت بخش UNIT در اين دستورات مشخص کننده نوع ورودی و خروجی است. برای ورودی از صفحه کليد و خروجی به صفحه نمايش، بخش UNIT در اين دستورات برابر * قرار می گيرد. برای ورودی و خروجی از فايل، ابتدا فايل را باز می کنيم، اين کار يک عدد (UNIT) به فايل اختصاص می دهد.

دستور OPEN
اين دستور يک فايل را باز می کند و يک عدد به فايل اختصاص می دهد. اين امکان وجود دارد که فايل را ايجاد کرد. ساختار اين دستور به اين شکل است:
OPEN(UNIT= number, FILE= ’Name of file’, STATUS= status, ACCESS= access…)
number عددی است که شما به فايل اختصاص می دهيد (اين عدد را بين 0 تا 255 انتخاب کنيد – يعنی شما می توانيد با خيال راحت تا 255 فايل مجزا را باز کنيد!)، اين عدد شناسه فايل است.
status وضعيت فايل را مشخص می کند و می تواند برای ايجاد فايل جديد ‘NEW’ باشد، يا ‘OLD’برای باز کردن فايل موجود و اگر مطمئن نيستيد ‘UNKNOWN’ بکار می رود و ‘SCRATCH’ برای ايجاد فايلهای موقت که با پايان برنامه يا بسته شدن فايل، فايل از بين می رود! وضعيت ‘REPLACE’ برای جايگزاری فايل جديد است. اگر فايل موجود باشد، پاک شده و فايل جديد جايگزين آن می گردد و اگر فايل موجود نباشد، فايل جديد ايجاد می گردد.
access نوع دسترسی به فايل را مشخص می کند که ممکن است، ‘DIRECT’ يا ‘SEQUENTAL’ باشد. نوع دسترسی به فايل بسيار مهم است، اما دسترسی ترتيبی ‘SEQUENTAL’ بسيار ساده است. در اين فايلها داده ها بترتيب خط به خط خوانده و نوشته می شوند. پيش فرض دسترسی ترتيبی است.

دستور CLOSE
پيشنهاد می گردد بعد از پايان کار با فايل آنرا ببنديد. ساختار اين دستور به شکل زير است:
CLOSE (UNIT= unit, STATUS = status…)
unit شماره شناسه فايل است وstatus وضعيت بستن می تواند ‘KEEP’ برای حفظ فايل و ‘DELETE’ برای حذف فايل است. پيش فرض حذف فايل است.

توابع و زيربرنامه ها
توابع داخلی Intrinsic Functions
هر مترجم برنامه فرترن کتابخانه ای از توابع داخلی دارد. بعضی از مهمترين اين توابع به شرح زير هستند.
توابع مثلثاتی: SIN, COS, ASIN, ACOS, TAN, ATAN, COTAN
توابع رياضی: قدرمطلق ABS، جذر SQRT، لگاريتم LOG, LOG10، تابع نمايی EXP، حداقل و حداکثر MIN,MAX، باقيمانده تقسيم MOD و...
توابع ماتريسی: DOT_PRODUCT, MATMUL, TRANSPOSE,…
توابع بسيار زياد ديگری نيز وجود دارد؛ همچنين ممکن است که مترجم شما توابع بيشتری از توابع استاندارد در اختيار شما قرار دهد. در هر حال اگر احتياج به تابعی داشتيد، قبل از اينکه خودتان به فکر نوشتن آن باشيد مطمئن شويد که آن تابع وجود ندارد!!
بعضی از اين توابع انواع داده ها را بعنوان ورودی خود می پذيرند البته اگر چند ورودی وجود داشته باشد همه بايد از يک نوع باشند، بعضی از اين توابع نيز نوع مشخصی را پشتيبانی می کنند. بعضی از مترجم ها مانند Digital Visual Fortranبرای مشخص کردن نوع داده ورودی و خروجی از پيشوند و پسوند برای توابع استفاده می کند (برای جزئيات به help نرم افزار خود مراجعه نماييد.).
فراخوانی توابع مانند اختصاص يک مقدار به متغير می باشد.
Result_variable = function_name({list of parameters})
برای مثال:
a= sin(b)
b متغيری است که به تابع ارسال می گردد و a حاصل تابع سينوس خواهد بود!

زيربرنامه های داخلی Intrinsic Subroutines
فرق تابع و زير برنامه در تعداد متغيرهای بازگشتی آنهاست. البته اين تنها فرق آنها نيست! تابع يک متغير بازگشتی دارد درحاليکه زير برنامه می تواند بيش از يک مقدار را برگرداند. تابع يک مقدار را بر می گردانند اما حق تغيير متغيرهای ورودی را ندارند. زير برنامه ها مقدار بازگشتی ندارند، در عوض امکان تغيير متغيرهای خود را دارند. زيربرنامه ها با دستور CALL به شکل زير فراخوانی می شوند.
CALL subroutine_name({list of variables})
بعضی از زيربرنامه های داخلی عبارتند از:
DATE_AND_TIME, MVBITS, RANDOM_NUMBER, RANDOM_SEED, SYSTEM_CLOCK

توابع خارجی External Functions
شما می توانيد خودتان توابع را بنويسيد. معمولاً بعد از پايان برنامه می توانيد توابع خودتان را اضافه کنيد. ساختار تابع به شکل زير است:
type FUNCTION name ({dummy arguments})
local variable declaration
body of function…
name = expression
body of function continued if needed
END FUNCTION name
type نوع تابع (نوع حاصل تابع) را مشخص می کند. حاصل تابع مقداری است که توسط تابع بازگردانده می شود. اگر به ساختار بالا توجه کنيد دقيقاً جايی که نام تابع برابر يک عبارت قرار گرفته، حاصل تابع است. تابع بايد حداقل يک مقدار خروجی داشته باشد. يعنی در جايی از تابع، مقداری به "نام" تابع اختصاص داده شود.
متغيرهای ظاهری dummyarguments، شامل همة ثابت ها، متغيرها و حتی روالهاي1 قابل دسترسی در بدنه تابع است. (منظور از روالها، توابع و زيربرنامه ها هستند). وقتی تابع فراخوانی می گردد بايد ليستی از اين متغيرها به آن فرستاده شود. نوع اين متغيرهای واقعی بايد با متغيرهای ظاهری موجود در تعريف تابع يکسان باشد، اما نام آنها مهم نيست. نوع متغيرها در هنگام ارسال به توابع توسط مترجم برنامه کنترل نمی گردد و اگر نوع متغيرهای يکسان نباشد با اشکالات عجيبی روبرو خواهيد شد!
بعنوان مثال برای محاسبه نيروی جاذبه بين دو جسم با استفاده از فرمول نيوتن، تابع نيوتن را به شکل زير تعريف می کنيم.
REAL FUNCTION Newton (m1, m2, r)
REAL:: gamma = 6.672E-11, m1, m2, r
Newton = -gamma*m1*m2/r**2
END Newton
توابع يک خطی Statement Functions
وقتی توابعی که بکار می بريد، آنچنان کوتاه هستند که در يک خط تمام می شوند، می توانيد از اين ساختار استفاده کنيد.
Function_name({list of parameters}) = expression
مثلاً تابع نيوتن که در بالا تعريف شد را می توان با اين ساختار به شکل زير نوشت.
Newton(m1, m2, r) = -6.672E-11*m1*m2/r**2

زيربرنامه های خارجی External Subroutines
ساختار زير برنامه ها به شکل زير است.
SUBROUTINE name {dummy argument list}
local variables declaration
body of subroutine…
END SUBROUTINE name
تمام متغيرها با آدرس فرستاده می شوند “call by reference” (مانند VAR arg در Pascal يا &arg در C++)، يعنی آدرس متغير در حافظه به زيربرنامه فرستاده می شود، و زيربرنامه می تواند متغير را مستقيماً تغيير دهد. در توابع نيز چنين است، اما فرض می گردد که توابع متغيرهای ورودی را تغيير نمی دهند.

دستورات RETURN, SAVE, EXTERNAL, INTERNAL
همة روالهای خوب بايد يک نقطه ورود و يک نقطه خروج داشته باشند، اما گاهی لازم است که زيربرنامه در نقطه ای ديگر پايان يابد (برای مثال هنگام ايجاد خطا). برای اينکار از دستور RETURN استفاده می گردد. اين دستور اجرای زير برنامه را متوقف کرده و برنامه را به روال فراخوانی کننده اين زير برنامه باز می گرداند.
پس از پايان يک زيربرنامه، مقدار همة متغيرهای محلی از بين می رود. اگر بخواهيم اين مقادير در اجرای بعدی زيربرنامه موجود باشد(STATIC ALLOCATION)، بايد اين موضوع را برای مترجم مشخص کنيم تا مترجم بداند که بايد مقدار متغيرها را ذخيره کند. اين موضوع را با دستورSAVE به مترجم اصلاع می دهيم. ساختار اين دستور به اين شکل است:
SAVE [{list of local variables to be saved}]
وقتی يک تابع بعنوان متغير به يک روال ديگر فرستاده می شود، نوع تابع بايد قبل از ارسال بعنوان داخلی يا خارجی تعريف گردد. اين تعريف با دستورات زير صورت می گيرد.
INTRINSIC {list of function names}
EXTERNAL {list of function names}
برای مثال
PROGRAM func
EXTERNAL CTN
INTRINSIC SIN, COS

REAL::angle=0.785 !...pi/4
REAL::sine,cosine,tangent

CALL TRIG(angle,SIN,sine)
WRITE(*,*) 'SIN(0.785)=',sine

CALL TRIG(angle,COS,cosine)
WRITE(*,*) 'COS(0.785)=',cosine

CALL TRIG(angle,CTN,cotangent)
WRITE(*,*) 'COTAN(0.785)=',cotangent

READ*,r
END PROGRAM func

SUBROUTINE TRIG(X,F,Y)
Y = F(X)
RETURN
END SUBROUTINE TRIG

FUNCTION CTN(X)
CTN = COS(X)/SIN(X)
RETURN
END FUNCTION CTN
ساختارهای کنترلی
ساختارهای کنترلی جهت اجرای برنامه را کنترل می کنند.
ساختار IF
اين ساختار يک ساختار تصميم گيری است. در اين ساختار بنابر حاصل يک مقايسه اجرای برنامه به جای ديگری منتقل می شود. ساختار عمومی آن به شکل زير است.
IF (First condition statement) THEN
First sequence of commands
ELSE IF (Second condition statement) THEN
Second sequence of commands
ELSE IF …

ELSE
Alternative sequence of commands
END IF
برای مثال برای يافتن علامت يک عدد می توان از بخش زير استفاده کرد:
IF (number .LT. 0) THEN
sign=-1
ELSE IF (number .GT. 0) THEN
sign=1
ELSE
sign=0
END IF
می توان برای اجرای يک IF با يک دستور، آنرا در يک خط خلاصه کرد. در اين حالت از THEN ، ELSE و END IF صرفنظر می شود.
IF (Condition statement) Statement to be executed
IF (r==0) WRITE(*,*) 'r=0'

حلقه Do
اين حلقه برای تکرار بخشی از برنامه است. چون استفاده از حلقه GOTO در برنامه نويسی پيشرفته بسيار بد است (گفته می شود که امکان اشتباه اين دستور بسيار زياد است). در هر حال جالب نيست که در هنگام اجرای برنامه به بخش ديگری پرش کرد، حداقل اينکار خوانايی برنامه را بسيار کاهش خواهد داد.
ساختار دستوری استفاده از حلقه DO به شکل زير است:
label: DO counter=start, limit, step
Sequence of commands to be looped through
END DO label
برای پياده سازی حلقه های ديگر مثل حلقه for و while در زبان C می توان از دستورات زير استفاده کرد.
دستور EXIT برای خروج از اجرای حلقه و دستور CYCLE برای تکرار حلقه از ابتدا می باشد. برای استفاده از اين دستورات بايد برای حلقه ها برچسب (label) در نظر گرفت اين کار را با دقت بسيار زياد انجام دهيد زيرا اينکار نيز مانند استفاده از دستور GOTO است! ساختار اين دستورات به شکل زير است:
EXIT [name of loop]
CYCLE [name of loop]
پيشنهاد می کنم تا جای ممکن از اين دستورات استفاده نکنيد، چون شما می توانيد بجای استفاده از اين دستورات با تغييراتی در کد برنامه را به شکل ديگری بنويسيد. به مثال زير توجه کنيد که برای روشنتر شدن روش استفاده از اين دستورات بيان شده است. در اين مثال داده های موجود در يک آرايه بترتيب جذر گرفته و معکوس می گردد.مشخص است که اعداد نبايد صفر يا منفی باشند.
REAL:: array(5)
Outer: DO
READ(*,*) array
Inner: DO k=1, 5
IF (array(k)==0) CYCLE inner
IF (array(k)<0) EXIT
Array(k)=1/SQRT(array(k))
END DO inner
WRITE(*,*) array
END DO outer
در برنامه بالا يک حلقه بينهايت وجود دارد (حلقه DO بدون محدوديت). برای خروج از چنين حلقه هايی از دستور EXIT استفاده می گردد.
ساختار حلقه DO در فرترن 77 بشکل زير است:
DO label, counter=start, limit, step
Sequence of commands to be looped through
label CONTINUE
دستور GOTO
از اين دستور تا حد امکان استفاده نکنيد. ساختار اين دستور بسيار ساده است.
GOTO label
و يک برچسب در هر جای برنامه که بخواهيد! و اجرای برنامه به آن محل منتقل می گردد.

دستور GOTO شرطی
استفاده از اين دستور هم مانند دستور قبل منع شده است.
دستور STOP
اگر بخواهيم برنامه را متوقف کنيم و کنترل را به سيستم عامل بازگردانيم! از اين دستور استفاده می گردد. ساختار اين دستور به شکل زير است:
STOP [‘message’]
آرايه ها Arrays
يکی از مهمترين ساختارهای داده در برنامه نويسی مهندسی آرايه ها هستند مخصوصاً وقتی با تعداد زيادی عدد در نقاط مختلف کار می کنيم. ساختار آرايه ها مانند انواع ديگر داده ها می باشد فقط تعداد داده ها مشخص می گردد. البته در شرايطی که می خواهيم که تعداد بصورت ديناميک اختصاص داده شود، تعداد را مشخص نمی کنيم.
type array_name({lower bound in nth dimention:Upper bound in nth dimention})
برای مثال فرض کنيد که می خواهيد داده های دمای نقاط در يک شبکه را ذخيره کنيد، نوع داده را اعداد حقيقی در نظر می گيريم. شماره نقاط در طول از 50 تا 70 می باشد و در عرض از 1 تا 20 است:
REAL:: temperature(50:70,1:20)
يا
REAL:: temperature(50:70,20)
حد پايين آرايه بصورت پيش فرض از يک شروع می شود. آرايه در فرترن 77 می تواند تا 7 بعد داشته باشد. آرايه ها بترتيب ستون در حافظه قرار می گيرند و اگر بخواهيم با دستور DO به آرايه ها دسترسی داشته باشيم بهتر است که حلقه شمارنده ستونها داخل حلقه شمارنده سطر ها قرار گيرد (برای سرعت دسترسی بالاتر). دسترسی به هريک از اجزائ آرايه ها با استفاده از انديسهای آن صورت می گيرد، البته دستوراتی در فرترن 90 وجود دارد که کار با آرايه ها را سريعتر و کارآمدتر کرده است و در صورتی که چنين دستوراتی وجود داشته باشد، از آنها استفاده کنيد. مخصوصاً اگر برای استفاده از کامپيوترهای چند پردازنده ای برنامه نويسی می کنيد.
درمثال بالا فرض کنيد که دمای نقطه ای با طول 55 و عرض 12 را بيابيم و در متغير temp قرار دهيم و همچنين دمای نقطه 56 و 13را برابر 400 کلوين قرار دهيم.
temp = temperature(55,12)
temperature(56,13) = 400.0
برای خواندن يا چاپ آرايه ها می توان انديسها را ناديده گرفت تا عمل مورد نظر روی کل آرايه انجام گيرد. برای مثال برای نمايش کل آرايه temperatureروی صفحه نمايش از دستور زير استفاده کرد.
WRITE(*,*) temperature
اين نمايش در صورتی که تعداد اعضاء در يک سطر جا نگيرد کمی گيج کننده است.

ارسال آرايه بعنوان يک پارامتر به تابع
بسياری از موارد شما می خواهيد که يک آرايه را به يک تابع ارسال کنيد, تنها مشکل عدم اطلاع آرايه از اندازه خودش می باشد, پس بايد آرايه فرستاده شده به تابع دارای اندازه ثابت باشد (fixed-size array) يا بايد اندازه آرايه را هم بعنوان يک پارامتر ديگر به تابع ارسال کنيم تا مبادا از مرزهای آرايه فراتر برويم! اگر اندازه آرايه مشخص نباشد می توانيم آن آرايه را با آرگومان * برای آخرين پارامتر آرايه (فقط يک بعد از آرايه را می توان به اين شکل تعريف کرد) به تابع ارسال کنيم. در هر حال بخاطر داشته باشيد که مترجم برنامه از طول آرايه اطلاع نخواهد داشت و شما خودتان بايد مطمئن شويد که فراتر از محدوده اعضاء آرايه نرويد.



مراجع: Aloksandra Donev, “Introduction to FORTRAN”, Physics Department, State University of Michigan, September 1999– recommended for reading
ترجمه: محمد نوروزی، "کتاب آموزشی Visual C++ 6"، کانون نشر علوم، چاپ اول، 1377
دکتر حبيب الله ده مرده، پرويز سرگلزايی، چنگيز دل آرا، "برنامه نويسی کامپيوتر – فرترن، موسسه نشر علوم نوين"، چاپ دوم 1370
[2] http://www.pcc.qub.ac.uk/tec/courses/f90/ohp/header_ohMIF_1.html
[3] Help of Digital Visual FORTRAN –standard edition V 6.0