C언어 변수의 존재기간과 접근범위

프로그래밍/C 2018.12.20 댓글 Plorence
C++에서도 해당되는 내용입니다.

변수(Variable)

함수내에 변수가 선언되었으면 그변수는 지역변수라고 부릅니다.
지역변수는 함수가끝나면 자동으로 소멸되고 함수가 호출될때 지역변수는 메모리공간에 할당됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
void Funcprintf();
/*
지역변수는 함수내에서만 사용이 가능
*/
int main (void){
    int num1 = 0//변수 num1은 지역변수이다. main함수가 끝나면 자동으로 소멸된다.
    printf("%d",n1); //Funcprintf 에 있는 변수n1에서 저장된 정수값을 출력하는거지만 해당 지역변수는 Funcprintf함수내에서만 사용 가능하기때문에 에러
}
void Funcprintf(){
    int n1 = 0//변수 n1도 함수안에 선언되었으므로 지역변수이다.
    printf("%d",n1);
}
결론은 함수내에서 선언된 변수는 그함수내에서만 사용이 가능합니다.
지역 변수는 그 함수가 호출되고 변수가 메모리에 할당되며 함수가 종료될시 자동으로 소멸됩니다.

지역변수의 특징
  • 지역변수는 '스택(stack)'이라는 메모리 영역에 할당된다.
  • 지역변수는 접시 쌓듯이 할당된다.

이렇게 지역변수는 접시쌓듯이 차곡차곡 쌓입니다.

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
void Funcprintf();
int main (void){
    int num1 = 0;
    Funcprintf(); //함수의 호출로 Funcprintf함수 지역변수는 메모리영역에 할당된다.
}
void Funcprintf(){
    int n1 = 0;
    printf("%d",n1);
    
    return//return시 Funcprintf함수의 지역변수가 모두 소멸된다.
}
위에 예제를 보면 Funcprintf();함수의 호출로 Funcprintf함수의 지역변수인 n1은 메모리영역에 n1 = 0 이라고 할당 됩니다.
함수의 호출로 함수가 실행되다가 return문을 만나면 Funcprintf함수의 지역변수는 모두 소멸됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
int main (void){
    int num1 = 5;
    printf("%d",num1);
    for(int i=0;i<5;i++){
        int num2 = 10;
        printf("반복문 (for문)안에 지역변수:%d\n",num2);
    }
    if(1 < 5){
        int num3 = 4;
        printf("조건문 (if문)안에 지역변수 %d",num3);
    }
    printf("%d",num3); //에러! 조건문,반복문내에 지역변수는 반복문을탈출하거나 조건문이 끝나면 자동으로 소멸된다.
    return 0;
}
위에 예제를 통해 알수있는건 중괄호안에있는 지역변수는 탈출하거나 중괄호밖으로 나갈때 자동으로 소멸이됩니다.
에러 없이 위에 예제를 컴파일할려면 마지막 printf함수를 지우거나 주석치면 가능합니다.

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main (void){
int num1 = 5;
printf("%d",num1);
if(num1 == 5){
     int num1 = 10;
     printf("%d",num1);
}
    return 0;
}
이러한 형태는 변수이름의 중복도 가능합니다.
같은위치의 지역변수가 아니면 변수이름은 중복이 가능합니다.
어차피 조건문내에서만 쓰고 탈출하면 소멸될것이기 때문입니다.
좀더 정확히말하면 지역변수는 외부에 선언된 동일한 이름의 변수를 가리게 됩니다.

매개변수

함수를 정의할때 선언하는 매개변수도 지역변수의 일종입니다.

매개변수 역시 지역변수의 특징을 나타냅니다.
  • 선언된 함수 내에서만 접근이 가능하다.
  • 선언된 함수가 반환하면,지역변수와 마찬가지로 소멸된다.
매개변수 = 지역변수 같다고 말할 수 있습니다. (다만 모든 지역변수가 매개변수는 아니다.)

전역변수

전역변수는 그이름이 의미하듯이 어디서든 접근이 가능한 변수로써 지역변수와 달리 중괄호 내에 선언이 되지 않습니다.

전역변수는 중괄호 밖에 선언이 됩니다.

