#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가 인쇄됩니다.고토 성명서의 동작
#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가 인쇄됩니다.고토 성명서의 동작
당신은 비교 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을 사용할 이유가 전혀 없습니다..
당신은이 경우 전체 고토가 무의미하다고 덧붙여 야합니다. 그리고 심지어 그것을 모르는 사람들! 'goto'를 사용하고 있습니다 ... 코드가 만들어져'goto'가 눈살을 찌푸리게 만드는 유일한 이유입니다. – dhein
'goto'는 어떤 상황에서는 정말 유용합니다. DRY 원칙을 위반하는 것을 방지합니다. –
그건 정확히 내 견해입니다. 필자의 이전 코멘트는 그런 고토 (goto) 코드를 작성하는 OPER와 같은 사람들이 프로그래머 대다수를 생각하게 만들고, 'goto'는 모든 악의 뿌리라고 생각했다. – dhein
코드는 Undefined Behavior입니다. 프로그램의 실행이 goto
문에 도달하면 for
루프 본문 내에서 프로그램 실행이 점프하여 for
루프의 초기화 부분을 건너 뛰기 때문입니다. 따라서 i
은 초기화되지 않으며 "가비지 값"을 포함합니다.
참고로 : Using goto
s are considered to be bad practice 코드 읽기/유지 관리가 훨씬 어려워졌습니다.
'i'를 초기화하지 않고 'goto l'이 루프에 들어가는 것을 보지 못합니까? –
@ iharob -하지만 왜 3 번 3 번 인쇄합니까? 그것이 초기화없이 루프에 들어가면 나는 어떤 가치가 있습니까? – SumS
정의되지 않은 동작입니다. – OldProgrammer