전역변수와 지역변수는 많이 들어볼 용어이다.
지역변수는 함수 안에서 선언하여 사용하는 변수이고,
전역 변수는 지역변수와 다르게 전체에서 사용한다는 의미로 받아들인 다면, 간단하게 이해가 가능하다
실제 코드에서도 사용하기 어렵지 않다.
간단한 예시를 들어본다면
string globalVar;
void test()
{
string localVar;
}
위치만 바뀐다고 생각해도 괜찮을 정도이다. (물론 문법이 추가될 수는 있다.)
그러면 정적(Static) 변수는 무엇인지, 전역변수랑 차이가 뭔지 알아보려고 한다.
(지역변수는 따로 정리하지 않아도 될 것 같아서 패쓰 😀)
개념에 대한 설명은 아래에 자세히 적을거고,
급한 분들을 위해 어떻게 쓰는지만 먼저 정리하자면
1. 전역 변수 사용
extern string globalVar;
2. 정적 변수 사용
static int globalVar;
이렇다.
- 전역변수란?
- 정적변수란?
1. 전역변수 (Global Variable)란?
위키백과: 전역 변수는 어떤 변수 영역 내에서도 접근할 수 있는 변수를 의미하는 전산학 용어이다. 지역 변수와 대비되는 개념이다.
전역변수는 말 그대로 전역에서 사용하는 변수이다
메모리 영역의 개념에서는 데이터 영역에 포함되는 친구이다
프로그램이 시작되어 메모리에 할당이 되면, 죽을 때까지 계속 메모리에 남아있는 친구이기도 하다
사실, 전역변수는 웬만하면 사용하지 않는게 사실 제일 좋다 (이유는 글 하단에 코멘트로 얘기하겠다)
전역 변수에 대해 아래의 코드로 예시를 간단히 들겠다
/* main.cpp */
#include <iostream>
using namespace std;
string globalVar;
void func1()
{
globalVar = "Hi";
}
void func2()
{
globalVar = "Bye";
}
int main(void)
{
func1();
func2();
cout << globalVar << "\n";
return 0;
}
누가봐도 globalVar가 전역 변수로 보인다
이야~ 정말 간단하네요~
하지만 우리는 위에 예시처럼 모든 함수를 하나의 파일에 넣어두지 않는다
또는 헤더파일과 소스 파일을 분리해서 사용한다 (전역변수를 사용하는 이유기도 하다)
예를들어,
main.cpp, variable1.cpp, main.h 이렇게 구성되어있다고 가정해보자
main.h
#include <iostream>
using namespace std;
string globalVar;
void func1();
void func2();
void func3();
main.cpp
#include "main.h"
using namespace std;
int main(void)
{
func1();
func2();
func3();
cout << globalVar << "\n";
return 0;
}
variable1.cpp
#include "main.h"
void func1()
{
globalVar = "My name is func1";
}
void func2()
{
globalVar = "My name is func2";
}
void func3()
{
globalVar = "My name is func3";
}
main.cpp 파일에서 정의했던 globalVar을 헤더 파일에 옮겨서 해보았다
옮기기만 하면 되는건가~ 놉
인생은 항상 호락호락하지 않다
release/variable1.o:(.bss+0x0): multiple definition of `globalVar'
release/main.o:(.bss+0x0): first defined here
위와 같은 에러를 만날 수 있다
왜냐면, 변수를 구현 파일에서 정의할 때 파일 마다 새로운 인스턴스가 생성되기 때문이다
그래서 main.cpp와 variable1.cpp에서 중복되어 globalVar라는 변수의 인스턴스가 생성되어 에러가 난거다
이를 방지하기 위한 장치가 하나 있다
변수 앞에 " extern "이라는 것을 추가해주면 된다
extern string globalVal;
요렇게 써주기만 하면~
release/variable2.o: In function `func1()':
CPP_PRAC/variable/variable2.cpp:5: undefined reference to `globalVar'
? 다른 에러가 떠서 잠시 당황하면 됩니다
왜 undefined reference (정의되지 않은 참조) 라는 에러가 뜨냐면
extern은 단어 뜻대로 외부에서 쓸 수 있다라고 알려주기만 한거라서
extern 변수를 정의가 아니라 선언만 해준거라서 그렇다
그냥 globalVal라는 이름이 있어~~ 사용할려면 사용해~~ 이거라서,
메모리 공간에는 할당이 되지 않은거다 (→ 선언만 되어있다고 흔히 얘기한다)
그래서 정의되지 않은 값이라는 에러를 뱉은 것이다
그러면 말 그래도 정의가 안되어있어서 문제라고 하니, 사용하려는 전역 변수를
파일에 정의해주면 되는거다
variable1.cpp
#include "main.h"
/* 전역변수로 선언 */
string globalVar;
void func1()
{
globalVar = "My name is func1";
}
void func2()
{
globalVar = "My name is func2";
}
void func3()
{
globalVar = "My name is func3";
}
이렇게! 해주면 컴파일이 되는 것을 볼 수 있다
2. 정적변수 (Static Variable)란?
정적변수는 전역변수처럼 프로그램 시작시 할당되어 죽을 때까지 메모리에 남아있다
또한 일반 전역변수처럼 (extern 사용하지 않는) 한번 선언해주면 편한 친구이다
보통 클래스에서 멤버 변수로 놓고 많이 사용하는데, 그건 다음에 다시 다루려고 한다
정적변수는 지역변수랑 비교하는게 더 알기 쉽다
지역변수 사용
#include "main.h"
using namespace std;
int func1()
{
int globalVar = 1;
return globalVar++;
}
int main(void)
{
cout << func1() << endl;
cout << func1() << endl;
return 0;
}
지역변수 사용 결과
1
1
정적변수 사용
#include "main.h"
using namespace std;
int func1()
{
static int globalVar = 1;
return globalVar++;
}
int main(void)
{
cout << func1() << endl;
cout << func1() << endl;
return 0;
}
정적변수 사용 결과
1
2
차이가 보이는가,,,,,
메모리에 계속 할당되기 때문에, 함수 범위안에서 사용하였어도
정적변수 키워드인 " static "으로 인해, 메모리에 globalVar라는 값이 계속 남아있어서
값이 초기화 되지 않고 증가 하였다
(extern 변수처럼 다른 파일에서도 쓸 수 있는거는 아님)
엑 static int globalVar =1; 이거로 매번 초기화 되는거 아닌가욤?
할 수 있는데, 처음 메모리에 자리 잡을 때만 사용된 초기화 값이라서
매번 초기화 되지는 않는다
사실 정적 클래스 멤버변수가 아닌 그냥 정적변수는 다룰 내용이 많지 않다
그래서 끝
전역변수는 사용시에
언제 내가 저장한 값(globalVar)이 변경되었는지, 어떤 값을 써야하는지도 모르기에..
잘 안쓰는 것이 좋다..
하지만 잘 쓴다면, 사용하기에 너무 편하고, 꼭 사용해야할 경우도 있다
모든 스레드와 함수에서 공유해야할 값이 있을 수도 있고
처음 프로세스가 실행되고, 바뀌지 않을 값을 설정해 놓을 수도 있다
예를 들어, 환경파일을 같이 사용할 때 사용하는 값을 로드할 때? 정도.
또는 값 변경이 될 것이란 걸 알고서, 뮤텍스 같은 장치를 사용하여 쓸 수도 있다
하지만 처음 개발 시작할 때는 좋지 않은 습관이라서, 염두만 해두면 좋을 듯 하다 ㅎㅎ
위키백과
ko.wikipedia.org/wiki/%EC%A0%84%EC%97%AD_%EB%B3%80%EC%88%98
전역 변수 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전.
ko.wikipedia.org
메모리 구조
[컴퓨터 기초] 메모리구조(Memory Structure) - jinShine
프로그램 실행 순서 메모리 영역에 관해 이야기하기 전에 어떤식으로 프러그램이 실행되는지 과정을 살펴 보겠습니다. 프로그램의 정보를 읽어 메모리에 로드되는 과정을 보실 수 있으실텐데,
jinshine.github.io
multiple definition 에러 참고
stackoverflow.com/questions/14526153/multiple-definition-of-a-global-variable
Multiple definition of a global variable
Possible Duplicate: constant variables not working in header In my header file which I use to create a shared object, I have the following: #ifndef LIB_HECA_DEF_H_ #define LIB_HECA_DEF_H_ st...
stackoverflow.com
undefined reference 에러 참고
extern 변수를 사용하자.
unix나 linux에서 extern을써서 프로그램을짯는데 undefined오류가 나더라구요 우선 간단하게 소스를 보여 드리겠습니다. head.h 내용 ----------------------- #include extern int a; temp.c내용 --------------..
sunder4.tistory.com
'BackEnd > C랑 C++' 카테고리의 다른 글
Boost Asio에 대해서 알아보자 (6) | 2021.05.20 |
---|---|
C++ 클래스 멤버변수 초기화를 알아보자 (4) | 2021.03.25 |
C++ 대문자/소문자 변환 (4) | 2021.02.26 |
C++ Function Object (함수 객체)를 알아보자 (4) | 2021.01.22 |
C++ std::map을 사용해보자 (4) | 2021.01.07 |