2011-01-05 47 views
6

Trong Fortran, tôi có thể trả về mảng từ một chương trình con với ba cách tiếp cận. Đầu tiên là thông số intent(out). Thứ hai là thông qua một hàm có mảng là result. Thứ ba là có một hàm có dạng result một con trỏ tới mảng, được phân bổ trong hàm.Trả về mảng so sánh chiến lược

Những ưu điểm và nhược điểm của từng phương pháp tiếp cận là gì?

Trả lời

5

Thực hành của tôi là sử dụng hàm trả về khi hàm chỉ thay đổi một biến và không tạo ra kết quả nào khác. Nếu nhiều biến được thay đổi hoặc thủ tục thực hiện các hành động khác, tôi sẽ đặt các biến đầu ra trong danh sách đối số. Đây là một lựa chọn phong cách. Có thể tạo rò rỉ bộ nhớ bằng con trỏ, đặc biệt là với con trỏ được trả về dưới dạng đối số hàm, vì vậy tôi sẽ tránh tùy chọn này trừ khi có lý do thuyết phục trong trường hợp cụ thể.

UPDATE: Không có vấn đề với một ý định (ra) lập luận mảng ... không có giả định cần được thực hiện về kích thước của mảng, như ví dụ sau đây cho thấy:

module example_one 

implicit none 

contains 

subroutine two_arrays (in_arr, out_arr) 

    integer, dimension (:), intent (in) :: in_arr 
    integer, dimension (:), allocatable, intent (out) :: out_arr 

    integer :: i, len 

    len = size (in_arr) 

    allocate (out_arr (1:len)) 

    do i=1, len 
     out_arr (i) = 3 * in_arr (i) 
    end do 

return 

end subroutine two_arrays 

end module example_one 


program test 

use example_one 

implicit none 

integer, dimension (1:5) :: in_arr = [ 1, 2, 4, 5, 10 ] 
integer, dimension (:), allocatable :: out_arr 

write (*, *) allocated (out_arr) 
call two_arrays (in_arr, out_arr) 

write (*, *) size (out_arr) 
write (*, *) out_arr 

write (*, *) allocated (out_arr) 
deallocate (out_arr) 
write (*, *) allocated (out_arr) 

stop 

end program test 
+0

có vấn đề như ngăn xếp đống khi bạn quay trở lại với các chiến lược khác nhau? giả sử bạn trả về một mảng 1 triệu reals. bạn sẽ tràn ngăn xếp, và nó sẽ được sao chép từ ngữ cảnh chức năng đến ngữ cảnh của người gọi không? –

0
  1. 'ý định (out) `có thể là một vấn đề khi bạn phải đưa ra giả định về kích thước của mảng đang được truyền vào.
  2. trả về mảng cũng là một vấn đề khi mã nhận sẽ phải đưa ra giả định về kích thước của mảng đang được trả về
  3. con trỏ tới mảng có các vấn đề liên quan đến kích thước cộng với vấn đề o f đưa ra giả định về việc con trỏ có được liên kết hay không.
  4. sự lựa chọn là để tạo ra một mô-đun, và trong mô-đun có một loại, trong đó có cả một mảng allocatable và một số nguyên quy định chi tiết kích thước của mảng:
module mymodule 
    type myvector 
     double precision,allocatable::values(:) 
     integer::length 
    end type 
end module 

Sau đó, chức năng của bạn có thể là:

function myvecreturner(someparam) 
    use mymodule 
    type(myvector)::myvecreturner 
    integer::someparam 

    allocate(myvecreturner%values(someparam)) 
    myvecreturner%length = someparam 
end function 

Và bạn có thể chuyển các loại myvector này xung quanh một cách vui vẻ. Chỉ cần nhớ để deallocate các mảng khi bạn đang thực hiện với họ ...

+1

Vâng, về mặt kỹ thuật, bạn đã mang theo kích thước của một mảng, mà không cần một loại. tìm hiểu 'size' đạt được hiệu quả tương tự. –

+0

Ngoài ra còn có các giải pháp cho # 2. Các hàm có thể trả về các mảng phân bổ. Xem http://stackoverflow.com/questions/4647772/function-returning-array-with-no-defined-explicit-shape –