오늘은, 간단하게 지역변수에 대해서 알아보도록 하겠습니다. 그 전에, 변수를 visible 할 수 있는 범위, 즉 scope하고, life time에 대해서 집중적으로 보도록 합시다.
8번째 줄에 정의된 t는 어디에 선언이 되었나요? foo 라는 함수 내부에 정의가 되었습니다. block 내부나, 프로그램 단위 (함수)에 정의된 변수들을 지역 변수라고 부릅니다.
그러면, 이것이 어떠한 특징을 가지는지, 위에 있는 코드를 한 번 실행해 봅시다. 결과가 0이 나오는데요. 차근 차근 설명해 보겠습니다. 먼저, 4번째 줄의 int t = 0; 이라는 문장을 실행하면, 변수 t에 0이 대입이 됩니다.
그러면 이렇게 상황을 그릴 수 있습니다.
다음에, foo(t)를 호출하게 되는데요. 6번째 줄에 보면 매개변수 a가 받고 있어요. 값이 복사되기 때문에, a의 값도 0이 됩니다. 그 다음에, 8번째 줄이 수행이 되는데요.
t를 foo 안에 선언했습니다. foo 안에서 선언이 되었기 때문에, main 함수 안에 있는 t와 별도의 공간을 사용하게 됩니다.
당연하게도, 8번째 줄의 t++이 수행되면, t의 값은 6이 될 건데요. main의 t 값은 변하지 않습니다.
그리고 함수가 끝나면, main 함수로 복귀하는데요. 이 과정에서, 스택 포인터가 이동합니다. 이 때, t = 6과 a = 0에 대한 정보는 필요 없어진다고 보시면 됩니다. 스택에 2, 3, 7 순으로 들어갔습니다. 7과 3을 빼면, 정보 3과 7은 필요 없어지는 것과 같습니다. 즉 지역 변수는 선언이 될 때 부터, 블록이 끝날 때 까지 사용 가능하고, 블록이 끝나면 사용을 할 수 없습니다.
다른 예를 들어봅시다. 책에서만 굉장히 많이 나오는 예제를 설명하기 전에, 이 예제 먼저 보고 넘어가겠습니다.
실행 결과가 어떻게 나올까요? 당연하게도 10이 나옵니다. i가 0일 때 부터, 9일 때 까지 루프를 돌면서 a의 값을 증가시켰기 때문입니다. 8번째 줄의 a를 보세요. for문의 블록 안에 int a; 가 없어요. 그렇기 때문에, main에 있는 a를 쓴 것입니다. 이것은 쉽게 이해가실 듯 싶습니다.
이 경우에는 어떨까요? 이상하게도, 0이 나온다는 것을 알 수 있습니다. 이는 예제 1과 비슷한 이유인데요. 보시면 블록 안에 a가 선언이 되어 있습니다. 그러면, block 안의 a와 main 함수, 그러니까 5번째 줄에 선언되어 있는 a와, 서로 다른 메모리 공간에 할당이 될 겁니다.
그러면, for문 안에 있는 a와 main 안에 있는 a가 별개의 공간에 있기 때문에, 9번째 줄 a++이 수행되면, 보라색으로 칠한 공간에 있는 값이 증가합니다. 분명한 것은, main에도 a가 있었고, for문 안에도 a가 있었습니다. 9번째 줄 a++은 for loop 안에 있었고, 이 블록 안에 a가 선언되었기 때문에, main에 있는 a는 가려집니다. 이 두 원칙을 이해하시면 지역 변수를 설명할 때, 꽤 많이 나오는 아래 예제 또한 이해하실 수 있을 겁니다.
차근 차근 보겠습니다. 먼저, 6번째 {에 들어가면, a와 b가 또 선언이 되어 있어요. 그리고, 8번째 {에 들어가면, 이 블록 안에 또 a가 선언이 되어 있는데요. 10번째 줄에는 어떤 값이 출력될까요? b부터 봅시다.
먼저, 9번째 줄에 들어왔을 때, b++이 되고 있어요. 보시면, 7번째 줄에 b가 선언이 되어 있습니다. main에도 b가 있지만, 9번째 줄의 b++의 입장에서 보았을 때에는, 가장 가까운 것은, main에 있는 것 보다 6번째 줄부터, 13번째 줄까지의 블록 안에 있는 b입니다.
따라서, 이 값이 하나 증가하고, 결과는 3이 나옵니다. 또, 12번째에서 b를 출력하라고 했는데요. 역시 블록 안에 있는 b를 출력할 거에요. 3이 출력됩니다. 5번째 줄에 있는 b는 가려집니다.
다음에, 14번째 줄에 또 b를 출력하라고 했습니다. 이 때에는 어떻게 되나요? 블록 내에 b가 선언이 되었습니다. 이것에 의해서 main에 있었던 b는 가려졌기 때문에, 0이 출력됩니다.
그러면 a에 대해서도 그리 어렵지 않게 해석할 수 있어요. 먼저 가장 안쪽에 있는 괄호를 보면, a가 먼저 선언되었어요. 이 순간, 9번째 줄에 있는 a++은 9번째 줄에 선언된 a에 대해서만 동작합니다. 따라서, 2가 출력됩니다.
다음에, 6번째 줄에 있는 block을 보면, a가 선언되고 ~가 실행된 다음에, 다시 a가 출력되는 형태입니다. a가 변화하는 문장이 없었으므로, 3이 출력됩니다. 그러면 바깥에 있는 a는..
6번째 줄에 있는 블록이 시작되자마자 선언이 되었기 때문에, 6번째 줄에 있는 블록은, main에 있는 a의 값을 결정하지 않습니다. 따라서 0이 출력됩니다.
그러면 이 경우에는 어떨까요?
블록에 들어온 상태에서, a++이 수행이 됩니다. 블록 내에 있는 a는 아직 선언이 안 된 상태이므로, 쓸 수 없고, 그 대신, main에 있는 a를 씁니다.
다음에, a가 블록 내에서 선언이 됩니다.
그러면, 이 때 9번째 줄이 수행되면 보라색으로 칠한 부분의 값이 1 증가할 겁니다. 그리고 10번째 줄을 수행하게 되면, 블록을 빠져나오게 되는데요. 이 때, block 내에 있었던, a는 쓸 수 없게 됩니다.
이 정도만 정리하셔도 무난할 듯 싶네요. 지역변수는, 블록 B 내에 선언이 되었을 때, B 내에 선언이 된 순간부터, B가 끝날 때 까지 쓸 수 있다는 것 정도만 기억하시면 될 듯 싶네요.
'코딩 > C' 카테고리의 다른 글
c언어 구조체 : 데이터들을 하나로 묶는다. (12) | 2019.10.01 |
---|---|
c언어 static 변수 : 메모리에 언제 올라가는가? (7) | 2019.09.29 |
C언어 strcat 함수 : 문자열을 이어 붙인다. (10) | 2019.09.23 |
c언어 2차원 배열 : 메모리 상에 어떻게 저장이 될까요? (11) | 2019.09.14 |
C언어 문자열 : 특별한 문자로 끝난다. (10) | 2019.09.09 |
최근댓글