2015-01-20 3 views
2

[SOLVED] by francescalus. 배정 밀도 동적 배열에 대한 작업 코드는 다음과 같습니다Fortran90의 동적 배열에 새 요소를 추가하는 방법

module DynamicalArrays 

    contains 

     subroutine AddToList(list, element) 

      IMPLICIT NONE 

      integer :: i, isize 
      double precision, intent(in) :: element 
      double precision, dimension(:), allocatable, intent(inout) :: list 
      double precision, dimension(:), allocatable :: clist 


      if(allocated(list)) then 
       isize = size(list) 
       allocate(clist(isize+1)) 
       do i=1,isize   
       clist(i) = list(i) 
       end do 
       clist(isize+1) = element 

       deallocate(list) 
       call move_alloc(clist, list) 

      else 
       allocate(list(1)) 
       list(1) = element 
      end if 


     end subroutine AddToList 


    end module DynamicalArrays 

배열이 될 것이다 충전 할 수있는 데모 서브 루틴, :는 별도의 파일에 모듈의 코드를 유지하기 위해 최선의 것을

subroutine UserDArrayTest() 

    use DynamicalArrays 


    integer :: i 
    double precision, dimension(:), allocatable :: list 
    double precision :: temp 

    temp = 0.1 
    do i=1,10 
    temp = temp+1 
    call AddToList(list, temp) 
    end do 

    do i=1,10 
    print *, i, list(i) 
    end do 


    end 

주, 모듈 코드가 메인 프로그램과 서브 루틴 코드 위에있을 때 작동한다는 것을 알았습니다.

--------------- 원래의 질문 ----------------- 내가 포트란에서 동적 배열을 사용할 필요가

처음에는 어레이의 정확한 크기를 예측할 수없는 경우를 대비하여 90입니다. 내가 여기서 뭔가를 놓치고 경우

subroutine DArray() 

    double precision, dimension(:), allocatable :: list 

    allocate(list(1)) 

    list(1) = 1.1 

    call AddToList(list, 2.2) 
    call AddToList(list, 3.2) 
    call AddToList(list, 4.2) 
    call AddToList(list, 5.2) 

    print *, list(1) 
    print *, list(2) 
    print *, list(3) 
    print *, list(4) 
    print *, list(5) 


    end 



    subroutine AddToList(list, element) 

    double precision :: element 
    double precision, dimension(:), allocatable :: list 
    double precision, dimension(:), allocatable :: clist 

    if(allocated(list)) then 
    isize = size(list) 
    allocate(clist(isize+1)) 
    do i=1,isize 
     clist(i) = list(i) 
    end do 
    clist(i+1) = element 

    deallocate(list) 
    allocate(list(isize+1)) 

    do i=1,isize+1 
     list(i) = clist(i) 
    end do 

    deallocate(clist) 

    end if 


    end 

그래서 누구나 볼 않습니다 그래서 때마다 새로운 요소가 배열의 끝에 추가됩니다 할당 가능한 배열 확장해야 코드를 썼다? [해답 - 맨위의 답안과 전체 코드보기]

+0

어떤 문제/오류가 있습니까? – agentp

+0

프로그램이'deallocate (list)'에 멈추고 더 이상 아무것도 실행되지 않습니다. 인쇄 된 오류는 없으며 그냥 멈추고 아무것도하지 않습니다. – chanfort

+0

아마도 Fortran 90을 의미하는 것이 아니라'DArray'에서'AddToList'를 위해 [explicit interface] (http://stackoverflow.com/q/13058743/3157076)를 사용할 수 있어야합니다 : 할당 가능한 더미 인수가 있습니다. – francescalus

답변

3

나는 당신이 문제를 발견했다고 의심하지만, 빠르게 움직였다. 나에게

의심스러운 라인은 다음과 같습니다

allocate(clist(isize+2)) 

왜 새로운 크기 isize+1 아닌가요? 나는 당신이 그것을 시도했지만 프로그램이 실패했다고 생각합니다.

올바른 결과를 얻지 못하는 이유에 대해 프로그램이 실패한 이유 (충돌 가능성이 있음)를 확인하는 것이 중요합니다. 루프를 자세히 살펴보십시오 (명확하게하기 위해 print 문이 제거되었습니다).

do i=1,isize 
    clist(i) = list(i) 
end do 
clist(i+1) = element 

"목록에서 모든 요소를 ​​복사하고 요소를 추가하십시오."라고 말하고 싶습니다. 어느 것이 옳은가. 그러나

do i=1,isize 
    clist(i) = list(i) 
end do 
! Here, i=isize+1 
clist(i+1) = element 
! Which means 
! clist(isize+2) = element. 

요약하면 루프 색인 변수는 최종 반복에서 갖는 값을 갖지 않습니다.

+0

오, 와우,'clist (isize + 1) = element'의 수정으로 이제는 잘 작동합니다 ('end do'가'isize + 1'이 된 후에 fortran 마지막 인덱스에서 알지 못했습니다). 추신 동적 인 배열을 사용하려는 각 서브 루틴의 시작 부분에서 이러한 인터페이스의 6 줄을 피할 수 있는지 알고 있습니까? 어쩌면 USE 문과 모듈을 어떻게 든 사용할 수 있습니까? – chanfort

+0

모듈은 명시 적 인터페이스를 제공하는 방식 (인터페이스 블록 이상)으로 선호되며 예제는 여기에서 쉽게 찾을 수 있습니다. 코드 권고안으로 넘어 가면서'move_alloc' 내장 함수를 가져와야합니다. 동적 크기 조정보다는 링크 된 목록을 고려하는 경우도 있습니다. – francescalus

+0

고마워. 방금 모듈 수정을 추가했는데 이제는 더 멋지게 보입니다. 또한 배열을 처음에 할당 할 필요가 없으며'move_alloc'을 수정해야합니다. 다른 사용자가 전체 코드를 쉽게 찾을 수있는 질문의 맨 위에 변경 사항을 사용했습니다. 실제로 다른 이야기를 위해 연결된 목록을 유지합시다 :) – chanfort

관련 문제