tip) 무언가 존재한다면 그것은 위치가 있어야함
-> 공짜는 없고 모든건 메모리를 사용해야 한다 -> 위치가 있어야 한다
R-Value && L-Value
ex)
int main() { int Left = 1; int Right = 2; // Left -> L-Value // Right -> L-Value // 눈에 보이지 않는 결과값이 존재 (Left +Right); // -> R-Value }

변수
- ex)
int main() { int Left = 1; }
- 위치 : main 실행 스택안에 들어있음
1-1. 위치 : 1000번지(예시)- 크기 : 4 바이트
- 형태 : 정수
- 값 : 1
return
int Test()
{
return 10;
}
int main()
{
int Left = 1;
Left = Test();
}

void ParameterStart(int Value)
{
Value = 9999;
}
int main()
{
int TestValue = 10;
ParameterStart(TestValue);
}




자료형이 다르면 대입이 되면 안되야 한다 (기본)
될때가 있고 안될때가 있음
2-1. 암시적 형변환 = 자료형이 다른데 대입이 문법적으로 혀용되는 것
-> 최대한 피할 것
명시적 형변환
int main()
{
int Value = 0;
bool Check = (bool)Value;
}
int main()
{
int Value = 0;
bool Check = static_cast<int>(Value);
}
-> 값 <-> 참조형 (reinterpret_cast<>)
int main()
{
int Value = 100;
int* ptr = &Valaue;
__int64 Address = reinterpret_cast<__int64>(Ptr);
}
cf) Char
cf) bool
cf) 참조형 & 값
tip) 자료형이 다른데 대입했다 -> 어떤일이 벌어지는지 확실히 알고 해야함\
ex)
int main()
{
// 자료형이 다를때 안되게 막는 예시
int Value = 0;
int* IntPtr = Value; // (오류)
// 자료형이 달라도 대입이 가능한 예시
int ;
int64;
}
- 일반적인 대입이 안된다.
-> 특정 메모리 영역의 주소값을 리턴해 달라는 단항 연산자(&)를 사용해야 함ex) 정수라고 해서 정수를 넣어주면 대입이 안된다
int Value = 0; int* ValuePtr = Value; // 틀린것 int * ValuePtr = &Value; // 맞는것
cf)
int Value = 0; int* ValuePtr = Value; // 틀린것 int** ValuePtrPtr = &ValuePtr;
ex)
int main()
{
// 포인터
int* ValuePtr;
}
#include <iostream>
// 함수 밖에서는 아무런 영향이 없음
void Damage(int _Hp, int_Att)
{
_Hp = _Hp - _Att;
}
int main()
{
{
int MonsterHp = 100;
Damage(MonsterHp, 10);
}
}
-> Damage 내부의 변수는 바깥에 존재하는 MonsterHp와 완전히 다른 개체(복제한 것)
이녀석은 이녀석이다 라고 할 수 있는것은 주소가 같은 것
포인터는 변경이 가능하다
-> 중간에 자신이 가리키는 대상을 바꿀수 있음
int main()
{
int Value0 = 10;
int Value1 = 20;
int* Ptr = &Value0;
*Ptr = 1000;
// Value0 = 1000;
Ptr = &Value1;
*Ptr = 2000;
// Value1 = 2000;
}
#include <iostream>
int main()
{
// 위치100번지
// 크기 4바이트
// 형태 int
// 값 200
int MonsterHp = 200;
// 위치 120번지
// 크기 8바이트
// 형태 int*
// 값 100번지
int* MonsterHpPtr = &MontserHp;
*MonsterHpPtr = 50;
// 내가 가진 번지 값의 값이 된다
// 변수명 앞에 *을 붙이면 해당 변수의 자료형에서 *을 뺀다.
// ex) int* MonsterHpPtr (int*형)
// -> *MonsterHp (int형)
}
int main()
{
int MonsterHps[5] = { 11, 22, 33, 44, 55 };
int* Ptr = MonsterHps;
int MonsterHp1 = Ptr[0];
int MonsterHp2 = Ptr[1];
int MonsterHp3 = Ptr[2];
int MonsterHp4 = Ptr[3];
int MonsterHp5 = Ptr[4];
}
int main()
{
int MonsterHps[5] = { 11, 22, 33, 44, 55 };
int* Ptr = MonsterHps;
int MonsterHp0 = *(Ptr + 0);
int MonsterHp1 = *(Ptr + 1);
int MonsterHp2 = *(Ptr + 2);
int MonsterHp3 = *(Ptr + 3);
int MonsterHp4 = *(Ptr + 4);
}
!!포인터는 배열이 아니다!!
int main()
{
int MonsterHps[5] = { 11, 22, 33, 44, 55 };
int* Ptr = MonsterHps;
int ArrSize = sizeof(MonsterHps); // 20Byte
int PtrSize = sizeof(Ptr); // 8Byte
}
-> 0번지
-> 자료형 : nullptr_t
int main()
{
int* Ptr = 0;
*Ptr = 100; // 오류 발생
}
프로그램 메모리 크러쉬 1순이 (Nullptr Exception / Null Reference Exception)
=> 사용하지 말것! -> C++ 11버전 이후로 0 대신 nullptr을 사용
C++ 스타일
int main()
{
int* Ptr = nullptr;
}
cf) 포인터 -> 주소값을 찾거나 아직 가리킬 대상을 찾지 못한 경우 존재
int main()
{
int Value = 0;
int* Ptr = &Value;
int SizePtr = sizeof(Ptr);
// 포인터의 크기 = 8Byte
int& Ref = Value;
int SizePtrValue = sizeof(*Ptr); // 주소값 안에 들어 있는 int 크기 = 4Byte
int SizeRef = sizeof(Ref); // => *Ptr과 같은 뜻
// *Ptr의 크기인 int의 크기 = 4Byte
}
int main()
{
int& ErrorRef; // 값이 들어오지 않아 오류
int MonsterHp = 100;
int& Ref = MontserHp;
int* Ptr = &MonsterHp;
// 항상 *이 붙어 있는 상태
Ref = 100; // -> *Ptr = 100;
Ref = 200; // -> *Ptr = 200;
Ref = 300; // -> *Ptr = 300;
}
int main()
{
int Value0 = 10;
int Value1 = 20;
int& Ref = Value0;
Ref = 1000;
// Value0 = 1000;
// Value1은 변경되지 않음/
Ref = Value1;
Ref = 200;
}
int MonsterHps[5]
-> MonsterHps는 int[]형(int 배열형)
초기화 방법
-> {}안에 값을 넣어서 초기화
-> int MonsterHps[5] = { 11, 22, 33, 44, 55 };
제로 베이스
-> 배열의 시작은 0부터 시작
int main()
{
int MonsterHps[5] = { 11, 22, 33, 44, 55 };
int MonsterHp1 = MonsterHps[0];
int MonsterHp2 = MonsterHps[1];
int MonsterHp3 = MonsterHps[2];
int MonsterHp4 = MonsterHps[3];
int MonsterHp5 = MonsterHps[4];
}
int main()
{
int MonsterHps[5] = { 11, 22, 33, 44, 55 };
// Ref == MonsterHps[0] -> MonsterHps[0] == int&
int& Ref = MonsterHps[0];
}
void Test(int _Value0, int _Value1, int _Value2, int _Value3)
{
__int64 Address0 = reinterpret_cast<__int64>(&_Value0);
__int64 Address1 = reinterpret_cast<__int64>(&_Value1);
__int64 Address2 = reinterpret_cast<__int64>(&_Value2);
__int64 Address3 = reinterpret_cast<__int64>(&_Value3);
}
int main()
{
int Value0 = 10;
int Value1 = 20;
int Value2 = 30;
int Value3 = 40;
Test(Value0, Value1, Value2, Value3);
}
-> 주소가 이어져 있다 (int포인터의 크기 8바이트 씩 떨어져 있음)