전역변수의 특징
  • 프로그램의 시작과 동시에 메모리 공간에 할당되어 종료 시 까지 존재한다.
  • 별도의 값으로 초기화하지 않으면 0으로 초기화된다.
  • 프로그램 전체 영역 어디서든 접근이 가능하다.

1
2
3
4
5
6
7
#include <stdio.h>
int num1; //전역변수이고, 따로 초기화를 하지 않았으므로 0으로 초기화된다.
int main (void){
    int num2 = 0//지역변수
}
    return 0;
}
예제를 보면 num1이라는 변수는 중괄호 밖에 선언되었습니다.
그래서 전역변수입니다. (이때 중괄호 밖은 보통 함수 밖을 말하는것이다.)
결국 변수 num1은 전역변수가 되어버리고 변수 num2은 지역변수입니다.

전역변수는 프로그램의 구조를 복잡하게 만드는 주범입니다.
그래서 전역변수를 선언할때 신중히 생각하고 선언해야합니다.
"전역변수의 수가 증가하면 그만큼 프로그램은 복잡해지며,좋은 구조의 프로그램과는 거리가 멀어지게 된다. 따라서 전역변수의 선언은 그만큼 신중해야 한다."
하나의 전역변수 만으로도 충분히 프로그램이 복잡해질 수 있다는 사실을 알아야 합니다.

static 변수

지역변수에 static선언이 붙게되면 이는 전역변수의 성격을 지니는 변수가 됩니다.

지역변수와 static변수의 특징을 비교하면
지역변수의 특징
  • 선언된 함수 내에서만 접근이 가능하다.
  • 함수 내에 선언된 지역변수는 해당 함수가 반환하면 소멸된다.
static선언이된 지역변수의 특징
  • 선언된 함수 내에서만 접근이 가능하다 (지역변수의 특징)
  • 딱 1회 초기화되고 프로그램 종료 시까지 메모리 공간에 존재한다 (전역변수의 특징)

이렇게 static선언이 붙은 지역변수는 지역변수의특징과 전역변수의특징을 한가지씩 가지게됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
void Func();
int main (void){
  
  for(int i=0;i<3;i++)
  Func();
  
    return 0;
}
void Func(){
    
    static int num1 = 0//static변수는 따로 초기화하지않으면 0으로 초기화됨
    int num2 = 0//지역변수는 따로 초기화하지않으면 쓰레기값이됨
    num1++;
    num2++;
    printf("static:%d , local:%d \n",num1,num2);
}
위에 예제를 컴파일해서 실행해보면 static변수 num1값은 1씩올라가 3이되며 지역변수 num2은 계속 1로 출력이 됩니다.
앞서 말햇듯이 static이 선언된 지역변수는 딱1회 초기화 되고 프로그램 종료 시까지 메모리공간에존재합니다.
하지만 지역변수는 계속 0으로 초기화해주고,증감연산자로 1을 올려주기 때문에 1이 출력되는겁니다.

static변수는 지역변수처럼 함수가호출되어야 변수가 선언되는게 아닙니다.
위치에 상관없이 선언되고, static변수가 함수안에있는 이유는 접근의 범위를 제한하기 위해서입니다.
정리를하면 static변수는 프로그램 실행시 함수가 호출되지 않아도 선언되고 메모리공간에 존재합니다. 그리고 접근의 범위를 제한하는것이다. (선언된 함수내에서만 사용가능)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
void Func();
int main (void){
  
  for(int i=0;i<3;i++)
  Func();
  
    return 0;
}
void Func(){
    
    static int num1 = 0//Func함수에서만 static변수 num1을 사용가능하다.
    int num2 = 0//지역변수도 마찬가지로 Func함수에서만 사용가능하다.
    num1++;
    num2++;
    printf("static:%d , local:%d \n",num1,num2);
}
(주석참고)
결국 static 변수도 지역변수와 같이 선언된 함수에서만 사용이 가능합니다.
따라서 static지역변수를 전역변수를 대체하는일은 없어야하며,전역변수를 static지역변수로 대체할수있다면 대체해서 프로그램의 안정성을 높여야 합니다.


댓글