2013-02-11 8 views
0
program bisect 
real(8) :: output 
call bisection(3.d0,4.d0,2.d0,output) 
print*, output 
end program bisect 

subroutine bisection(a,b,error,result) 
real(8):: a,b,error,c,result 
logical:: proceed 
    proceed = .true. 
    do while (proceed) 
    if (sin(a)*sin(b).lt. 0.d0) then 
    c=(a+b)/2 
    if (sin(a)*sin(c).lt.0.d0) then 
     b=c 
    else 
     a=c 
    end if 
    else 
    stop 'cannot be bisected' 
    end if 

    if (abs(a-b).lt. error) then 
    proceed = .false. 
    end if 
end do 
result= a 
end subroutine bisection 

동일한 코드 버전이 here에 업로드됩니다.세그먼트 화 오류 - 포트란 90 - 이분법 서브 루틴

이것은 내가 생각해 낼 수있는 최소한의 예입니다. gfortran 및 웹 사이트에서 실행 파일을 실행하면 세그먼트 화 오류가 발생합니다.

답변

1

가짜 인수 a 및 b는 상수 인 실제 인수와 연결됩니다. 상수는 정의 할 수 없습니다 - 프로그램이 "3.0d0"또는 "4.0d0"의 값을 변경하려고합니다. 당신의 프로그램이 성공한다면 혼돈이 우주를 뛰어 넘을 것입니다.

내가 강력하게 추천 :

  • 사용 모듈 절차를. 이를 통해 컴파일러는 실제 인수가 더미 인수와 일치하는지 확인할 수 있습니다.
  • 임시 인수 정의에 INTENT 스펙을 사용하십시오. 이것은 컴파일러가 수정할 필요가있는 것들이 있는지 그리고 수정할 수없는 것들이 아닌지를 검사 할 수있게합니다.

문제의 해결 방법은 주 프로그램에서 3.0d0과 4.0d0의 초기 값을 갖고있는 적절한 변수를 가지며 해당 변경 가능한 변수를 서브 루틴에 전달하는 것입니다. 또는 서브 루틴 내부에 더미 인수의 임시 복사본을 만들 수도 있습니다. F2003에서는 VALUE 속성을 사용하여이 작업을 자동으로 수행 할 수 있습니다.

우리가 사용하는 동안 모든 범위에서 IMPLICIT NONE을 사용하십시오. 항상.

+0

서브 루틴은 인수를 변수로 취급하지 않습니까? 예를 들어 파이썬에서 비슷한 것을 사용할 수 있습니다. –

+0

포트란 - 파이썬을 선호하는 강력한 이유. '4.0 = 3.5' ​​할당을 허락하는 어떤 언어도 심각하게 깨졌습니다. –

+0

@ 마크 : 적어도 논쟁의 여지가있다. 누군가가 코드 블록을 재사용 할 수있는 서브 루틴을 설계한다면; 인수가 전달되는 방식에 무관심하고 불가지론하게 만드는 것이 더 좋습니다. Fortran의 일을 수행 할 때 나오는 이점 하나라도 이름을 붙일 수 있습니까? 나는 상수 값을 변경하는 것에 대한 당신의 요지를 얻지 만, 그것은'intent (out)'를 가진 인자에 대한 리터럴을 허용하지 않음으로써 주위를 둘러 볼 수 있습니다. 명확성을 위해 –