평생 공부하는 빠타박스 블로그 : Learning is Happiness
article thumbnail
SMALL

- "본 내용은 Inflearn에 Rookies 강사님의 강의로 학습하고 있는 내용입니다."-


>>>>> 이전 내용 :  비트 연산과 비트플래그


> 전체코드

 

더보기

전체코드

/*const와 메모리구조*/
#include <iostream>
using namespace std;

// 주제 : 데이터 연산

unsigned char flag; // 부호를 없애야 >> 하더라도 부호비트가 딸려오지 않는다.

// 한번 정해지면 절대 바뀌지 않을 값
// constant 의 약자 const를 붙임 (변수를 상수화 함)
// const를 붙이면 초기값을 반드시 지정해야 한다.

/* 보통 바뀌지 않는 값을 대문자로 표현하는 코딩컨벤션을 지키는 팀들이 있다. */


// const도 바뀌지 않는 읽기전용
// .rodata?
// 실제로 C++ 표준에서 꼭 그렇게 하라는 말이 없다.
// 컴파일러 마음대로(VS) 작동한다. 그러니 잘 모른다.
const int AIR = 0;
const int STUN = 1;
const int POLYMORPH = 2;
const int INVICIBLE = 4;

// 전역 변수

// [데이터영역]
// .data (초기값 있는 경우)
int a = 2;

// .bss (초기값 없는 경우)
int b;

// .rodata (읽기 전용 데이터)
const char* msg = "Hello World";


int main()
{
	// [스택 영역]
	int c = 3;


#pragma region const
	// 0b0000 [무적][변이][스턴][공중부양]

	/*무적상태*/
	flag = (1 << INVICIBLE);

	/* 변이 상태를 추가 (무적 + 변이) */
	// flag |= 4; // 이것도 가능하겠지만.
	flag |= (1 << POLYMORPH);

	// 무적인지 확인하고 싶다? (다른 상태는 관심 없음)
	// bitmask : 필요 없는 부분은 가린다.
	bool bInvisible = ((flag & (1 << 3)) != 0);

	// 무적이거나 스턴 상태인지 확인하고 싶다면?
	bool bStunOrInvicible = ((flag & 0b1010) != 0);


#pragma endregion
}

 

 

기존 코드에 쓴 상태에 대해 작성된 것을 보면 언제든지 누군가 들어와서 바꿔버릴 수 있다.

 

모든 코드에 숫자로 떄려 박아있으면 나중에 해당 하는 부분을 고쳐야 할 때 직접 일일히 찾아서 해야 할 수도 있다. 

flag = (1 << 3) 형식으로 하드코딩 되어있으면. 어떻게 해야할까?

 

 

 이거 자체를 하나의 상수 값으로 만들어서 넣어주는 편이 더 안전하다.

 

대문자를 쓴 것은 회사마다 다르지만 바뀌지 않는 상수값 표현시 대문자로 표현한다.

 

해당 코드 안에 변수의 이름을 넣어 처리할 수 있게 되었다.

  • 하지만 저런식으로 하게되면 어디서든 변경이 가능해져 버린다... 그래서 한가지 추가하는 것이다. 
// 다른 위치 변경 가능성이 있음.
INVICIBLE = 4;

 

그래서 절대 바뀌지 않는 값이라면 앞에 const 를 넣어주는 것이 좋다. 그러면 수정하려고 할 때 error가 발생한다.

const int AIR = 0;
const int STUN = 1;
const int POLYMORPH = 2;
const int INVICIBLE = 3;

// 0b0000 [무적][변이][스턴][공중부양]

또 이런식으로 처리하게 되면 중간에 상태를 추가한다 했을 때

// 0b0000 [무적][공포][변이][스턴][공중부양]

const int AIR = 0;
const int STUN = 1;
const int POLYMORPH = 2;
const int FEAR = 3
const int INVICIBLE = 4;
  • 중간에 저런식으로 끼워 넣어서 처리하면 좀 더 간단히 변경이 가능하고 컴파일러가 알아서 처리해줄 것이다. 
const를 사용시 반드시 초기값을 붙여주자 (어차피 안붙이면 Error가 발생한다)

 

 

변수 위치에 따른 영역

전역 변수

함수 밖에서 선언된 변수들은 어셈블리에서 데이터영역이 BSS(전역변수) 메모리 영역에 잡아서 하는 것들이 함수 밖에 선언했을 때 똑같이 이루어진다.

 

