주소
변수 등에서 어떤 데이터를 저장하기 위해 메모리에서 저장할 공간을 할당받는다. 그럼 이 데이터를 찾아서 호출하기 위해서는 이 데이터가 메모리 어느 부분에 저장되어 있는지를 알아야 한다. 이때 데이터가 저장된 메모리의 시작 주소를 주소 값이라고 한다.
예를 들어 int형 데이터를 저장하기 위해 변수를 하나 선언했다면 4 bytes 크기로 메모리에 공간이 할당된다.
주소: 0x0001 / 변수로 할당 받은곳 |
주소: 0x0002 / 변수로 할당 받은곳 |
주소: 0x0003 / 변수로 할당 받은곳 |
주소: 0x0004 / 변수로 할당 받은곳 |
주소: 0x0005 |
주소: 0x0006 |
주소: ..... |
이런 식으로 총 4 bytes크기의 공간이 할당되고 이 공간의 시작 주소인 0x0001이 해당 변수를 가리키는 주소 값이 된다.
포인터
포인터는 일반 데이터가 아닌 메모리의 주소 값을 저장하는 변수이다.
예를 들어 int형 변수에 10이란 값이 저장되어 있고 변수의 메모리 시작 주소가 0x0010이라고 한다. 그럼 포인터 변수를 하나 선언하여 위의 int형 변수를 저장한다면 10이란 값이 아닌 0x0010이라는 시작 주소를 저장한다.
실제 메모리의 위치는 아니지만 이런 식으로 포인터 변수는 int변수의 시작 주소를 저장해 저 변수를 가리키고 있다고 생각하면 된다. 또한 이 포인터도 변수기 때문에 메모리 어딘가에 저장되기 때문에 포인터도 주소 값을 가지고 있다.
주소 연산자(&)
변수 이름 앞에 사용하여 해당 변수의 메모리 주소 값을 반환한다.
참조 연산자(*)
포인터의 이름이나 주소 앞에 사용하며 해당 주소를 참조하여 주소에 저장되어 있는 값을 반환한다.\
포인터와 배열의 관계
#include <iostream>
using namespace std;
int main(){
int a[] = {1, 2, 3, 4};
cout << "a[0]의 주소값 : " << a << endl;
cout << "a[1]의 주소값 : " << a+1 << endl;
cout << "a[0]의 값 : " << *a << endl;
cout << "a[1]의 값 : " << *(a+1) << endl;
}
실행결과
이중포인터
포인터(Pointer) 사용 시 주의점
1. 포인터(Pointer) 변수 선언시 초기화 하기
만약 포인터가 선언만 되고 초기화되지 않았다면 포인터는 쓰레기값을 가지게 됩니다. 이런 상태에서 포인터를 사용하여 메모리의 내용을 변경한다면 문제가 생길 수 있을 소지가 있습니다. 만약 우연히 포인터가 중요한 값을 가리키고 있었다면 중요한 정보를 덮어쓸 수도 있으며 따라서 전체 시스템을 다운시킬 수도 있으니 그냥 포인터를 단순히 선언만 하지 말고 선언 시 초기화를 사용하거나 NULL 포인터로 만들어주는 것이 바람직합니다.
2. NULL 포인터(Pointer)의 사용
포인터가 아무것도 가리키지 않을 때는 NULL로 설정하는 것이 좋습니다. NULL은 헤더 파일 stdio.h에 0으로 정의되어 습니다. 주소 0은 CPU가 사용하는 영역이어서 일반 프로그램은 주소 0에 접근할 수 없기에 안정성이 높습니다.
3. 포인터 자료형과 변수의 자료형 일치
만약 포인터의 자료형이 변수의 자료형보다 크다면, 포인터를 통해 변수의 주소를 통해 쓰게 될 경우 변수의 범위를 넘어가서 이웃 바이트를 덮어쓰게 되어 문제가 생길 수 있습니다.
4. 절대 주소 사용 금지
절대 주소는 아두이노와 같은 엠베디드 시스템에서만 사용합니다. 그 이유는 PC는 윈도우와 같은 운영체제가 프로그램을 관리하기 때문에 프로그래머가 사용하고자 하는 주소가 어떠한 용도로 사용되는지 모르기 때문입니다. 실행을 할 때마다 할당되는 주소가 다르기에 절대 주소는 사용하시면 안 됩니다.
'Programming > C++' 카테고리의 다른 글
[C++] enum (0) | 2022.09.06 |
---|---|
[C++] 구조체 (0) | 2022.09.06 |
[C++] Template (0) | 2022.09.06 |
[C++] namespace, using (0) | 2022.06.16 |
[C++] 함수 (0) | 2022.06.11 |