Fortran - ขั้นตอน

procedureคือกลุ่มของคำสั่งที่ทำงานที่กำหนดไว้อย่างดีและสามารถเรียกใช้จากโปรแกรมของคุณ ข้อมูล (หรือข้อมูล) ถูกส่งผ่านไปยังโปรแกรมการเรียกไปยังโพรซีเดอร์เป็นอาร์กิวเมนต์

มีสองประเภทของขั้นตอน -

  • Functions
  • Subroutines

ฟังก์ชัน

ฟังก์ชันคือโพรซีเดอร์ที่ส่งคืนปริมาณเดียว ฟังก์ชันไม่ควรแก้ไขอาร์กิวเมนต์

ปริมาณที่ส่งคืนเรียกว่า function valueและแสดงด้วยชื่อฟังก์ชัน

Syntax

ไวยากรณ์สำหรับฟังก์ชันมีดังนี้ -

function name(arg1, arg2, ....)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงฟังก์ชันที่ชื่อ area_of_circle คำนวณพื้นที่ของวงกลมที่มีรัศมี r

program calling_func

   real :: a
   a = area_of_circle(2.0) 
   
   Print *, "The area of a circle with radius 2.0 is"
   Print *, a
   
end program calling_func


! this function computes the area of a circle with radius r  
function area_of_circle (r)  

! function result     
implicit none      

   ! dummy arguments        
   real :: area_of_circle   
   
   ! local variables 
   real :: r     
   real :: pi
   
   pi = 4 * atan (1.0)     
   area_of_circle = pi * r**2  
   
end function area_of_circle

เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังนี้ -

The area of a circle with radius 2.0 is
   12.5663710

โปรดทราบว่า -

  • คุณต้องระบุ implicit none ทั้งในโปรแกรมหลักและขั้นตอน

  • อาร์กิวเมนต์ r ในฟังก์ชันที่เรียกนั้นเรียกว่า dummy argument.

ตัวเลือกผลลัพธ์

หากคุณต้องการให้เก็บค่าที่ส่งคืนในชื่ออื่นที่ไม่ใช่ชื่อฟังก์ชันคุณสามารถใช้ไฟล์ result ตัวเลือก

คุณสามารถระบุชื่อตัวแปรส่งคืนเป็น -

function name(arg1, arg2, ....) result (return_var_name)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]

รูทีนย่อย

รูทีนย่อยไม่ส่งคืนค่า แต่สามารถแก้ไขอาร์กิวเมนต์ได้

Syntax

subroutine name(arg1, arg2, ....)    
   [declarations, including those for the arguments]    
   [executable statements]  
end subroutine [name]

เรียก Subroutine

คุณต้องเรียกใช้รูทีนย่อยโดยใช้ call คำให้การ.

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงนิยามและการใช้รูทีนย่อย swap ที่เปลี่ยนค่าของอาร์กิวเมนต์

program calling_func
implicit none

   real :: a, b
   a = 2.0
   b = 3.0
   
   Print *, "Before calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
   
   call swap(a, b)
   
   Print *, "After calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
   
end program calling_func


subroutine swap(x, y) 
implicit none

   real :: x, y, temp   
   
   temp = x  
   x = y 
   y = temp  
   
end subroutine swap

เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังนี้ -

Before calling swap
a = 2.00000000    
b = 3.00000000    
After calling swap
a = 3.00000000    
b = 2.00000000

การระบุเจตนาของอาร์กิวเมนต์

แอตทริบิวต์เจตนาช่วยให้คุณระบุความตั้งใจที่ใช้อาร์กิวเมนต์ในโพรซีเดอร์ ตารางต่อไปนี้ระบุค่าของแอตทริบิวต์เจตนา -

มูลค่า ใช้เป็น คำอธิบาย
ใน เจตนา (ใน) ใช้เป็นค่าอินพุตไม่เปลี่ยนแปลงในฟังก์ชัน
ออก เจตนา (ออก) ใช้เป็นค่าผลลัพธ์ซึ่งจะถูกเขียนทับ
inout เจตนา (เข้า) อาร์กิวเมนต์มีทั้งใช้และเขียนทับ

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -

program calling_func
implicit none

   real :: x, y, z, disc
   
   x = 1.0
   y = 5.0
   z = 2.0
   
   call intent_example(x, y, z, disc)
   
   Print *, "The value of the discriminant is"
   Print *, disc
   
end program calling_func


subroutine intent_example (a, b, c, d)     
implicit none     

   ! dummy arguments      
   real, intent (in) :: a     
   real, intent (in) :: b      
   real, intent (in) :: c    
   real, intent (out) :: d   
   
   d = b * b - 4.0 * a * c 
   
end subroutine intent_example

เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังนี้ -

The value of the discriminant is
   17.0000000

ขั้นตอนการเรียกซ้ำ

การเรียกซ้ำเกิดขึ้นเมื่อภาษาโปรแกรมอนุญาตให้คุณเรียกใช้ฟังก์ชันภายในฟังก์ชันเดียวกัน เรียกว่าฟังก์ชันเรียกซ้ำ

เมื่อโพรซีเดอร์เรียกตัวเองโดยตรงหรือโดยอ้อมเรียกว่าโพรซีเดอร์แบบวนซ้ำ คุณควรประกาศขั้นตอนประเภทนี้โดยนำหน้าคำrecursive ก่อนการประกาศ

เมื่อฟังก์ชันถูกใช้แบบวนซ้ำไฟล์ result ต้องใช้ตัวเลือก

ต่อไปนี้เป็นตัวอย่างซึ่งคำนวณแฟกทอเรียลสำหรับจำนวนที่กำหนดโดยใช้ขั้นตอนการเรียกซ้ำ -

program calling_func
implicit none

   integer :: i, f
   i = 15
   
   Print *, "The value of factorial 15 is"
   f = myfactorial(15)
   Print *, f
   
end program calling_func

! computes the factorial of n (n!)      
recursive function myfactorial (n) result (fac)  
! function result     
implicit none     

   ! dummy arguments     
   integer :: fac     
   integer, intent (in) :: n     
   
   select case (n)         
      case (0:1)         
         fac = 1         
      case default    
         fac = n * myfactorial (n-1)  
   end select 
   
end function myfactorial

ขั้นตอนภายใน

เมื่อมีโพรซีเดอร์ภายในโปรแกรมเรียกว่าโพรซีเดอร์ภายในของโปรแกรม ไวยากรณ์สำหรับการมีโพรซีเดอร์ภายในมีดังนี้ -

program program_name     
   implicit none         
   ! type declaration statements         
   ! executable statements    
   . . .     
   contains         
   ! internal procedures      
   . . .  
end program program_name

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -

program mainprog  
implicit none 

   real :: a, b 
   a = 2.0
   b = 3.0
   
   Print *, "Before calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
   
   call swap(a, b)
   
   Print *, "After calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
 
contains   
   subroutine swap(x, y)     
      real :: x, y, temp      
      temp = x 
      x = y  
      y = temp   
   end subroutine swap 
   
end program mainprog

เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังนี้ -

Before calling swap
a = 2.00000000    
b = 3.00000000    
After calling swap
a = 3.00000000    
b = 2.00000000