참조

 

전역변수는 어디서든 불러올 수 있다.

  • Data영역은 : 3가지로 분류된다. bss영역, 일반데이터영역, readonlydata 영역

일반적인 전역변수는 데이터 영역에 올라간다.

프로시저::함수 : 비슷한 기능들을 묶어서 만든(프로시저:어셈블러)

 

 

 

전역으로 설정된 각 값들은 해당 영역별로 들어가게 된다.

앞에 16진수로 이루어진 주소 값을 메모리에서 찾아보면

b영역도 bss영역

 

 

포인터로 선언한 부분도 영역내 rodata 영역에 helloWorld라고 표시된 것을 볼 수 있다.

 

 

지역변수

Rookies 강의 참조 : Stack Memory

  • 함수 내부에 변수를 설정하게 되면 이제 완전 다른 변수가 된다.
  • 지역변수는 스택영역에 잡히게 된다.
  • Stack Memory
    • 함수에서 먼가 인자를 넘기기 위해서 사용된다.
    • 내부적으로 돌아갈 return 코드 장소도 저장 어떤 함수콜을 하고 돌아갈 코드를 Stack에 저장한다.
    • 함수내부에서 일시적으로 저장할 값들이 생기면 stack에 메모장 처럼 잠깐 쓰이는 곳이 있다. Stack Frame 함수내 만들어진 변수들이 잠시 stackframe에 저장되어있다.
    • 함수 호출이 끝나면 접근이 유효해지지 않고, 원래 상태로 돌아간다.

 

int main()
{
		int c = 3;
}

선언한 지역변수를 보면 나머지와 다르게 시작 주소가 좀 다르다.

스택 관련된 메모리는 ebpesp레지스터에 저장되어있으니까.

 

esp나 ebp영역을 보면 해당 주소값 위치가 거의 인접한 것을 볼 수 있다. (좀더 EBP영역에 있는 듯 하다)

 

그래서 어떤 코드를 짤 때 어떤 선언을 할 때 C++에서는 반드시 책임이 따른다. 

 

C#은 알아서 처리해주지만. C++은 그렇지 않다.

 

포인터와 같은 것을 하게되면 C++에서 어디서든 접근하는게 편해진다. 즉 잘못해서 스택을 망가트려 놓으면 정말 위험할 수 있다. 그래서 스택에 문제가 생길 수 있기에 조심하자.

 

 

전역변수로 선언된 것에 대한

//선언된 const
const int INVICIBLE = 4;

실제로 조사식을 통해 확인해 볼 수 없다라고 뜬다.

이게 메모리에 할당이 되지 않았다는 것이다.

 

 

위 사진 처럼 그냥 컴파일러가 바꿔 버리는 것이다. 스택영역에 할당 된 것이긴 하나. 

그냥 코드상에만 존재하고 컴파일된 다음에 해당 값으로 치환한다고 보면 된다.

뭔가 있기는 한데. 그냥 바로 바꿔져서 4번 옮겨진 16이 나오게 되는것을 알 수 있다. 

 

 

int main()
{
	const int AIR = 0;
	const int STUN = 1;
	const int POLYMORPH = 2;
	const int INVICIBLE = 4;
}

이 내용을 함수 내부에 넣어주면 또 다르게 작동한다.

 

 

기본적으로 로컬(지역변수) 데이터들은 외부에서 사용할 수 없어야 하기 때문에,

스택에 만들어줘서 처리할 수 있게 하는 것이다.

 

 

실제로 함수내에 설정된 int 정수형 변수 하나를 다른 함수에서 사용할 수 없다. 

예를 들어 

int main()
{
	int a;
}

void f_Test(int b)
{
	a = 3;
}

// 당연히 말도 선언되지도 않은 a값을 f_Test에서 사용한다는 것은 말이 안된다. 뭐 ..
// 아래와 같은 경우면 모를까 아래는 그냥 함수에 인자에 값을 넣어 temp변수에 넣어준것... 

int main()
{
	int a;
    f_Test(a);
}

void f_Test(int b)
{
	int temp = b;   
}

 

 

728x90
728x90
LIST
profile

평생 공부하는 빠타박스 블로그 : Learning is Happiness

@공부하는 PPATABOX

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!