포인터와 정적배열의 관계를 이해하면 포인터의 성질을 이해할 수 있다.
포인터와 배열은 매우 비슷하다. 
배열이 편의성기능이 몇가지 추가되어있다.
ex) 배열은 sizeof해보면 배열은 총 Byte가 출력된다. 포인터는 포인터의 Byte가 출력된다.

array변수는 포인터와 비슷하다. 배열의 첫번째 주소를 담고 있다.

	int arr[5] = { 9,7,5,3,1 };
	//배열의 첫번째 주소가 출력된다.
	cout << arr << endl;


확인방법 : de-reference 해보면 배열의 첫번째 데이터가 출력된다.

문제가 되는부분
함수 파라미터로 배열을 넘겨줄때 포인터로 넘어간다.
확인방법 : sizeof()를 활용해보면 포인터의 Byte가 출력된다.

함수안에서 포인터로 직접접근하여 값을 변경할 수 있다.

void printArray(int arr[]) {
	//(생략)...
	//직접접근하여 값변경하기
	*arr = 1000;
}

배열이 struct나 class에 들어가있으면 포인터로 변환되지 않는다.

#include <iostream>

using namespace std;

void printArray(int arr[]) {
	cout << "======" << endl;
	cout << arr << endl;
	cout << *arr << endl;
	cout << sizeof(arr) << endl;

	//직접접근하여 값변경하기
	*arr = 1000;
}

struct A
{
	int arr[3] = { 1,2,3 };
};

void doSomethig(A a) {
	//포인터로 변환되지 않는것을 확인할 수 있다.
	cout << sizeof(a.arr) << endl;
}

int main()
{
	int arr[5] = { 9,7,5,3,1 };

	cout << arr << endl;
	cout << *arr << endl;
	cout << sizeof(arr) << endl;
	//같은 주소를 보고있는지 확인하기
	int *ptr_arr = arr;
	cout << ptr_arr << endl;
	cout << *ptr_arr << endl;
	cout << sizeof(ptr_arr) << endl;

	char name[] = "choi";
	cout << *name << endl;
	printArray(arr);
	printArray(ptr_arr);
	cout << arr[0] << "   " << *arr << endl;
	
	cout << "======" << endl;

	A a;
	cout << a.arr[0] << endl;
	cout << sizeof(a.arr) << endl;
	
	doSomethig(a);

	return 0;
}

 

 

 

포인터는 c,c++중요한 특징이다.

컴퓨터 내부에서 작동하는 방법 즉, CPU와 메모리의 협력방법을 알 수 있다.

포인터의 기본적인 사용법

변수를 선언할때 변수가 사용할 공간을 os로 부터 빌려온다.
이때 변수는 메모리의 주소를 가르키고 있고 주소에 접근 하여 데이터를 가져온다.

 

또 지역변수는 스택 영역을 사용하고 동적할당메모리는 힙 영역을 사용한다.

변수명 앞에 &(adrress-of operator)을 사용하면 주소값을 알 수 있다.

그 메모리주소를 담는 변수를 포인터라고 부른다.

변수를 사용할때 *(de-reference operator)는 포인터가 가르키고 있는것에 대해
직접적으로 접근하는 것을 말한다.  

간단하게 생각하자! 포인터는 그냥 메모리 주소를 담는 변수이다.
주소값을 직접적으로 입력하는것은 가능하지 않다.

int *ptr_x = &x;


형식으로 선언한다.

함수가 리턴타입으로 포인터를 가질 수 있다.

포인터를 선언하는 이유
기본적인 이유는 array때문에 사용한다.
함수에 array가 파라미터로 들어가면 복사가 된다.
100만개라고 생각한다면 복사를 하면 엄청 느려진다.

포인터로 주소와 데이터의 갯수만 알려주면 속도를 줄일 수 있다.

다른언어들에서도 내부적으론 포인터를 사용하고 있다.
사용자정의자료형에서도 포인터를 사용할 수 있다.
포인터의 주소는 비트의 값다를때 크기만 다르지 저장하는 값은 고정이다.

 

#include <iostream>
#include <typeinfo>

using namespace std;

int* nullPoint(int* a)
{
	return nullptr;
}

struct A {
	int a, b, c;
};

int main() {

	int x = 5;

	cout << x << endl;
	cout << &x << endl;
	cout << *(&x) << endl;

	//포인터 선언
	//변수의 주소를 포인터에 넣어준다.
	//데이터 타입과는 상관없이 중립적이다.
	//다만 de-reference할때 타입을 알아야하기에 타입을 정해준다.
	int *ptr_x = &x;

	cout << ptr_x << endl;
	//de-reference 가리키고있는 메모리안에있는 데이터를 가져온다.
	cout << *ptr_x << endl;
	//포인터임을 확인 할 수 있다.
	cout << typeid(ptr_x).name() << endl;

	A a;
	A *ptr_a;

	//12Byte이다.
	cout << sizeof(a) << endl;
	//포인터는 4Byte이다.
	cout << sizeof(ptr_a) << endl;

	return 0;
}

'개발 소발 > 개발 C++(기초)' 카테고리의 다른 글

c++ 포인터와 정적배열  (0) 2019.07.25
c++ 널 포인터 Null Pointer  (0) 2019.07.25
c++ 정적 다차원 배열  (0) 2019.07.25
c++ 배열 선택정렬,버블정렬  (0) 2019.07.24
c++ 배열 array 배열반복문사용  (0) 2019.07.24

+ Recent posts