2012-07-31 1 views
2

, 우리는 변수 정의 후에 :이름으로 참조 할 때 이름은 어디에 저장됩니까? 예를 들어

int a=2; 

우리는 그 후 "는"2로 사용할 수 있습니다.
처음 c/C++을 배웠을 때, 나는 당연한 것으로 생각했습니다.
그러나 "포인터"개념과 변수 주소를 배운 후에는 혼란 스럽습니다.

int* p=&i; 인 경우, "i"는 int입니다. 나는 p가 i의 주소를 가지고 있다는 것을 압니다. 그래서 * p를 사용하여 i의 값을 얻을 수 있습니다. 그러나 우리가 더 나아가면, "p"는 어떻게 접근됩니까? p는 반드시 이름으로 참조되어야한다고 보입니다.

이제는 주소를 통해 변수에 액세스하는 것이 더 자연스럽고 이해하기 쉽습니다.
하지만 지금은 변수에 액세스하는 가장 간단한 방법을 사용할 때 메커니즘에 대해 혼란 스럽습니다.
int a=2;의 경우와 같이 "a"라는 이름이 저장되어 있습니까?

"a"를 사용하면 "a"또는 "2"가 저장된 메모리에 액세스하는 동작과 동일합니까?

+4

모두 컴파일되면 해당 기호 이름이 남아 있지 않습니다. 그것들은 모두 메모리 주소 및/또는 레지스터로 축소됩니다. 변수 이름은 독자를위한 것입니다. – Mysticial

답변

9

여기 a은 단지 상징적 인 이름입니다. 로컬 변수라면 아무 곳에 나 저장되지 않습니다. 컴파일러는 컴파일 단계에서 실제 값 (스택 또는 레지스터에있을 수 있음)을 참조하고 폐기합니다.

컴파일러에서 생성 된 어셈블리를 살펴 본다면 a이 나타나지 않을 수도 있고 (또는 주석에있을 수도 있음) 알 수 있습니다. 컴파일러는 어딘가에 변수를 넣을 것이고, 나중에 그 위치를 사용할 것입니다 (x86의 eax 레지스터처럼). 당신이 (아주 재미있다)는 LLVM 어셈블리 보았다 경우 a가하고자하는 경우

, 당신은, 다른 한편으로

... 컴파일러는 단지 @1, @2, @3로 변수를 처리하는 것을 알 것 전역 변수 (그리고 static이 아닌 것)이면, 이름은 실제로 변수를 참조하기 위해 기호 테이블에서 사용됩니다. 그러나 다른 방법이 있습니다. 변수는 이름없이 어딘가에 배치되고 심볼 테이블은 다른 프로그램에서 찾을 수 있도록 그 이름을 위치에 매핑합니다.보조 노트로


: 프로그램이 디버그 데이터로 컴파일하면 디버거가 당신이 무슨 일이 일어나고 있는지 이해하는 데 도움을 표시 할 수 있도록 이름 a가 저장됩니다.

3

이것을 추상화라고합니다. 어디서 어떻게 a이 저장되었는지는 의도적으로 지정되지 않습니다. 컴파일러가이를 처리합니다.

실제로는 a이 함수 내부의 로컬 변수이면 호출시 해당 함수의 스택 프레임에 저장됩니다. 스택 프레임의 레이아웃은 컴파일 타임에 결정되며 그 이후에는 변경되지 않습니다. 결과적으로 컴파일러는 a (스택 프레임의 시작을 기준으로 함)의 상대 주소를 생성하고 함수가 실제로 실행될 때 절대 주소로 변환되며 스택 주소의 시작 주소 프레임이 알려져있다.

2

"a"및 "p"와 같은 모든 기호는 컴파일 링 및 연결 프로세스 후 주소로 변환됩니다. 기호는 이름으로 함수를 사용하기위한 것입니다. 메모리 주소를 나타내는 태그와 같습니다. "p"가 "a"의 주소를 보유하더라도 포인터 "p"도 컴파일러에 의해 주소로 변경됩니다.