#include <iostream>
using namespace std;
void Plus_One(int* _n);
void main()
{
메모리 주소
메모리 주소를 확인하기 위해서는 &(어드레스 연산자)를 사용한다.
& + 변수명 을 명시하면 해당 변수가 할당된 메모리의 시작 주소를 반환한다!
int iA = 10;
cout << "iA: " << iA << endl;
cout << "&iA: " << &iA << endl;
포인터 선언
자료형과 변수명 사이에 *(에스크리터)를 추가해주면 된다.
/*
자료형 * 변수명
*/
int* ptr1;
int * ptr2;
int *ptr3;
int iA;
double dB;
long long llC;
int* ptr;
int iA;
double dB;
long long llC;
포인터의 초기화
쓰레기 값 초기화
int* ptr;
0으로 채워진 주소를 가진다.
이 주소는 0번지를 가리키는 것이 아니라 아무런 곳도 가리키고 있지 않다 라는 의미이다.
int* ptr1 = 0;
int* ptr2 = NULL;
int* ptr3 = nullptr;
cout << ptr1 << endl;
cout << ptr2 << endl;
cout << ptr3 << endl;
선언과 동시에 초기화
int iA = 10;
int* ptr = &iA;
cout << "iA: " << iA << endl; // iA의 값
cout << "&iA: " << &iA << endl; // iA의 주소
cout << "--------------------" << endl;
cout << "ptr: " << ptr << endl; // ptr의 값 == iA의 주소
포인터 초기화 시 주의 사항
##1. 쓰레기 값 초기화
-> 포인터 변수가 쓰레기 값을 가진다.
-> 포인터가 가지는 값은 주소이다.
-> 결국, 쓰레기 값이란 어디를 가킬지 모르는 주소이다.
만약, 쓰레기 값이 가리키는 곳이 윈도우를 구동하는데 중요한 메모리 공간이라면?
그 공간을 사용자가 임의로 값을 변경한다면?
운영체제에 심각한 문제가 발생한다!
단, 요즘의 운영체제는 특정 프로그램에서 할당되지 않는 메모리 접근의 시도가 있고
운영체제가 이를 감지한다면 해당 프로그램을 강제로 종료시켜버린다.
##2. nullptr 초기화
아무런 곳도 가리키고 있지 않다!
만약 접근하여 값을 확인 또는 수정한다면?
확인하고 수정할 값이 없다!!!
-> 오류가 발생한다!
주소를 통한 원본 데이터 접근
-> 간접 참조
* : 역참조 연산자
어느 상황에선 에스크리터, 어느 상황에선 역참조 연산자
에스크리터 : 변수 선언 시 사용하면 에스크리터가 된다.
역참조 연산자 : 변수 선언 후 변수명 앞에 붙이면 역참조 연산자가 된다.
역참조 연산자를 읽는 방법은
'해당 변수가 가지고 있는 주소로 찾아가 값을 확인해라!' 라고 읽으면 된다.
int iA = 10;
int* ptr = &iA; // 에스크리터
cout << "iA: " << iA << endl; // iA의 값
cout << "&iA: " << &iA << endl; // iA의 주소
cout << "--------------------" << endl;
cout << "ptr: " << ptr << endl; // ptr의 값 == iA의 주소
cout << "*ptr: " << *ptr << endl; // iA의 값
int iA = 1;
Plus_One(&iA);
cout << iA << endl;
}
// int* _n = &iA;
void Plus_One(int* _n)
{
++(*_n);
}
#include <iostream>
using namespace std;
void main()
{
포인터의 크기
어떠한 자료형이든 4bytes의 고정된 크기를 가진다.
-> 32bits 개발환경에서 가용할 수 있는 메모리는 4기가이다.
-> 포인터는 1byte당 하나의 주소가 할당되니 4기가를 byte단위로 환산하면
-> 약 42억 9천만개가 나온다.
-> 이는 0, 1, 2, 3, .... 약 42억9천을 각 저장하기 위해서는
-> 4bytes의 공간만 있으면 충분히 저장할 수 있다!
-> 64bits 개발 환경에서는 동일한 계산 방식으로 8bytes의 크기가 나온다.
cout << sizeof(char*) << endl;
cout << sizeof(short*) << endl;
cout << sizeof(int*) << endl;
cout << sizeof(long*) << endl;
cout << sizeof(float*) << endl;
cout << sizeof(long long*) << endl;
cout << sizeof(double*) << endl;
cout << sizeof(long double*) << endl;
int*, float* 는 서로 대입할 수 있을까?
-> 4bytes 공간이 필요하며, 주소를 저장한다!
int iA = 10;
int* ptr1 = &iA;
float* ptr2 = ptr1; // 불가능
불가능한 이유는 역참조 연산자를 붙여보면 된다.
ptr1이 가지고 있는 주소로 찾아가 값을 확인해라
값을 확인해라!
##1. 시작 주소부터 몇 바이트를 읽어야 하는가?
##2. 어떤 형식으로 읽어야 하는가?
ptr1의 선언된 타입을 보면 int* 이다.
이는, ptr1이 가지고 있는 주소로 찾아가
해당 주소부터 타입의 크기(int)만큼의 공간을 타입 형태(정수형)으로 읽어라!
*ptr1;
ptr2가 가지고 있는 주소로 찾아가
해당 주소부터 타입의 크기(float)만큼의 공간을 타입 형태(실수형)으로 읽어라!
*ptr2;
int*와 long* 는 대입이 가능할까?
자료형의 크기는 운영체제 환경에 따라 다르게 적용된다.
32bits환경에서는 int와 long의 크기가 같지만
운영체제가 발전하여 업그레이드될 경우 int와 long의 크기가 같다고 보장할 수 없다!
int iA = 10;
int* ptr1 = &iA;
long* ptr2 = ptr1; // 불가능
const와 포인터의 관계
const는 바로 뒤에 있는 것을 상수화 시킨다!
##1. const가 에스크리터 앞에 올 경우
const 뒤에 int*가 있다!
-> 역참조를 통한 정수 값이 상수가 된다.
int iA = 10, iB = 20;
const int* ptr = &iA;
*ptr = 999; // 불가능
ptr = &iB; // 가능
##2. const가 에스크리터 뒤에 올 경우
const 뒤에 ptr이 있다!
-> ptr을 통해 확인할 수 있는 주소가 상수가 된다!
int iA = 10, iB = 20;
int* const ptr = &iA;
*ptr = 999; // 가능
ptr = &iB; // 불가능
}
#include <iostream>
using namespace std;
void main()
{
이중 포인터
포인터 또한 변수이다!
-> 메모리에 등록이 된다!
-> 포인터 또한 할당된 주소가 있다!
// 포인터 변수의 할당된 주소를 저장할 수 있는 것.
int iA = 10;
int* ptr = &iA;
cout << "iA: " << iA << endl;
cout << "&iA: " << &iA << endl;
cout << "---------------------------" << endl;
cout << "ptr: " << ptr << endl;
cout << "*ptr: " << *ptr << endl;
cout << "&ptr: " << &ptr << endl;
cout << "---------------------------" << endl;
// 포인터 변수의 주소를 저장하기 위해서는 2중 포인터가 필요하다!!
//int* ptr2 = &ptr; // 불가능
int** ptr2 = &ptr;
cout << "ptr2: " << ptr2 << endl; // ptr이 할당된 공간의 주소 값
// ptr2가 가지고 있는 주소로 찾아가 값을 확인한다!
cout << "*ptr2: " << *ptr2 << endl; // ptr이 가지고 있는 값 == iA의 주소
cout << "**ptr: " << **ptr2 << endl; // iA의 값
// ##1. 에스크리터와 역참조 연산자는 1:1의 비율로 작동한다!
// ##2. 포인터는 원본에 접근하는 방법으로 원본이 주소이다!
}
C++ 배열, 2차원배열, 문자열배열, 3차원 배열 (0) | 2020.10.08 |
---|---|
C++ 자판기 프로그램 3 (0) | 2020.10.08 |
c++ 자판기 프로그램 2 (0) | 2020.10.07 |
C++ 함수, 포인터 개론 (0) | 2020.10.07 |
C++ 삼항연산자, 함수 (0) | 2020.10.07 |