[C++] 배열(Array)

2024. 3. 4. 18:56Programming Language/C++

배열

동일한 자료형으로 변수를 한 번에 여러 개를 할당하고 싶을 때 사용하는 자료구조

일일이 변수명을 하나씩 선언하지 않고 묶어서 한 번에 선언할 수 있다.

• 특징 : 연속적인 메모리 구조

배열 문법

• `자료형 배열변수명[배열길이] = {배열요소들};`

▷ 예시

int Array[10] = {};  // Array는 int형 10묶음의 전체 이름이다.

배열은 배열에서의 위치를 가리키는 인덱스(index) 제공한다.

index는 0부터 시작한다.첫 번째 index = 0

• 배열을 빈 중괄호`{ }`로 선언하면 전체 메모리가 0으로 초기화된다.

• 배열 공간을 다 채우지 않으면 나머지 공간은 전부 0으로 채워진다.

 

▷ 예시

int Array[10] = { 1, 2, 3, 4, 5 };  // 1, 2, 3, 4, 5, 0, 0, 0, 0, 0
// int Array[10] = { 1, 2, 3, 4, 5, };  // 5 뒤에 콤마는 작성해도 되고 생략해도 된다.

나머지는 0으로 채워짐.

배열의 변수는 지역 변수일까?

배열이 어디에 선언되었는지에 따라 지역 변수일 수도 있고, 전역 변수일 수도 있다.

지역 변수인 경우

• 함수나 지역 내에서 선언되면 해당 배열은 그 범위 내에서만 접근 가능하며, 스택 영역에 존재하므로 범위가 끝나면 자동으로 소멸한다.

▷ 예시

void myArray()
{
	int arr[5] = {1, 2, 3, 4, 5};
}

전역 변수인 경우

• 프로그램 전체에서 접근할 수 있다.

▷ 예시

int arr[5] = {1, 2, 3, 4, 5};

int main()
{
	// 코드 내용..
    
    return 0;
}

동적 배열을 가리키는 포인터인 경우 (힙 영역)

• 포인터로 메모리를 동적 할당하면 배열은 힙 영역에 존재하게 된다.

• 배열 사용 후 메모리를 해제하면 배열도 소멸된다.

▷ 예시

int* arr = new int[5];
delete[] arr;

배열의 개별 요소에 접근하는 법

▷ 5번째에 10을 넣는 코드

int Array[10] = {};
// '[]' 안에 있는 숫자는 index를 뜻하기 때문에 10을 4번째에 넣는 것이 아니라 index로 4에 해당하는 5번째에 값을 넣겠다는 의미이다.
Array[4] = 10;  // 0, 0, 0, 0, 1, 0, 0, 0, 0, 0

int형으로 10개를 선언했기 때문에 접근할 수 있는 최대 index는 9이다.

n번 째 index
1 0
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8
10 9

최대 index보다 큰 숫자를 넣으면 발생하는 일

▷ 최대 index가 9인데 10을 넣었을 때

<실행 전> 코드

최대 index보다 큰 숫자 넣음.

 

<실행 전> 오류 목록

코드 경고

 

<실행 후> 코드

코드 오류

배열이 손상됐다는 의미인데, 항상 위의 오류가 나타나는 것은 아니다.

오류가 표시되지 않고 실행되는 경우가 있기 때문에 주의가 필요하다.

 

이번엔 `Array`의 12번째 index에 10을 넣는 코드로 수정해 봤다.

초과된 인덱스 범위

 

뜬금없이 `a`에 10이 들어가 있는데, 어떻게 된 것일까?

다른 변수에 지정한 배열 값이 들어가있음.

`main()` 스택에 있는 `a`의 메모리 상의 위치가 우연찮게 10개짜리 배열 옆에 13번째 자리에 있다.

오버된 배열의 인덱스 값으로 인해 원래 `a`에 있던 값이 소실되면서 10이 들어가게 된 것이다.

위의 경우는 오류가 떠야 되는 상황인데 오류가 뜨지 않았다. 때문에 뭐가 잘못된 건지 못 찾는 경우가 발생한다.

인덱스 값이 초과되지 않도록 주의하기!

 

지금은 인덱스에 숫자를 넣었지만 인덱스 값 자체가 변수이거나 수식을 통해서 원하는 인덱스를 계산하게 하는 경우가 있다.

이때 수식이 잘못되면 초과된 인덱스 범위가 들어간다.

#include <iostream>  // 표준 입출력 헤더파일

using std::cout;
using std::endl;

int main() {
	// ex1. 인덱스 값 자체가 변수인 경우
    int arr[] = {10, 20, 30, 40, 50};
    int index = 2; // 2번 인덱스값인 30 저장
    cout << arr[index] << endl; // 30

	// ex2. 인덱스 값 자체가 수식인 경우
    int n = 4; // n : 배열 길이
    int cIndex = (n - 2) % 4; // (4 - 2) % 4 = 2 % 4 = 2
    cout << arr[cIndex] << endl; // 30
    
    return 0;
}

배열에 대해 정확히 알려면 포인터를 알아야 한다.

참고 링크
포인터, 포인터 배열

포인터가 앞으로의 문법(클래스, 구조체 등)과 연계된다.