2010-08-13 4 views
0

static int i = 10; 

int 
main() 
{ 
    static int i = 20; 

    printf ("i = %d\n", i); 

    return 0; 
} 

포함 개의 정적 변수, 전역 함수의 하나 범위에 하나가 있습니다. 컴파일러에서 "다중 정의"오류가 발생하지 않습니다. 2 개의 정적 병이 어디에 저장되어 있는지 알려주시겠습니까?전역 정적 및 로컬 정적은 언제 저장되고 초기화됩니까?

+0

'여기에는 글로벌 범위에 하나, 함수 범위에 하나의 두 개의 정적 변수가 있습니다. 그게 뭐라고하지 않니? –

+0

유닉스 시스템에서는'nm'을 사용하여 코드가 생성하는 심볼을 볼 수 있습니다. –

답변

3

두 변수는 구분되어 있기 때문에 별도로 저장됩니다. 두 변수는 분리되어 있는지 확인하기 위해 컴파일러의 문제입니다.

변수는 프로그램 시작 전에 모두 초기화됩니다.이 규칙은 C++가 아니라 C이며 규칙이 약간 다릅니다.

그림과 같이 전역 변수 (이 경우 C++가 아니라)에 액세스 할 수 없습니다.

컴파일러 플래그는 로컬 i에 대해 경고합니다.

+0

그러나 정적 변수는 초기화 된 데이터 세그먼트에 저장됩니다. 맞습니까? 그렇다면 어떻게 컴파일러가 글로벌 i와 로컬 i를 구별합니까? –

+2

그러나 그것이 원한다. 이것이 구현 자의 임무입니다. –

+2

힌트 : 정상적인 구현에서 디버거 용으로 보관 된 데이터를 제외하고 이러한 변수 중 * *에는 여전히 컴파일 후 이름이 남아 있습니다. –

0

이러한 변수를 "기호"라고하며 컴파일 중에 테이블이 생성되면 "기호 테이블"이 생성됩니다. 이 테이블에는 각 심볼에 대한 이름, 유형, 범위 및 메모리 포인터가 포함되어 있습니다 (최소값과 같고, 일반적으로 더 많은 요소가 있음). 특정 범위의 심볼에 대한 참조가 생성 될 때마다 테이블에 대한 인덱스. 이러한 인덱스는 고유하므로 name + scope의 조합도 있습니다.

간단히 말해 변수의 이름은 단순히 장식입니다. 내부적으로 컴파일러는 심볼 테이블과 인덱스를 사용하여 작업합니다. Statics는 프로그램 시작시 포인터 포인터를 통해 반복하여 올바른 값을 입력하여 초기화됩니다.

관련 문제