본문으로 바로가기

[C/C++] 배열 (Array)

category Theory/Lecture 2009.10.24 22:19

본 자료는 국립 창원대학교 메카트로닉스 공학부 학생을 대상으로 한 컴퓨터 언어 응용 수업 자료입니다. 본 자료는 수업의 교재인 (핵심요약판) C++로 시작하는 객체지향 프로그래밍 (Y. Daniel Liang 저, 권기형 / 김응성 공역) 의 내용을 재구성한 것으로 수업보조 자료 이외의 목적이 없음을 알립니다.


배열 Array
100명의 학생에 대한 각 과목의 점수를 저장하고, 그 데이터를 분석(평균, 등수, 학점부여 등등)할때 100개의 변수를 생성한다는 것은 얼핏봐도 비효율적으로 보입니다. 이렇게 동일 유형의 데이터들이 여러개 있을때 배열을 사용하면 아주 편합니다. 특히, 해당 데이터에 접근할 때, for문 같은 명령어를 통해 무난히 접근할 수 있어서 그 효율성은 더욱 증가합니다.
 
배열은

 
위와 같은 형식으로 선언합니다. 이때 datatype은 각 요소 모두에 적용되는 것입니다. 예를 들면

 
위와 같이 선언하면 double형의 유형을 가지는 기억공간 열개가 준비되는데

 
위 그림처럼 됩니다. 각 저장공간에는 사용자에 따른 데이터들을 저장할 수 있게 됩니다. 이 배열을 가지고 일반 연산( 'myList[1]+myList[3]' )이 가능합니다. 


이렇게 배열을 선언할 때는 배열의 크기를 입력하게 되는데 주의할 점은 항상 상수를 입력해야합니다. 이는 배열은 한번 선언되면 원칙적으로는 그 크기를 변경할 수 없기 때문입니다.(단, 원칙적입니다.)

 
배열은 선언할 당시 위와 같이 초기화가 가능합니다. 

 
그러나 초기화에서 사용하는 { } 괄호는 자료를 대입할 때는 사용할 수 없습니다.


만약 위에서처럼 선언하고자 하는 배열의 크기가 4이고 모두 초기화한다면 그 크기는 생략해줘도 됩니다.


또 위에서 처럼 처음 두 공간만 초기화하는 것도 가능합니다.

 
문자에 대해서도 초기화가 가능한데요. 위의 두 선언법은 같은 것이긴 하지만, 딱 하나 차이가 납니다. 첫번째 방법은 배열의 크기가 6으로 0번부터 5번까지 저장공간이 만들어 지지만,


두번째 방법은 위 그림처럼 문자의 끝을 의미하는 널(null)문자가 하나 들어가서 배열의 크기가 하나 커집니다.


또 배열은 위에서 보면 cout<<myList 처럼 해서는 출력되지 않습니다. 항상 각 저장공간의 번호, 즉 인덱스별로 따로 출력해줘야합니다.


단, 문자열에 대해서는 허용됩니다.


배열을 사용할 때 유용한 몇몇 코드


위의 코드는 배열내에서 최대값을 찾는 것입니다. for문으로 전체 배열을 검색하면서 그 때까지의 최대값만 기억하는 것입니다.


위 코드는 최대값뿐만아니라 그 최대값이 저장되어있던 공간의 번호, 즉 인덱스도 같이 출력하는 것입니다.

 
위 코드는 배열의 순서를 뒤집는 코드입니다.


위 코드는 선형검색이라는 개념을 사용한, 특정한 요소의 인덱스, 즉 몇번째 공간에 저장되어 있는지를 찾는 것입니다. 선형방법말고 이진방법도 있습니다.

 
이진 방법은 첫값과 끝, 그리고 가운데 이렇게 세개의 값을 찾아서 내가 원하는 값과의 관계를 봅니다. 그렇게 해서 범위를 좁혀가는 것입니다. 이진방법을 사용하면 최소한 절반으로 검색시간을 줄일 수 있습니다.



이제는 정렬에 대해 이야기해보겠습니다. 오름차순이나 내림차순으로 정렬하는 것이 항상 필요할 때가 있습니다. 이때 많이 사용하는 방법중 하나가

 
선택정렬입니다. 이 선택정렬은 전체를 검색해서 가장 큰 (오름차순이라면) 요소를 제일 뒤로 보내고, 다시 제일 뒤를 제외하고 다시 검색해서 가장 큰 요소를 제일뒤(실제로는 뒤에서 두번째)에 보내는 방법입니다.

<코드1>

#include <iostream>
using namespace std;

void selectionSort(double [], int);
void printArray(double list[], int arraySize); // function prototype

int main()
{
  double list[] = {2, 1, -4, 4};
  selectionSort(list, 4);

  printArray(list, 4);
  return 0;
}

void printArray(double list[], int arraySize)
{
  for (int i = 0; i < arraySize; i++)
  {
    cout << list[i] <<  " ";
  }
}

void selectionSort(double list[], int arraySize)
{
  for (int i = arraySize - 1; i >= 1; i--)
  {
    // Find the maximum in the list[0..i]
    double currentMax = list[0];
    int currentMaxIndex = 0;

    for (int j = 1; j <= i; j++)
    {
      if (currentMax < list[j])
      {
        currentMax = list[j];
        currentMaxIndex = j;
      }
    }

    // Swap list[i] with list[currentMaxIndex] if necessary;
    if (currentMaxIndex != i)
    {
      list[currentMaxIndex] = list[i];
      list[i] = currentMax;
    }
  }
}

두번째 방법은 삽입정렬이라는 것인데

 
두 요소만 검색해서 큰 요소를 오른편에 두는 것입니다. 이걸 계속 반복해가는 것이지요. 

<코드2>

#include <iostream>
using namespace std;

void insertionSort(double [], int);
void printArray(double list[], int arraySize); // function prototype

int main()
{
  double list[] = {2, 1, -4, 4, -3};
  insertionSort(list, 5);

  printArray(list, 5);
  return 0;
}

void printArray(double list[], int arraySize)
{
  for (int i = 0; i < arraySize; i++)
  {
    cout << list[i] <<  " ";
  }
}

void insertionSort(double list[], int arraySize)
  {
  for (int i = 1; i < arraySize; i++)
  {
    /* insert list[i] into a sorted sublist list[0..i-1] so that
       list[0..i] is sorted. */
    double currentElement = list[i];
    int k;
    for (k = i - 1; k >= 0 && list[k] > currentElement; k--)
    {
      list[k + 1] = list[k];
    }

    // Insert the current element into list[k+1]
    list[k + 1] = currentElement;
  }
}


위에서 계속 다룬 배열은 1차원 배열입니다. 물론 그 이상의 배열도 많이 사용합니다. 사용법은 동일하기때문에 그냥 위에서처럼 선언법과 초기화만 익히시면 되겠습니다.


참고자료

[2009] 06.pdf



신고