C Language
식별자 범위
수색…
블록 범위
식별자는 해당 선언이 블록 (함수 정의의 매개 변수 선언 적용)에 나타나면 블록 범위를가집니다. 스코프는 해당 블록의 끝에서 끝납니다.
동일한 식별자를 가진 다른 엔티티는 동일한 범위를 가질 수는 없지만 범위가 겹칠 수 있습니다. 겹치는 범위의 경우 가장 눈에 보이는 범위는 가장 안쪽 범위에서 선언 된 것입니다.
#include <stdio.h>
void test(int bar) // bar has scope test function block
{
int foo = 5; // foo has scope test function block
{
int bar = 10; // bar has scope inner block, this overlaps with previous test:bar declaration, and it hides test:bar
printf("%d %d\n", foo, bar); // 5 10
} // end of scope for inner bar
printf("%d %d\n", foo, bar); // 5 5, here bar is test:bar
} // end of scope for test:foo and test:bar
int main(void)
{
int foo = 3; // foo has scope main function block
printf("%d\n", foo); // 3
test(5);
printf("%d\n", foo); // 3
return 0;
} // end of scope for main:foo
기능 프로토 타입 범위
#include <stdio.h>
/* The parameter name, apple, has function prototype scope. These names
are not significant outside the prototype itself. This is demonstrated
below. */
int test_function(int apple);
int main(void)
{
int orange = 5;
orange = test_function(orange);
printf("%d\r\n", orange); //orange = 6
return 0;
}
int test_function(int fruit)
{
fruit += 1;
return fruit;
}
프로토 타입에 유형 이름을 입력하면 수수께끼의 오류 메시지가 나타납니다.
int function(struct whatever *arg);
struct whatever
{
int a;
// ...
};
int function(struct whatever *arg)
{
return arg->a;
}
GCC 6.3.0에서이 코드 (소스 파일 dc11.c
)는 다음을 생성합니다.
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -c dc11.c
dc11.c:1:25: error: ‘struct whatever’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
int function(struct whatever *arg);
^~~~~~~~
dc11.c:9:9: error: conflicting types for ‘function’
int function(struct whatever *arg)
^~~~~~~~
dc11.c:1:9: note: previous declaration of ‘function’ was here
int function(struct whatever *arg);
^~~~~~~~
cc1: all warnings being treated as errors
$
함수 정의 앞에 구조체 정의를 두거나 struct whatever;
추가하십시오 struct whatever;
함수 선언 앞에 한 줄로 표시하고 아무런 문제가 없습니다. 해당 유형을 사용할 방법이 없기 때문에 함수 프로토 타입에 새 유형 이름을 도입해서는 안되며, 따라서 해당 유형을 정의하거나 사용할 방법이 없기 때문입니다.
파일 범위
#include <stdio.h>
/* The identifier, foo, is declared outside all blocks.
It can be used anywhere after the declaration until the end of
the translation unit. */
static int foo;
void test_function(void)
{
foo += 2;
}
int main(void)
{
foo = 1;
test_function();
printf("%d\r\n", foo); //foo = 3;
return 0;
}
기능 범위
기능 범위 는 레이블 의 특수 범위입니다. 이것은 그들의 특이한 재산 때문입니다. 레이블 은 정의 된 전체 함수를 통해 볼 수 있으며 같은 기능의 모든 점에서 label
점프 할 수 있습니다 (명령 goto
label
). 유용하지는 않지만 다음 예제는 그 요점을 설명합니다.
#include <stdio.h>
int main(int argc,char *argv[]) {
int a = 0;
goto INSIDE;
OUTSIDE:
if (a!=0) {
int i=0;
INSIDE:
printf("a=%d\n",a);
goto OUTSIDE;
}
}
INSIDE
공진 영역 정의 보일 수 if
그것의 경우와 같이, 블록 i
범위 블록 인이 있지만 아니다. goto INSIDE;
명령으로 전체 기능에서 볼 수 있습니다 goto INSIDE;
설명합니다. 따라서 하나의 함수에 동일한 식별자를 가진 두 개의 레이블을 사용할 수 없습니다.
가능한 사용은 할당 된 자원의 올바른 복잡한 정리를 실현하는 다음과 같은 패턴입니다.
#include <stdlib.h>
#include <stdio.h>
void a_function(void) {
double* a = malloc(sizeof(double[34]));
if (!a) {
fprintf(stderr,"can't allocate\n");
return; /* No point in freeing a if it is null */
}
FILE* b = fopen("some_file","r");
if (!b) {
fprintf(stderr,"can't open\n");
goto CLEANUP1; /* Free a; no point in closing b */
}
/* do something reasonable */
if (error) {
fprintf(stderr,"something's wrong\n");
goto CLEANUP2; /* Free a and close b to prevent leaks */
}
/* do yet something else */
CLEANUP2:
close(b);
CLEANUP1:
free(a);
}
CLEANUP1
및 CLEANUP2
와 같은 레이블은 다른 모든 식별자와 다르게 동작하는 특수 식별자입니다. 레이블은 레이블이 지정된 명령문보다 먼저 실행되는 위치 또는 심지어 goto
가 실행되지 않으면 도달 할 수없는 위치에서도 함수 내부의 모든 곳에서 볼 수 있습니다. 레이블은 대문자가 아닌 소문자로 작성되는 경우가 많습니다.