포인터
포인터는 메모리 주소를 저장하는 변수로 변수의 주소를 갖는 하나의 타입이다.
포인터의 운영체제의 크기에 따라 4바이트 혹은 8바이트로 나뉜다.
포인터 기본
포인터는 타입 뒤에 *을 붙여 선언하고 &를 사용하여 주소를 추출해 포인터 변수에 담는다.
포인터 변수의 원본 값을 변경하기 위해서는 *을 붙여 변수 값을 수정할 수 있다. 이때 *을 포탈이라고 생각하고 주소를 가지고 있는 포인터 변수의 주소를 이용해 원본데이터로 접근하여 데이터를 변경해 준다.
int num = 10; // 정수 변수 선언 및 초기화
int *ptr; // 포인터 변수 선언
ptr = # // num 변수의 주소를 포인터에 할당
// 포인터를 통해 num 변수의 값을 출력
std::cout << "num 변수의 값: " << *ptr << std::endl;
포인터 함수
포인터를 함수에 적용하면 값을 복사하지 않아도 되는 장점이 존재한다.
이는 값을 복사하지 않기 때문에 메모리적인 이점을 얻을 수 있다.
이렇게 포인터로 구조체를 받아 안에 원본 매개변수를 접근할 때는 ->를 사용하여 접근할 수 있다. ->를 풀어서 쓴다면 (*info). Id로 쓸 수 있다.
struct Info
{
int Id;
int pwd;
};
int main()
{
Info info1;
info1 = CreateInfo1();
Info info2;
CreateInfo2(&info2);
}
Info CreateInfo1()//포인터 사용안했을 때
{
Info ret;
ret.Id = 100;
ret.pwd= 100;
return ret;
}
void CreateInfo2(Info* info)
{
info->Id = 150;//(*info).Id = 150 과 같다
info->pwd = 10;//(*info).pwd = 10 과 같다
}
포인터 함수와 *const
포인터를 매개변수로 갖는 함수에서 const를 *뒤에 붙일 수 있다. 이렇게 하면 해당 포인터 매개변수의 주소를 수정할 수 없음을 의미한다.
void CreateInfo2(Info* const info)
{
info +=1;// 주소값을 변경할 수 없다.
info->Id = 150;// 데이터 변경 가능
info->pwd = 10;// 데이터 변경 가능
}
포인터 함수와 const *
포인터를 매개변수로 갖는 함수에서 const를 *앞에 붙일 수 있다. 이렇게 하면 해당 포인터 매개변수가 가르키 데이터를 수정할 수 없다.
void CreateInfo2(const Info* info)
{
info->Id = 150;// 데이터 변경 불가능
info->pwd = 10;// 데이터 변경 불가능
info += 1;// 주소값을 변경할 수 있다.
}
참조
변수 또는 객체에 대한 별칭(alias)을 제공하는 개념입니다. 참조를 사용하면 기존 변수 또는 객체에 대해 별칭을 만들어 코드를 더 간결하고 읽기 쉽게 만들 수 있습니다.
참조기본
타입 뒤에 &를 사용하여 참조를 선언할 수 있다.
int num = 10; // 정수 변수 선언 및 초기화
int &ref = num; // 참조 변수 선언 및 초기화
std::cout << "num 변수의 값: " << num << std::endl;
std::cout << "ref 변수의 값: " << ref << std::endl;
ref = 20; // 참조를 통해 변수 값 변경
std::cout << "변경 후 num 변수의 값: " << num << std::endl;
std::cout << "변경 후 ref 변수의 값: " << ref << std::endl;
또 한 참조는 포인터와 다르게 참조하는 대상이 없으면 선언할 수 없고 nullptr 개념이 존재하지 않는다.
정말로 없음을 표현하고 싶다면 참조보다는 포인터를 사용해야 한다.
int num = 10;
int& ref; // 참조하는 대상이 없으면 오류남.
ref = num;
참조함수
참조는 포인터와 유사하지만 포인터 문법(->)이 아닌 값복사 문법처럼 간결하게. 을 사용하여 원본데이터에 접근할 수 있다. 그렇기 때문에 값을 읽을 때 주로 사용한다. 함수에서 참조를 매개변수라 하여 사용하면 값 복사인지 참조인지 바로 확인할 수 없다. 보통 값을 읽을 때 사용하기 때문에 참조함수를 사용할 때는 보통 원본데이터를 수정하지 않고 읽기만을 한다는 의미로 참조 매개변수에 const를 입력하여 값을 수정하려는 시도를 막을 수 있다.
참조함수 읽기 모드
struct Info
{
int Id;
int pwd;
};
int main()
{
Info info2;
CreateInfo2(info2);
}
void CreateInfo2(const Info& info)
{
info.Id = 150;
info.pwd = 10;
}
참조함수 쓰기 모드
OUT을 사용하여 명시적으로 참조함수에서 변경이 일어남을 표시할 수 있다.
#define OUT
struct Info
{
int Id;
int pwd;
};
int main()
{
Info info2;
CreateInfo2(info2);
}
void CreateInfo2(OUT Info& info)
{
info.Id = 150;
info.pwd = 10;
}
Pointer to 참조와 참조 to Pointer
포인터를 참조로 변경하기 위해서는 *연산자를 사용하여 포인터가 가리키는 데이터를 넣어주면 된다.
참조에서 포인터로 변경하기 위해서는 &연산자를 사용하여 참조의 주소값을 넘겨주면 된다.
struct Info
{
int Id;
int pwd;
};
int main()
{
Info* pointer = nullptr;
Info& reference = *pointer;
PrintInfoByRef(*pointer);
PrintInfoByPtr(&reference);
}
void PrintInfoByRef(Info& info)
{
info.Id = 100;
info.pwd = 100;
}
void PrintInfoByPtr(Info* info)
{
info->Id = 150;
info->pwd = 10;
}
'VisualStudio > C++' 카테고리의 다른 글
[C++] && 오른 값 참조(move)와 보편 참조(forward) (0) | 2024.06.04 |
---|---|
[C++] 스마트 포인터 (shared_ptr, weak_ptr, unique_ptr) (0) | 2023.07.31 |
[C++] STL(Standard Template Library) (0) | 2023.07.25 |
[C++] 형변환 (static_cast, dynamic_cast, const_cast, reinterpret_cast) (0) | 2023.07.24 |
[C++] 타입변환에서 소멸자 Virtual 사용 (0) | 2023.07.24 |