2016-07-27 3 views
1

다음 코드는 여기에 유지하려면 C 언어 구문 : 1에서이 코드의 출력) 표준 C, 실행을 무엇Need and Standard C Output을 (를) 호출하십니까?

#include <stdio.h> 
int func(int a, int b){ 
if (b==0) 
return 0; 
else return func(a,b); 
} 

int main(){ 
printf("%d \n", func(func(1,1),func(0,0))); 
return 0; 
} 

2) 필요 속성에 의해 호출이있는 언어 , 다음 :

(1)에서 프로그램은 무한 호출로 루프를 돌고 (2)는 0이됩니다. 이것은 프로그래밍 언어 과정에서 TA에 의해 해결 된 예제입니다, 어떤 생각이 나를 위해 그것을 설명? 감사

답변

0

은 첫 번째 부분을 해결하기 위해,

는 C 초안, 6.5.2.2-> 10 (기능 통화)

실제 인수 ... 평가의 순서를 말한다. .. 불특정.

  • 모두 ++ii++ 하나씩 i 값을 증가시키는, 즉 부작용 때문에

이러한 이유로

무언가 그러한

printf("%d%d",i++,++i); 

같이 행동 정의되지 않았습니다.

  • printf의 쉼표는 단지 ​​구분 기호이며 [ sequence point ]이 아닙니다.
  • 위의 이유로 함수 호출 자체가 시퀀스 포인트 임에도 불구하고 i의 두 가지 수정이 수행되는 순서는 정의되지 않습니다. 귀하의 경우

    func(func(1,1),func(0,0)) 
    

    에서

  • 하지만, 외부 funcfunc(1,1) 또는 func(0,0)에 대한 인수는 위의 경우에 서로 반대로 아무런 관계가 없다. 이러한 인수에 대한 평가 순서는 결국 무한 재귀를 초래하므로 메모리가 고갈되어 프로그램이 중단됩니다.

    C와
    +2

    "함수 인수의 순서를 선택하는 것은 프로세서까지입니다"라는 말은 무엇을 의미합니까? 왜 UB인가? – Xiobiq

    +0

    알아,하지만 왜 정의되지 않은 행동을한다고 생각하니? –

    +2

    'func (1,1)'또는'func (0,0)'는 먼저 평가 될 수 있지만 둘 다'func()'호출 전에 평가되어야하기 때문에 여전히 무한 재귀를 제공합니다 (C로). – Dmitri

    0

    는, 일반적으로 int func(int a, int b)

    분명 func(1,1)이 문제가되고 코드/후 먼저 평가된다없이 경우 func(1,1) 앓고 평가 같은 함수 인수 ab 평가 순서를 정의하지/필요에 따라 func(a,b)func(0,0)


    분석 동시 결론을 b==0 수 있다면 func()으로 전화를 걸어 0으로 바꿀 필요가 없습니다.

    printf("%d \n", func(func(1,1),func(0,0))); 
    // functionally then becomes 
    printf("%d \n", func(func(1,1),0)); 
    

    어플라이드 다시

    // functionally then becomes 
    printf("%d \n", 0); 
    

    물론 이러한 결론 b != 0 분석 특정되지 않고 else return func(a,b); 무한 순환을 이끈다. 이러한 코드는 (. 예를 들어, 스택 오버 플로우 및 시스템 재설정)에 유용한 원하는 부작용이있을 수 있습니다 그래서 분석은 보수적해야하고 하지func(1,1) 반환 및 심지어 경우 호출을 최적화하지 것으로 가정 func(0,0) 호출을 최적화했습니다. 함수가 호출되기 전에 때문에 엄격한 평가 인수 C에서


    +0

    인수는 before/after/simultaneous 인수로 인해 표준 C에서 실행될 때 동작이 정의되지 않았습니까? –

    +0

    @Sara PhD C는 재귀의 상한을 정의하지 않았습니다 (무한대 (스택 프레임 재사용) 일 수 있음). 최소 최소 금액 또는 재귀 만 가능합니다. 'int main() {while (1); }', 우리는 정의되지 않은 행동 UB가 없습니다. 그것은 결코 완료되지 않습니다. 똑똑한, 코드 또는 제한이있을 수 있습니다. – chux

    +0

    의미 상으로 C 프로그램은 무한 시간 동안 만 실행됩니다. 실제로 - 우리는 모른다. 그것은 정의되지 않은 행동을 계산합니까? –

    3

    1) (strict evaluation semantics를 사용하는) 우리 무한 재귀 얻을 평가된다. 그래서 f(f(1,1), f(0,0))f(1,1)f(0,0)은 외부의 f (먼저 두 개의 인수 중 하나를 평가하는 것이 C에서는 지정되지 않지만 중요하지는 않음) 전에 평가됩니다. 그리고 f(1,1)은 무한 재귀를 발생시키기 때문에 무한 재귀가 발생합니다.

    2) non-strict evaluation (call-by-name 또는 call-by-need가 됨)을 사용하는 언어에서는 평가되지 않은 함수 본문에 대체되며 필요한 경우에만 평가됩니다. 그래서 f에 대한 외부 호출은 같은 먼저 평가 다음 if을 평가할 때

    if (f(0, 0) == 0) 
    return 0; 
    else return f(f(1,1), f(0,0)); 
    

    그래서, 우리는 그래서 우리가 if 결코의 다음 분기로 이동 단순히 0으로 평가 f(0,0)을 평가해야 else-branch를 실행하십시오. f에 대한 모든 호출은 else-branch에서만 사용되기 때문에 절대 필요하지 않으므로 평가되지 않습니다. 그래서 아무런 재귀도 없습니다. 우리는 단지 0을 얻습니다.

    +2

    왜 downvote? 그것은 정확합니다 ... –

    +1

    이 사이트는 매우 이상합니다! 나는 아주 좋은 질문을한다. 언젠가는 투표를해야한다. 좋은 대답이 많다. 나는 혼란 스럽다. ... –

    +0

    @EugeneSh. 너 chux 대답에 대해 어떻게 생각하니? –