[C] 13. 변수의 범위

Wonder_Land🛕·2022년 7월 28일
0

[C]

목록 보기
14/18
post-thumbnail
  1. 변수의 접근 범위
  2. 변수의 생존 기간
  3. 데이터 세그먼트의 구조
  4. Q&A
  5. 마치며

1. 변수의 접근 범위

1) 지역 변수(Local Varaible)

#include <stdio.h>

void function() {
  int a = 2;
}

int main() {
  int a = 3;
  function();

  printf("a = %d \n", a);
}

[Result]
a = 3

위의 예제에서,
function이라는 함수에서 분명히 a2를 대입했습니다.
그런데 출력된 결과는 3이네요...

그 이유는,
어떠한 함수 내에서 일반적으로 정의된 변수는 해당 함수 내에서만 접근할 수 있습니다.

즉, 해당 지역(Scope)에서만 접근할 수 있다고 해서 위와 같은 변수는 '지역 변수(Local Variable)'이라고 합니다.

  • 지역 변수(Local Variable)
    : 특정 지역에서만 접근할 수 있는 변수

참고로, { }는 하나의 지역으로 취급됩니다.
즉, { }내에서 선언된 변수는, 밖에서 접근할 수 없습니다.

#include <stdio.h>

int main() {
  int a = 3;
  {
    int a = 4;	// Local Varialbe
    printf("a = %d \n", a);
  }

  printf("a = %d \n", a);
}

[Result]
a = 3


2) 전역 변수

#include <stdio.h>

int global = 0;

int function() {
  global++;
  return 0;
}

int main() {
  global = 10;
  function();
  printf("%d \n", global);
  return 0;
}

[Result]
11

위의 예제의 변수 global은 어느 지역에도 속하지 않습니다.

그리고 function이라는 함수와 main함수 모든 곳에서 접근가능 합니다.

이와 같은 변수는 '전역 변수(Global Variable)'이라고 합니다.

  • 전역 변수(Local Varaible)
    : 코드 상 어느 곳에서도 접근할 수 있는 변수

참고로 전역 변수는 정의를 할 때, 자동으로 0으로 초기화 됩니다.

또한, 지역 변수는 함수가 종료될 때 파괴됩니다.

그러나 전역 변수는 프로그램이 시작할 때 만들어지고, 종료될 때 파괴됩니다.

또한, 지역 변수와 달리,
전역 변수는 메모리의 데이터 영역(Data Segment)에 저장됩니다.

전역 변수는 어느 곳에서나 접근 가능하다는 편리함 때문에, 자칫 무수히 많은 전역 변수를 사용해 남용할 수 있습니다.

그러나, 좋은 가독성을 위해,
많은 수의 전역 변수를 사용하는 것은 지양해야합니다.


2. 변수의 생존 기간

일반적으로 정의된 변수는 자신이 정의된 지역을 빠져나갈 때 파괴됩니다.

#include <stdio.h>

int* function() {
  int a = 2;
  return &a;
}

int main() {
  int* pa = function();
  printf("%d \n", *pa);
}

위의 예제를 실행하면 오류가 발생하는데,
function함수를 보면,
int형 변수 a를 정의하고 a의 주소값을 반환합니다.

하지만, afunction이라는 함수가 종료되면,
파괴됩니다.

그런데 main함수에서 *pa가 파괴된 a의 주소값을 가리키기 때문에,
오류가 발생하죠.


1) 정적 변수(Static Variable)

  • 정적 변수(Static Varaible)
    : static 키워드로 선언한 변수
    : 정의된 지역을 빠져나가도 파괴되지 않는 변수
static 자료형 변수 =;
#include <stdio.h>

int* function() {
  static int a = 2;	// Static Variable 'a'
  return &a;
}

int main() {
  int* pa = function();
  printf("%d \n", *pa);
}

[Result]
2

function내에서 정의된 static 변수 a는,
해당 함수가 종료되도 사라지지 않고 남아있습니다.

그래서 main함수에서도 작동이 잘 되죠.

그러면 function함수를 계속 실행해보면 어떻게 될까요?

사실 이 static int a = 2; 문장은 딱 한 번만 실행됩니다.
그리고, 실행하지 않더라도 a는 이미 정의되어 있는 상태입니다.

이러한 특성 때문에,
static 변수는 함수가 몇 번 실행됐는지 쉽게 확인할 수 있게 해줍니다.

int function() {
  static int how_many_called = 0;

  how_many_called++;
  printf("function called : %d \n", how_many_called);

  return 0;
}

int main() {
  function();
  function();
  function();
  function();
  return 0;
}

[Result]
function called : 1
function called : 2
function called : 3
function called : 4

참고로, 정적 변수는 전역변수처럼 데이터 영역(Data Segment)에 저장되고, 프로그램이 종료될 때 파괴됩니다.

그리고, 정의 시 특별한 값이 없다면 자동으로 0으로 초기화합니다.


3. 데이터 세그먼트의 구조

프로그램이 실행될 때, 프로그램은 RAM에 적재됩니다.

다시 말해, 프로그램의 모든 내용이 RAM에 올라가는 것이죠.
(이 때, 프로그램의 모든 내용은, 코드, 데이터 모두를 의미합니다)

여기서 RAM에 올라오는 프로그램의 내용을 크게

  1. 코드 세그먼트(Code Segment)
  2. 데이터 세그먼트(Data Segment)

로 분류할 수 있습니다.

우리는 데이터 세그먼트의 각 부분에 대해 살펴볼 것입니다.


(이 부분은 데이터 세그먼트의 그림과 같이 보면 좋습니다!!)

먼저 살펴볼 곳은 '읽기 전용 데이터(Read-only Data) 부분'입니다.

해당 부분에 저장된 데이터는 절대로 변경할 수 없습니다.

즉, 보호 받는 부분입니다.

상수(Constant)와 리터럴(Literal)이 저장됩니다.


그 위에는 전역 변수와 정적 변수가 저장되는 데이터 영역이 있습니다.

그리고 그 위에는 '힙(Heap)'이라는 영역이 있는데, 추후에 살펴보겠습니다.

그리고 힙의 맨 위를 보면 '스택(Stack)''이 있습니다.

스택은 지역변수가 저장되는 곳입니다.

스택은 지역 변수가 늘어나면, 크기가 아래로 증가합니다.
그리고 지역 변수가 파괴되면, 크기는 위로 줄어들게 됩니다.

즉, 스택이 늘어나는 방향(저장되는 방향)은 메모리 주소가 낮아지는 방향(아래 방향)입니다.


4. Q&A

-


5. 마치며

-

[Reference] : 위 글은 다음 내용을 참고, 인용하여 만들어졌습니다.

profile
아무것도 모르는 컴공 학생의 Wonder_Land

0개의 댓글