2011-12-23 35 views
22

Không chắc chắn rằng tiêu đề có được đặt hay không. Đề nghị chào đón.Cách đặt bí danh tên hàm trong Fortran

Đây là những gì tôi muốn làm. Kiểm tra một điều kiện, và sau đó quyết định chức năng để sử dụng trong một vòng lặp. Ví dụ:

if (a < 0) then 
    loop_func = func1 
else 
    loop_func = func2 
endif 

Tôi có thể sử dụng loop_func làm con trỏ khi viết vòng lặp của mình. Cả hai hàm đều lấy chính xác các đầu vào giống nhau và là các cách tiếp cận khác nhau để giải quyết vấn đề dựa trên giá trị của a. Điều này sẽ cho phép tôi chỉ có một khối mã, thay vì hai khối gần giống nhau. Điều này cũng có thể áp dụng cho các chương trình con.

Bất kỳ ý tưởng nào về cách triển khai này có thể được thực hiện?

Cảm ơn bạn.

Trả lời

31

Có, Fortran có các con trỏ thủ tục, vì vậy bạn có thể có hiệu lực bí danh tên hàm. Đây là một ví dụ mã gán cho hàm con trỏ "f_ptr" một hàm hoặc hàm kia. Sau đó chương trình có thể sử dụng "f_ptr" và hàm được chọn sẽ được gọi.

module ExampleFuncs 

    implicit none 

contains 

function f1 (x) 
    real :: f1 
    real, intent (in) :: x 

    f1 = 2.0 * x 

    return 
end function f1 


function f2 (x) 
    real :: f2 
    real, intent (in) :: x 

    f2 = 3.0 * x**2 

    return 
end function f2 

end module ExampleFuncs 


program test_func_ptrs 

    use ExampleFuncs 
    implicit none 

    abstract interface 
     function func (z) 
     real :: func 
     real, intent (in) :: z 
     end function func 
    end interface 

    procedure (func), pointer :: f_ptr => null() 

    real :: input 

    write (*, '(/ "Input test value: ")', advance="no") 
    read (*, *) input 

    if (input < 0) then 
     f_ptr => f1 
    else 
     f_ptr => f2 
    end if 

    write (*, '(/ "evaluate function: ", ES14.4)') f_ptr (input) 

    stop 

end program test_func_ptrs 
+0

Phương ngữ này là gì? – wallyk

+0

Hmm ... vì vậy '=>' là một loại toán tử gán cho con trỏ, và 'procedure (func)' là một kiểu khai báo cho các thủ tục, như 'type (mytype)' là cho các kiểu có nguồn gốc. Tôi giả sử 'null()' được sử dụng để khởi tạo và tương đương với 0. Như bạn có thể nói tôi là người mới bắt đầu ở đây.Và vâng, Fortran là ngôn ngữ lập trình đầu tiên tôi học đúng cách. –

+0

Một vài câu hỏi. Giao diện 'là gì? Đó có phải là cách để xác định một thủ tục (một lần nữa, như kiểu dẫn xuất), và để đảm bảo rằng những gì con trỏ trỏ đến là của "loại" chính xác? Ngoài ra, bạn có một 'stop' trước khi kết thúc chương trình của bạn. Đó có phải là thực hành tốt nhất, và tôi nên bao gồm trong mã của tôi không? –

2

Hầu hết các triển khai Fortran không có cách thức tiêu chuẩn để thao tác con trỏ hàm hoặc con trỏ thủ tục. Tuy nhiên, Fortran 2003 và sau đó có một cái gì đó. (Xem trang 6 của this.)

Đối với các tình huống cụ thể, điều này sẽ làm việc khá tốt trong vị trí của nó:

function func1 (p1, p2, etc) 
... as you have it already 
end 

function func2 (p1, p2, etc) 
... as you have it already 
end 

function funcselect (a, p1, p2, etc) 
    if (a < 0) then 
      x = func1 (p1, p2, etc) 
    else 
      x = func2 (p1, p2, etc) 
    endif 
end 

Sau đó, chỉ cần gọi funcselect với tham số thêm thay vì những gì bạn đã có thể thực hiện với loop_func .

+0

Nhưng chương trình sẽ không kiểm tra điều kiện mỗi khi nó gọi hàm? Tôi đang cố tránh điều đó. –

+0

@SamuelTan: Vâng, nhưng hầu như không có gì phải lo lắng. Trên bất kỳ bộ vi xử lý hiện đại nào, đó chỉ là một vài chu kỳ CPU: một vài nano giây. – wallyk

+2

Tôi không đồng ý với tuyên bố "Fortran không có cách tiêu chuẩn để thao tác con trỏ hàm hoặc con trỏ thủ tục." Con trỏ thủ tục là một phần của tiêu chuẩn ngôn ngữ Fortran 2003. –

Các vấn đề liên quan