전역 변수, 정적 변수

Yama·2023년 12월 6일
0

어소트락 수업

목록 보기
7/55

지역 변수

  • 해당 함수가 호출되면 함수 스택에 존재하는 변수
  • 서로 다른 함수의 지역변수에 접근이 불가능하다. (포인터 예외)
int Test()
{
	int i = 0;
	++i;

	return i; 
}

int main(void)
{
	int i = 0;

	Test();

	Test();
    
    Test();
}
  • 스택메모리에 지역 메모리가 만들어지고 생기고 3번반복한다.
  • 나는 이 3번 했다는걸 표현 하고 싶다.
    • 지역변수만을 활용해서 불가능하다.
    • 지역변수는 저 Test함수가 스택에서 사라질때마다 값이 증발하기 떄문이다.
  • 그래서 전역변수를 사용하면 가능하다.

데이터 영역

  • 전역변수와 정적변수가 존재한다.
  • 프로그램의 시작시 초기화, 프로그램의 종료시 해제(프로그램 실행 도중 유지되는 공간)

전역변수

  • 함수(지역) 호출과 종료에 상관없이 유지되는 변수
  • 데이터 영역 메모리에 존재한다
  • 모든 함수에서 접근 가능
int Global = 0;

int Test()
{
	++Global;

	return Global;
}

int main(void)
{
	Test();

	Test();

	int Call = Test();
    
    int a = Global;
    
    // Global = 100;
}
  • 이건 이제 함수 호출횟수를 알수 있다.
    • 전역변수는 스택메모리영역이 아닌 데이터 영역에 있기 떄문이다.
  • Test함수는 명령어가 호출하면 스택이 생기지만 지역변수는 존재하지않고 데이터 영역에 있는 Global(전역변수)변수가 1증가하고 테스트함수는 해제된다.
  • 볼때마다 메모리 상태 그려보기.
int a = Global
  • 데이터 영역에 있는 Global 변수의 값을 메인함수가 있는 스택 영역에 있는 a지역 변수에 값을 넣어라.

전역변수의 문제점

  • 위의 코드에서 Global = 100;을 해버린다면 글로벌 변수의 원래의도(테스트함수 호출횟수)와 다르게 해석될 수 있다.
    • 3이 100으로 변함.
  • 이문제를 해결할려고 정적 변수를 사용한다.

정적 변수(static)

  • 데이터 영역 메모리에 존재한다.
  • 선언된 곳에서만 사용가능하다.
// 테스트 함수 호출 횟수.
int Test()
{
	static int myglobal = 0;
	++myglobal;

	Global_static = 100;
	return myglobal;
}

int main(void)
{
	Test();

	Test();

	int Call = Test();

	// myglobal 오류 발생. 

	Global_static = 100;

	return 0;
}
	static int myglobal = 0;
  • static 키워드가 붙었으므로 지역변수가 아니라 정적 변수이다.
	static int myglobal = 0;
  • 초기화는 1번만 수행된다. 그래서 두번쨰 세번쨰 수행될때는 수행되지않는다.
	myglobal 오류 발생. 
  • 메인 함수에서 myglobal 접근할려하면 오류 발생한다

전역변수와 정적 변수의 차이점

int Global = 0;

static int Global_static = 0;

int main(void)
{
	
    return 0;
}
  • 이런식으로 접근하면 한 파일(.cpp)를 할때는 같아보이지만 여러 파일을 다를때는 다르다.
  • 알려면 함수 선언과 정의를 알아야함.

함수의 선언

int Add(int, int);

함수의 정의(구현)

	int Add(int a, int b)
	{
		return a + b;
	}

함수 선언을 안하고 구현을 아래에다하는 경우.

	int main(void)
    {
    	int i = Add(10, 20);
        
        return 0;
    }
	int Add(int a, int b)
	{
		return a + b;
	}

  • 컴파일 오류 발생
  • 위의 선언이나 구현부분이 위에 없고 아래쪽에 있기떄문에
    • 컴파일러는 위에서 아래로 코드를 본다.

함수 선언을 위에다 하고 아래에 적는 경우.

	int Add(int, int);
	int main(void)
    {
    	int i = Add(10, 20);
        
        return 0;
    }
	int Add(int a, int b)
	{
		return a + b;
	}
  • 위에 함수 선언이있어서 컴파일러는 Add함수 구현부분이 어디가에는 있을거라고 믿고 컴파일을 한다.(오류x)
  • 컴파일후 링킹 과정에서 이걸 다 연결해준다.

함수 선언만 하고 구현부분이 없을 경우.

	int Add(int, int);
	int main(void)
    {
    	int i = Add(10, 20);
        
        return 0;
    }

  • 링킹 오류 발생
  • 컴파일러가 Add함수가 있다고 믿고 컴파일은 통과히자만 이걸 연결하는 링킹 과정에서 구현이 없기때문에 문제가 발생한다.

선언과 구현을 한 파일에다가 분리하면 안좋은 이유?

  • 구현과 선언을 분리하는것도 중요하지만 우리가 지금은 파일 하나에서만 코드를 작성한다.
  • 나중가면 cpp파일 규모가 존나 커진다.
  • 문제는 cpp파일은 용량이 제한이 걸린다.
    • 컴파일할떄 컴파일 실패가 뜰수 있당.
  • 게임만들떄 선언과 구현을 분리하면 파트를 담당해서 파일을 분리해서 만들수 있당.
    • 파트분할해서 능률 높아짐.

강의 코드

#include <iostream>

int Global = 0;

static int Global_static = 0;


// 테스트 함수 호출 회수
int Test()
{
	++Global;
	++Global_static;

	static int myglobal = 0;
	++myglobal;

	return myglobal;
}


int Add(int, int);


int main()
{	
	Test();

	Test();

	Global = 100;
	Global_static = 100;
	// myglobal = 0;

	int Call = Test();

	int i = Add(10, 20);
	
	
	return 0;
}


int Add(int a, int b)
{
	return a + b;
}

1차 23.12.06
2차 23.12.07
3차 23.12.08
4차 23.12.11
5차 23.12.17
6차 23.12.24
7차 24.01.01
8차 24.01.22

0개의 댓글