Post

C++ - 배열, 포인터, 참조자

C++ 배열, 포인터, 참조자

1. 배열

코드 짜는데 배열 모르는 사람이 있나?라고 물을 수 있다.
배열 모르는 사람은 없다. 단지, 하이레벨 언어를 사용하다보면 C계열 언어 배열 선언법을 까먹을 순 있다 ;;
Javascript는 별도로 array로 만들던가, 그냥 배열 형태로 값을 넣으면 됐었고, python도 그냥 넣으면 된다.
이렇게 되니 까먹을 수 있다. 이 포스팅은 Remind의 목적을 띄고 있으니 포스팅을 하려고 한다.

가령 int형으로 크기 4의 배열을 선언하고 싶다면 C++에서 배열 선언은 아래와 같이 할 수 있다.

1
int A[4];

물론 C++도 초기화 값을 넣어두면 대괄호 안의 값을 생략할 수 있다.

1
int a[] = {2,2,2,2,2} // size 5의 int형 배열

다차원 배열을 선언하고 싶다면 아래와 같이 사용하면 된다.

1
int a[2][2] = {{1,2,},{3,4}}

※ 배열 선언시 size는 꼭 상수만 써야할까?

당연히 상수만 써야지!라고 답할 수도 있다. 하지만 놀랍게도 아니다!
정확한 답은 사용하는 컴파일러에 따라 다르다이다.

일단 공식적으로 standard한건 C는 가변 배열을 지원하는게 맞고, C++ 가변 배열을 지원하지 않는다.
C언어는 c99 부터 공식적으로 표준에 포함 되어있고, C++은 아니다.

하지만 GCC에서 빌드시 가변 크기 배열은 빌드가 된다, 그리고 윈도우에서 Visual studio로 빌드시 에러가 난다. 이는 GCC에서 C 계열 확장으로 가변크기 배열을 지원해주기 때문이다.

그리고 사실 가변크기 배열의 사용은 지양하는것이 좋은게, Stack의 경우 Heap보다 할당 가능한 사이즈가 작기 때문에 여차하면 Stackoverflow가 날 수 있다. 따라서 가능하면 그냥 따로 동적할당해서 쓰는게 현명하다.

2. 포인터

사실 참조자 이야기를 하고 싶은데 참조자 이야기를 하려면 포인터가 빠질 수 없기 때문에, 포인터 이야기를 넣는다.
C언어를 배웠다면 알겠지만, 포인터는 메모리 주소를 가르키는데 사용한다. C에서 선언한 형태와 동일하게 사용한다.

변수 앞에 &를 붙이면 해당 변수의 주소를 나타내며 *을 붙이면 주소(OS의 가상 주소)를 가르켜서 값을 가져올 수 있다. 대상이 되는 자료형에 *을 붙여서 정의하며 가령 int* a라고 정의했다면 int형으로 정의된 변수의 주소를 저장할 수 있다.
이는 원시 타입만 아니라 사용자 정의 자료형도 가능하다.
이렇게 선언된 포인터 변수는 32bit system이냐 64bit system이냐에 따라서 크기가 달라지며 32bit시 4bytes, 64bit시 8bytes의 크기를 갖는다.
이는 memory주소 alignment로 인해 그런 것이다.

포인터 변수의 선언은 아래와 같다.

1
2
int a = 4;
int* b = &a;

int형 변수 a를 선언했고, 4를 넣었는데 해당 a의 주소를 포인터 변수b에 넣을 수 있다.

※ 추가 업데이트 예정

3. 참조자

기본적으로 동작은 포인터와 같다. 다만 포인터는 NULL이 될 수 있으나 참조자는 존재하는 것만 지정가능하며 가볍게 개인적으로 사용이 좀 더 편리하다고 생각한다.(특정 부분에서는 더 사용이 복잡해진다고 한다)

기본적으로 참조자와 포인터의 자료형 크기는 같으며 32bit system이면 4bytes, 64bit system이면 8bytes이다.

1
2
int a = 20;
int &b = a;

위와 같이 b는 a의 참조자가 되어 b를 변경시 a도 변경된다.
이는 함수에서 인자로 받을 때는 아래와 같이 사용할 수 있다.

1
void func(int& a) {};

int형 참조자를 인자로 받는다는 뜻이다.

※ 추가 업데이트 예정

참고자료

This post is licensed under CC BY 4.0 by the author.