2015-01-08 5 views
-4
#include<stdio.h> 

int main() { 

    int i; 
    goto l; 

    for(i = 0; i < 5; i++) { 
     l:printf("Hi\n"); 
    } 

    return 0; 

} 

위의 코드는 세 번 출력을 제공합니다. 나는 그것이 어떻게 일어날 지 전혀 모른다. expalin해라. 내가 5에서 3의 값을 줄이면 Hi가 인쇄됩니다.고토 성명서의 동작

+2

'i'를 초기화하지 않고 'goto l'이 루프에 들어가는 것을 보지 못합니까? –

+0

@ iharob -하지만 왜 3 번 3 번 인쇄합니까? 그것이 초기화없이 루프에 들어가면 나는 어떤 가치가 있습니까? – SumS

+2

정의되지 않은 동작입니다. – OldProgrammer

답변

2

당신은 비교 i < 5을하고 먼저 정의되지 않은 동작

당신이하려고하면 (그 시점에서 i의 값이 임의의 쓰레기 값에게 있습니다 )를 일으키는 원인이 초기화하지 않고 for 루프에서 i를 증가하는 대신

#include<stdio.h> 

int main() 
{ 
    int i = 0; 

    goto l; 
    for(i = 0 ; i < 5 ; i++) 
     l: printf("Hi\n"); 

    return 0; 
} 

이 동작을 정의하고이 프로그램은 Hi 5 회를 인쇄합니다.

그리고

#include<stdio.h> 

int main() 
{ 
    int i = 4; 

    goto l; 
    for(i = 0 ; i < 5 ; i++) 
     l: printf("Hi\n"); 

    return 0; 
} 

시도하고 당신이 for 루프를 입력하면 becase Hi은 한 번만 i == 4를 인쇄 할 수 있습니다에 무슨 일이 일어나고 있는지 확인합니다.

그래서 basicaly 당신은 i를 초기화하는 데 실패이 줄

for(i = 0 ; i < 5 ; i++) 

점프하고, 그 이유는 위의 설명에 대해 이렇게 정의되지 않은 동작을 가지고.

goto을 사용하면 프로그램의 흐름을 제어하는 ​​데 어려움이있는 것은 아니지만 코드를 따르고 코드가 수행하는 것을 이해하는 데 어려움이 있습니다. 일반적으로 필요한 것은 아니지만 일반적으로 유용합니다. 어떤 경우는, 예를 들어

FILE *file; 
int *x; 
int *y; 

file = fopen("/path/to/some/file", "r"); 
if (file == NULL) 
    return IO_ERROR_CODE; 

x = malloc(SomeSize * sizeof(int)); 
if (x == NULL) 
{ 
    fclose(file); 
    return MEMORY_EXHAUST_ERROR_CODE; 
} 

y = malloc(SomeSize * sizeof(int)); 
if (y == NULL) 
{ 
    free(x); 
    fclose(file); 
    return MEMORY_EXHAUST_ERROR_CODE; 
} 

return SUCESS_CODE; 

그래서 각 함수 종료 시점에서 더 많은 코드를 추가 할 필요가이 사건을 고려,하지만 당신이, 당신의 예에서 물론이 대신

FILE *file = NULL; 
    int *x = NULL; 
    int *y = NULL; 

    file = fopen("/path/to/some/file", "r"); 
    if (file == NULL) 
     return SOME_ERROR_CODE; 
    x = malloc(SomeSize * sizeof(int)); 
    if (x == NULL) 
     goto abort; 
    y = malloc(SomeSize * sizeof(int)); 
    if (y == NULL) 
     goto abort; 

    return SUCCESS_CODE; 

abort: 
    if (x != NULL) 
     free(x); 
    if (y != NULL) 
     free(y); 
    if (file != NULL) 
     fclose(file); 
    return MEMORY_EXHAUST_ERROR_CODE; 

을 할 수 01을 사용할 이유가 전혀 없습니다..

+0

당신은이 경우 전체 고토가 무의미하다고 덧붙여 야합니다. 그리고 심지어 그것을 모르는 사람들! 'goto'를 사용하고 있습니다 ... 코드가 만들어져'goto'가 눈살을 찌푸리게 만드는 유일한 이유입니다. – dhein

+0

'goto'는 어떤 상황에서는 정말 유용합니다. DRY 원칙을 위반하는 것을 방지합니다. –

+1

그건 정확히 내 견해입니다. 필자의 이전 코멘트는 그런 고토 (goto) 코드를 작성하는 OPER와 같은 사람들이 프로그래머 대다수를 생각하게 만들고, 'goto'는 모든 악의 뿌리라고 생각했다. – dhein

2

코드는 Undefined Behavior입니다. 프로그램의 실행이 goto 문에 도달하면 for 루프 본문 내에서 프로그램 실행이 점프하여 for 루프의 초기화 부분을 건너 뛰기 때문입니다. 따라서 i은 초기화되지 않으며 "가비지 값"을 포함합니다.

참고로 : Using gotos are considered to be bad practice 코드 읽기/유지 관리가 훨씬 어려워졌습니다.