آموزش فرترن FORTRAN - مقدماتی

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


همانطور که در اغلب کتابهای مکانيک ديده ايد، در اغلب برنامه های مهندسی از اين زبان استفاده می گردد. زبان برنامه نويسی فرترن با وجود سادگی از قدرت و سرعت بالايی برخوردار است، بطوريکه می توان از آن برای نوشتن برنامه های 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 Studio Microsoft است. اگر قبلاً تجربه کار با اين محيط را داريد می توانيد مطالب را از بخش بعدی ادامه دهيد.

برای نوشتن برنامه فرترن ابتدا يک پروژه می سازيم. مراحل زير را دنبال کنيد. ساده ترين راه برای اين کار استفاده از منوی فايل است. از منوی اصلی File و New را انتخاب کنيد.

1- File > New



از صفحه نمايش داده شده ، برگه Projects را انتخاب کنيد. در اين برگه آيکون (Icon), Fortran Consol Application را انتخاب کنيد. فراموش نکنيد برای پروژه در قسمت Project Name، يک نام انتخاب کنيد.

2- Project(tab) > Fortran Consol Application



روی 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...z A...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 پس از اجرای اين دستورات برابر رشته کاراکتری FOR TRAN خواهد بود( فاصله بعلت اندازه متغير 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'

10 FORMAT(1X, A, F10.5, A(

ابتئا مکان نما يک خانه به راست حرکت می کند، رشته کاراکتری نمايش داده می سود، مقدار متغير f با حداکثر 15 رقم و با دقت 5 رقم اعشار نمايش داده شده و دوباره رشته کاراکتر چاپ می گردد. می توان از کلمات کليدی UNIT و FMT صرفنظر کرد و فقط مقدار آنها را نوشت.

WRITE(*,10) 'The frequency is', f, 'Hz'

10 FORMAT(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 نوع تابع (نوع حاصل تابع) را مشخص می کند. حاصل تابع مقداری است که توسط تابع بازگردانده می شود. اگر به ساختار بالا توجه کنيد دقيقاً جايی که نام تابع برابر يک عبارت قرار گرفته، حاصل تابع است. تابع بايد حداقل يک مقدار خروجی داشته باشد. يعنی در جايی از تابع، مقداری به "نام" تابع اختصاص داده شود.

متغيرهای ظاهری dummy arguments، شامل همة ثابت ها، متغيرها و حتی روالهاي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) يا بايد اندازه آرايه را هم بعنوان يک پارامتر ديگر به تابع ارسال کنيم تا مبادا از مرزهای آرايه فراتر برويم! اگر اندازه آرايه مشخص نباشد می توانيم آن آرايه را با آرگومان * برای آخرين پارامتر آرايه (فقط يک بعد از آرايه را می توان به اين شکل تعريف کرد) به تابع ارسال کنيم. در هر حال بخاطر داشته باشيد که مترجم برنامه از طول آرايه اطلاع نخواهد داشت و شما خودتان بايد مطمئن شويد که فراتر از محدوده اعضاء آرايه نرويد.


سال1391 ، 7 آذر


کلمات کلیدی
   vb.net       httpstatus       کارکرد موتورهای جستجو       education mobile web       mdi       formula in word       parameter       export       psd       listening       shared       android       rar       Boardband       Samples       nti       auto       web services       asp.net mvc       CKEditor        progress       Fundamentals       TuneUp       opera       Zend       int64       flash repair       segment       mvc5       compiler       catch       متن باز       begin       chome       Optics       referrer       os       error       desgin       گزارش       translator       بدست آوردن اطلاعات جدول       sleep       dev       xsession-errors       mtp usb drive       org       photoshop       reports       Analytics    

صفحات ما در فیس بوک
SQL



Google ++

طراحی وب سایتطراحی وب سایت با جدیدترین تکنولوژی های روز

طراحی و پیاده سازی وب سایتهای شخصی و تجاری و اداره ای با جدیدترین تکنولوژی های دنیا
به زبانهای

Asp.net{C#, Vb.Net, J#, Ajax}, Php{Html, Ajax}, js



بهینه سازی صفحات وببهینه سازی صفحات وب برای موتورهای جستجو

بهینه سازی صفحات وب برای موتور های جستجوگر برای افزایش بازدید و معرفی بهتر برای کاربران که به اصتلاح seo نامیده میشود

برنامه نویسیتولید و ساخت نرم افزار

ساخت انواع نرم افزارهی تحت ویندوز و وب و سرور و موبایل و میکروکنترلرها و... ساخت انواع سرویس دهنده های وب و سرور و ... ساخت انواع انالیزگرها و...