2016-06-02 2 views
3

오랫동안 저는 Fortran을 사용 해왔고 최근 C를 배우기로 결심했습니다. C에서의 함수가 어떻게 작동하는지 알지만 C에서 Fortran 서브 루틴과 동일한 것을 구현하는 방법에 대한 정보를 찾는 데 어려움을 겪고 있습니다. C 언어로 모두? 서브 루틴에 대한C에서 서브 루틴이 Fortran과 유사한 서브 루틴이 있습니까?

module myMod 
    implicit none 
    contains 

    function func(a, b) 
     integer :: func 
     integer, intent(IN) :: a, b 
     func = a + b 
    end function func 

    subroutine sub(a, b, c) 
     integer, intent(INOUT) :: a, b 
     integer, intent(OUT) :: c 
     a = a * b 
     b = 3 * a 
     c = a + b 
    end subroutine sub 

end module myMod 

program example 
    use myMod 
    implicit none 
    integer :: i, j, k 

    i = 1 
    j = 2 

    k = func(i,j) 
    print*, k 

    call sub(i,j,k) 
    print*, i, j, k 

end program example 

C로 변환 할 사소한 것 모듈 mymod를의 기능을하지만 :

이 포트란 코드를 고려? 비슷한 일을하는 방법이 있습니까?


편집 :

#include <stdio.h> 

void subroutine(int num1, int num2) { 
    num1 -= 1; 
    num2 *= 2; 
    printf("this has been executed! \n"); 
} 

int main() { 

    int a = 10; 
    int b = 10; 

    subroutine(a,b); 
    printf("a = %d, b = %d \n", a, b); 

    return 0; 
} 

그것은 출력 : 대신 예상의

this has been executed! 
a = 10, b = 10 

:

this has been executed! 
a = 9, b = 20 
예를 들어, 아래 코드는 내가 기대했던 출력되지 않는다

그럼 변수가 왜없는가요? a와 b는 포트란 서브 루틴처럼 void 함수에서 수정 되었습니까?

+0

올바르게 이해한다면, 서브 루틴과 함수의 차이점은 (적어도이 예제에서) 서브 루틴이 둘 이상의 값을 반환 할 수 있다는 것입니다. C에서는 포인터를 사용하고 함수에'i, j, k' 포인터를 넘기 만하면 함수는 포인터를 통해 메모리 위치에 액세스하여 변수의 값을 변경할 수 있습니다. –

+0

Fortran의 서브 루틴은 주 프로그램의 변수 값을 변경할 수 있습니다. –

+3

"* 나는 C *를 배우기로 결심했다."라는 질문에 대한 답을 보려면 위의 "C"입문서에서 "address-of"연산자 ('&')와 "de-reference" "-operator ('*'), 일반적으로 포인터와 함께. – alk

답변

5

반환 유형이 void 인 함수를 정의 할 수 있습니다. 즉, 아무 것도 반환하지 않습니다.

반환 유형이 void 인 함수는 return 키워드를 값없이 사용할 수 있지만 return을 사용할 필요는 없습니다.

void sub(int *a, int *b, int *c) 
{ 
    *a = (*a) * (*b); 
    *b = 3 * (*a); 
    *c = (*a) + (*b); 
    printf("a=%d, b=%d, c=%d\n", *a, *b, *c); 
} 

과 같이 호출 :

다음과 같이 상기 한 서브 루틴을 번역 할 수있는 모든 변수 값 통과되어 C에서

sub(&i, &j, &k); 

때문에 함수 ISN의 파라미터를 수정 발신자에게 반영되지 않았습니다.

각 하나에 당신에게 포인터를주는 대신 주소는 & 연산자를 사용하여 수정하려는 각 변수의 전달하면 함수에 전달할 값을 수정할입니다. 그런 다음 참조를 가리키는 단항 * 연산자가있는 포인터를 가리키고 값을 읽고 쓰십시오.

+0

흠, 이것이 제가 놓친 것 같습니다. '* '은 정확히 무엇을 의미합니까? 그리고 왜 '& '을 사용하여 서브 루틴을 호출해야합니까? –

+0

