전역변수와 지역변수
전역변수와 지역변수의 차이점
1. 메모리상에 존재하는 기간
2. 변수에 접근할 수 있는 범위
지역변수
중괄호 내에 선언 된 변수는 모두 지역변수이다. 하지만, 지역변수는 선언된 지역 내에서만 유효하다는 특성을 지닌다.
ex)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include<stdio.h> void SimpleFunc(void); int main() { int n1 = 17; // 이후부터 main의 n1유효 SimpleFunc(); printf("%d\n",n1); return 0; // main의 n1이 유효한 마지막 문장 } void SimpleFunc() { int n1 = 20; // 이후부터 SimpleFunc의 n1유효 n1++; printf("%d\n",n1); return 0; // SimpleFunc의 n1이 유효한 마지막 문장 } |
21
17
SimpleFunc함수의 int형 지역변수 n1은 함수가 종료되는 21번째 문장에서 사라지게 된다. 지역변수는 해당 지역을 벗어나면 자동소멸되기 때문!
또 한, 지역변수는 선언된 지역 내에서만 유효하기 때문에 선언된 지역이 다르면 이름이 같아도 문제가 되지 않는다.
반복문과 조건문에도 지역변수의 선언이 가능하다.
ex)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include<stdio.h> int main() { int cnt; for(cnt=0;cnt<3;cnt++) { int num=0; num++; printf("%d번째 반복, 지역변수 num은 %d. \n",cnt+1,num); } if(cnt==3) { int num=7; num++; printf("if문 내에 존재하는 지역변수 num은 %d. \n",num); } return 0; } |
출력결과
1번째 반복, 지역변수 num은 1.
2번째 반복, 지역변수 num은 1.
3번째 반복, 지역변수 num은 1.
if문 내에 존재하는 지역변수 num은 8.
제일 먼저 5행의 cnt라는 지역변수가 선언되고, 이 지역변수는 main함수의 어디에서든 사용이 가능하다. 하지만 8행의 지역변수 num은 반복문 안에서만 유효한 변수이다. 여기서 중요한 것은 반복이 시작하면서 지역변수가 생성되고, 첫번째 반복이 끝나면서 지역변수 역시 사라지게 된다. 그리고 조건이 참일 때 다음 반복이 이루어 질 때 다시 한번 지역변수가 생성된다. 이렇게 지역변수는 생성 소멸 생성 소멸을 반복하게 된다.
15행의 지역변수 역시 if문이 끝나는 동시에 지역변수는 소멸이 된다.
지역변수는 외부에 선언된 동일한 이름의 변수를 가리게 된다.
함수를 정의할 떄, 선언하는 매개변수도 지역변수의 일종이다.
매개변수의 특성
1. 선언된 함수 내에서만 접근이 가능하다.
2. 선언된 함수가 반환을 하면, 지역변수와 마찬가지로 소멸이 된다.
전역변수
전역변수는
1. 중괄호에 포함되지 않는다.
2. 프로그램의 시작과 동시에 메모리 공간에 할당되어 종료 시까지 존재한다.
3. 별도의 값으로 초기화하지 않으면 0으로 초기화된다.
4. 프로그램 전체 영역 어디서든 접근이 가능하다.
ex)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include<stdio.h> void Add(int val); int num; // 전역변수는 기본 0으로 초기화 됨 int main() { printf("num;%d \n",num); Add(3); printf("num;%d \n",num); num++; printf("num;%d \n",num); return 0; } void Add(int val) { num += val; } |
출력결과
num;0
num;3
num;4
전역변수와 동일한 이름의 지역변수가 선언된다면, 해당 지역 내에서는 전역변수가 가리워지고, 지역변수로의 접근이 이루어진다.
전역변수와 지역변수의 이름은 달리하는 것이 좋다.!!
전역변수의 수가 증가하면 그만큼 프로그램은 복잡해지며, 좋은 구조의 프로그램과는 거리가 멀어지게 된다. 따라서 전역변수의 선언은 그만큼 신중해야 한다.
static지역변수
지역변수에 static을 붙이게 되면 전역변수의 성격을 갖게 된다.
지역변수의 특성은 선언된 함수 내에서만 접근이 가능하고, 함수 내에 선언된 지역변수는 해당 함수가 반환되면 소멸이 된다.
하지만 함수 내에 선언된 지역변수에 static을 붙이게 되면
선언된 함수 내에서만 접근이 가능하고, 딱 1회 초기화되고 프로그램 종료 시까지 메모리 공간에 존재한다.
ex)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include<stdio.h> void SimpleFunc(void) { static int num1 = 0; // 초기화하지 않으면 0으로 초기화 int num2 = 0; // 초기화하지 않으면 쓰레기 값 초기화 num1++; num2++; printf("static:%d, local:%d \n",num1,num2); } int main() { int i; for(i=0;i<3;i++) { SimpleFunc(); } return 0; } |
static:1, local:1
static:2, local:1
static:3, local:1
static지역변수는 초기화하지 않으면 전역변수처럼 0으로 초기화되고, 프로그램 시작과 동시에 할당 및 초기화되어서 프로그램이 종료될 때까지 메모리 공간에 남아있는다. SimpleFunc에 선언된 이유는 접근의 범위를 SimpleFunc로 제한하기 위해서이다.
5행의 static int num1 = 0 이 문장은 맨 처음 프로그램이 시작될 때, 선언이 되고 이후에는 존재하지 않는것처럼 보아야한다.for문으로 3번 돌릴 떄, 0으로 초기화가 3번이 되지 않고 맨 처음 한번만 0으로 초기화가 된다. 존재하지 않는 것처럼 보라는 뜻이다?
(메모리 상에는 거주하고 있고, 다른 함수에서는 사용할 수 없고, 프로그램이 끝날 때까지 메모리공간에 남아있는다.)
register변수
ex)
1 2 3 4 5 | void SimpleFunc(void) { register int num=3; ... } |
위처럼 register라는 선언이 추가된 변수 num은 cpu내에 존재하는 레지스터라는 메모리 공간에 저장 될 확률이 높아진다.
그 이유는 빈번히 사용 할 것이니, 접근이 가장 빠른 레지스터에 저장하는 것이 성능향상에 도움이 될 것이야! 라는 힌트를 컴파일러에게 전달하는 선언이기 때문이다.
레지스터는 cpu내에 존재하는 크기가 매우 작은 메모리이다. 하지만 cpu내에 존재하기 때문에 메모리에 저장된 데이터를 대상으로 하는 연산은 매우 빠르다. 바로 이러한 레지스터의 활용과 관련해서 컴파일러에게 힌트를 주는 선언이 바로 register선언이다.
'programming > C' 카테고리의 다른 글
C // 1차원배열 (0) | 2017.12.18 |
---|---|
C // 재귀함수 (0) | 2017.12.16 |
C // 함수 (0) | 2017.12.13 |
C// 조건에 따른 흐름의 분기 (0) | 2017.12.11 |
C // 반복문 (0) | 2017.12.07 |