본문 바로가기

개발/C&C++

(C/C++ 속성 정리) 9일 차 : 포인터와 배열

안녕하세요 넬다이 입니다.

 

오늘 시간에는 포인터와 배열에 대해서 정리해보는 시간을 가질 건데요!

 

8일 차에는 포인터를 배웠지만 오늘은 포인터 + 배열에 관해서 배워보도록 하겠습니다.

 


배열에 대해서 알아봅시다.


int iA = 0;
int iB = 0;
int iC = 0;
int iD = 0;
int iE = 0;
일반 변수는 메모리 상에 떨어져서 할당이 될 수도 있고 붙어서 할당이 될 수도 있습니다.
즉 블록 단위 할당을 보장할 수 없으므로 인덱스를 통한 임의 접근이 불가능한 것입니다.

 

배열을 선언한 것..
int iArray [5];
5개의 값을 저장하기 위해 다섯 개의 변수가 필요하지만

배열을 사용하면 번잡스럽게 선언할 필요가 없이 간단하게 선언할 수 있다.

 

[] 첨자, 인덱스 혹은 순번이라고 표현한다.

//배열을 선언과 동시에 초기화할 수 있다.
int iArray[5] = {10, 20, 30, 40, 50};

cout << iArray[0] << endl;
cout << iArray[1] << endl;
cout << iArray[2] << endl;
cout << iArray[3] << endl;
cout << iArray[4] << endl;

위에 코드는 int 형 변수 5개를 선언한 것과 같다.

 

배열 인덱스를 넘어가는 공간에 접근하려고 하면 컴파일 시에는 오류가 발생하지 않지만
실행 시 오류가 난다는 것을 기억할 것!!

배열은 블록 단위로 연속된 공간을 예약하는 것이기 때문에 인덱스를 통한 임의 접근이 가능하다.

변수와 배열은 둘 다 기억공간을 확보한다는 것이지만

변수는 하나의 자료형에 대한 하나의 기억 공간,

배열은 하나의 자료형에 대한 여러 개의 연속적인 기억 공간이다.

 

배열의 다른 초기화 문법 정리.
int iArray [10] = {};
0으로 모든 요소가 초기화된다.

하지만 0으로 요소들을 초기화해야 한다면..
int iArray [10] = {0};
이런 식으로 명시적으로 초기화하는 것이 좋다고 한다.

배열의 요소 중 앞의 몇 개만 초기화하고 싶을 때
int iArray [10] = {10, 20};
초기화된 요소를 제외한 나머지 요소들은 0으로 초기화가 된다.

그리고 배열의 인덱스는 0부터 시작한다.

 

int iArray[20] = {0};

cout << iArray[0] << endl;

int iIndex = 10;

//변수도 인덱스 안에 들어갈 수 있다.
cout << iArray[iIndex] << endl;

cout << iArray[iIndex + 3] << endl;

 

int	iArray[10] = {0};

for(int i = 0; i < 10; ++i)
{
	iArray[i] = (i + 1) * 10;
}

for(int i = 0; i < 10; ++i)
{
	cout << iArray[i] << endl;
}

위에 내용처럼 변수 또한 인덱스로 들어갈 수 있다.

 

int iA1 = 0;
int iA2 = 0;
int iA3 = 0;

int iArray[3] = {0};

cout << "iA1 주소 : " << &iA1 << endl;
cout << "iA2 주소 : " << &iA2 << endl;
cout << "iA3 주소 : " << &iA3 << endl;

int*	pArray = NULL;
pArray = iArray;

cout << "iArray[0] 주소 : "<< &iArray[0] << endl;
cout << "iArray 배열명 : " << iArray << endl;
cout << "pArray : " << pArray << endl;

for(int i = 0; i < 3; ++i)
{
	cout << "iArray[" << i << "] 번째 주소 : " << &iArray[i] << endl;
}

배열은 연속된 메모리의 주소 값을 갖는다.
배열의 첫 번째 주소를 알면 연속해서 접근할 수 있다는 뜻으로 배열의 이름은 배열의 시작 주소이다.

 

배열의 이름은 배열의 시작 주소이긴 하지만 다른 위치를 가리키도록 변경할 수는 없다.

int iArray = {0};

int* pArray = NULL;
iArray = pArray;

이런 문법은 불가합니다!!!

 

int iArray[20] = {0};
int* pArray = NULL;

pArray = &iArray[5];

for(int i = 0; i < 4; ++i)
{
	cout << pArray[i] << endl;
}
//이런 경우는 인덱스로 음수값이 들어갈 수도 있다.
// pArray는 iArray[5]를 가르키고 있으니
// pArray[-1]은 iArray[4]와 같다.
cout << pArray[-1] << endl;

pArray = iArray;

이게 같다는 소리입니다.
pArray == iArray == &iArray [0]
(pArray + 1) == &iArray [1]
(pArray + 2) == &iArray [2]

 

정리

정리를 하면 배열의 이름은 배열의 시작 주소 포인터의 연산은

일반 변수의 연산과 다르게 자료형의 크기만큼 증감 연산이 된다.
배열의 인덱스 증감 또한 배열의 자료형에 의해 크기가 결정되는 것이다.