2014-11-12 2 views
0

저는 Silverfrost FTN95를 사용하고 있습니다. 전문가는 아니기 때문에 논리 변수의 배열을 입력으로 반환하는 함수를 작성하는 데 도움이 필요합니다. 정수 변수의 배열. 거짓이면 0, 참이면 1. 난 그냥 내가 그것을 구현하기 위해 노력하는 방법 semplify이 간단한 코드를 작성 :논리적 유형의 배열을 정수/더블 유형의 배열로 변환

program main 
logical, dimension(2,1)  :: a 
integer, dimension(2,1)  :: b 
integer, dimension(2,1)  :: toInt 
a(:,1)=.false. 
b=toInt(a) 
write(*,*)b 
end program 

function toInt(log) result(val) 
logical, dimension(2,1), intent(in)  :: log 
integer, dimension(2,1)     :: val 
do i=1,2 
    if (log(i,1)) then 
     val(i,1) = 1 
    else 
     val(i,1) = 0 
    end if 
end do 
end function 

이 코드는 날이 오류를 제공합니다 : 배열 범위 첨자 예상 INTEGER 식을 변수 'A'에서 (정수형이 없습니다 줄 "b = toInt (a)"), 그리고 오류가 무엇인지 찾을 수 없습니다. 내 문제를 해결하기위한 제안이나 다른 방법이 도움이 될 것입니다. 감사

+2

도움말을 요청하기 전에 항상 '암시 적 없음'을 사용하십시오! 왜 사용하지 않는 것이 위험한 지 반드시 읽어보십시오.이전 프로그램에 대한 몇 가지 예외가 있지만 여기서는 볼 수 없습니다. 또한 가능한 한 모듈을 사용하는 것이 좋습니다. –

+0

전체 코드에 따라 가장 계산 효율이 높은 방법은 논리 배열을 전혀 사용하지 않는 것입니다. 'if (a (i))'를'if (b (i) .ne.0)'로 대체하면 코드 편의성을 제외하고는 아무것도 들지 않습니다. – agentp

답변

1

오류 메시지 때문에 당신이 배열로 toint을 선언 한 main 프로그램에서 온다, 그래서 문 toint(a)가 논리적 a을 사용하여 해당 배열에 인덱스 시도로 해석됩니다. 정수 배열을 반환하는 외부 함수로 toint을 선언했지만 함수 정의에 연결하기에 충분한 정보를 컴파일러에 제공하지 않았다고 생각할 수 있습니다.

당신은, 당신은 현재 end program을 줄 contains를 삽입하여 소스 파일의 마지막 라인 end program를 이동하여, 프로그램에서 toint의 잘못된 선언을 제거하여 그 문제를 해결 할 수있다. 이 단계들은 toint을 내부적으로 만들 것이고 컴파일러는 자신의 호출을 함수 자체에 매치시키는 역할을 할 것입니다.

하지만 현재 가지고있는 것보다 3 가지, 더 좋은 방법이 있다고 생각합니다. m.true.입니다

하나는 a에서 r에 값을 할당합니다

integer, dimension(x,y) :: a,b,r 
logical, dimension(x,y) :: m 

! set the elements of m as you wish 

a = 1 
b = 0 

r = merge(a,b,m) 

의 라인을 따라 뭔가를 작성하는 것이며 mb에서 .false. 그것은 중요하지 않습니다 무슨 xy 그냥 merge에 대한 배열 인수를 따르는 것입니다. 이 기능을 반복적 인 기능으로 전환하는 것은 상대적으로 쉽습니다.

둘째, 당신은 아마이 방법 ab과 분배이

r = 0   ! all elements are set to 0 
where(m) r = 1 ! where m is true, r is set to 1 

처럼 where 문을 사용할 수 있습니다.

세 번째로 스칼라 및 임의의 순위의 배열에서 작동하는 elemental 함수를 작성하는 방법을 조사 할 수 있습니다. 나는 이것을 운동으로 남겨 둘 것이다. 이미 가지고있는 함수를 수정해야 고정 크기 배열이 아닌 스칼라에서 작동합니다. 이 세 번째 방법은 아마도 가장 쉽고, 가장 유연하며, 프로그램하기 가장 쉽습니다.

+0

당신이 생각하기에, 3 중 어느 것이 계산 시간면에서 가장 효율적입니까? –

0

마크의 3 가지 가능성 네 번째는 병합 내장 함수입니다. 실제로 이것은 본질적으로 그의 제 3의 제안이며 이미 언어에 들어 있습니다. 예를 들면 다음과 같습니다.

[email protected]:~/test/stack$ cat merge.f90 
Program m 

    Implicit None 

    Logical, Dimension(1:3, 1:2) :: log 
    Integer, Dimension(1:3, 1:2) :: val 

    log = .False. 
    log(2, 1) = .True. 

    val = Merge(1, 0, log) 

    Write(*, *) val 

End Program m 
[email protected]:~/test/stack$ nagfor -C=all -C=undefined merge.f90 
NAG Fortran Compiler Release 5.3.1(907) 
[NAG Fortran Compiler normal termination] 
[email protected]:~/test/stack$ ./a.out 
0 1 0 0 0 0 
+0

실제로'merge '를 사용하는 것이 나의 첫 번째 제안이었습니다. 하지만 제 제안은 여기에 설명 된 병합 값에 대한 스칼라 사용을 간과했습니다. –

+0

예 - 읽지 못해 죄송합니다. 마크! –