예제를 더 분명하게 만들고, 서브 루틴에서'print * '를 제거하고 주 프로그램에 추가하기 위해 포트란 코드를 업데이트했습니다.나는 위의 코드에서'printf'를 움직이는 것과 같을 것이라고 생각합니다. –

+0

@ gilberto.agostinho.f : 참조로 매개 변수를 전달해야합니다. – sjsam

1

함수는 값을 반환 할 필요가 없습니다. FORTRAN 서브 루틴의 대안은 반환 유형이 void 인 함수를 선언하는 것입니다. 이것은 효과적으로 함수 서브 루틴을 만든다

void function(arguments){ 
... 
} 

는 - 함수가 그 범위 밖에있는 변수를 변경할 수 있도록 값을 참고로 함수에 전달된다 제공.귀하의 경우에는

void subroutine(int* num1, int* num2) { 
    /* num1 stores the address of a 
    * and *num1 gives the value stored in that address 
    */ 
    *num1 -= 1; 
    *num2 *= 2; 
    printf("this has been executed! \n"); 
} 

로 함수를 선언하고 호출 : 당신이 서브 루틴처럼 동작 매크로를 정의하는 C 프리 프로세서를 사용할 수있는 경우에

subroutine(&a,&b); // &a means the address of a 
1

. 예를 들면 :

#define subroutine(X,Y) do{ \ 
    X -= 1; \ 
    Y *= 2; \ 
    printf("this has been executed!\n"); \ 
} while(0) 

int main(int argc, char**argv) 
{ 
    int a = 10; 
    int b = 10; 

    subroutine(a, b); 
    printf("a = %d, b = %d\n", a,b); 
} 

결과 :

this has been executed! 
a = 9, b = 20 

C 매크로는 문자 텍스트 대체합니다. 외부 do...while(0)while(0)이 후행 ;을 삼킬 것이며 사용 가치가있는 컴파일러에 의해 최적화되기 때문에 함수처럼 "호출 가능"한 다중 명령문 매크로를 만들기위한 아주 기본적인 "트릭"입니다. 후행 \ characetrs를 사용하면 여러 줄 매크로를 정의 할 수 있습니다.

GCC (Gnu 확장자, 표준 C가 아닌)의 기능 중 일부는 나중에 적용 할 수있는 효과를 줄 수 있습니다. 함수를 내부에서 정의 할 수 있습니다 내부 함수는 외부 함수의 로컬 범위 변수에 액세스 할 수 있습니다. 예를 들어

Gnu C Reference manual sections on nested functions

: 출력 결과

#include <stdio.h> 

int main(int argc, char**argv) 
{ 
    int a = 10; 
    int b = 10; 

    void subroutine(){ 
    a -= 1; 
    b *= 2; 
    printf("this has been executed!\n"); 
    } 

    subroutine(); 
    printf("a = %d, b = %d\n", a,b); 
    subroutine(); 
    printf("a = %d, b = %d\n", a,b); 
    subroutine(); 
    printf("a = %d, b = %d\n", a,b); 
} 

:

this has been executed! 
a = 9, b = 20 
this has been executed! 
a = 8, b = 40 
this has been executed! 
a = 7, b = 80 

이 두 기술은 일반적으로 함정의 많음을 가지고는 "모범 사례"의 영역을 벗어나는 C에서, 그러나 어느 쪽이든지 Fortran에서 C로 점진적으로 코드 (그리고 당신의 사고)를 마이그레이션하려는 강력한 도구가 될 수 있습니다.

+0

이것은 매우 흥미 롭습니다! 두 번째 예제에서 변수 a와 b는 고정되어 있으므로'subroutine(); '을 호출하면 Fortran에서 서브 루틴과 반대되는 특정 두 변수에 항상 영향을줍니다. –

+0

첫 번째 예제에서 수정 된 변수를 수정하십시오. 다른 함수처럼 매개 변수화 할 수 있지만, C는 * 실제 * 참조에 의한 참조가 없으므로 dbush의 대답으로 되돌아갑니다. 매크로 방식이 더 유용 할 것입니다. –

+1

표준 C는 중첩 된 함수를 지원하지 않습니다. –

관련 문제