본문으로 바로가기

[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




댓글을 달아 주세요

  1. 하마하마 2009.10.24 23:04 신고

    자료 분량에 비해 난이도가 급격히? 올라가네요. 처음 접하는 학생은 조금 어려울것 같습니다. ^^;

    메카 쪽 대학원생 이신가요? 저는 이제 졸업하는 상황이 되었습니다.
    요즘은 학교 다닐때 누군가 방향을 제시해 주었던 사람이 있었으면 좋았을텐데 하는 생각이 많이 들어요.

    C++ 가르치면서 어떤 경우에 사용한다. 그러니깐 꼭 배워두면 좋다. 이런식것이나 미래에 대한
    방향 제시는 꼭 해 주셨으면 합니다.

    51호관에 있는 학과 학생이.

    • BlogIcon PinkWink 2009.10.24 23:41 신고

      처음 접한 경우 어려운것이라는 것을 알고있습니다..^^
      그러나... 예제코드를 본인이 결코 공부하기에는 또한 긴코드는 아니라고 생각했지요^^

      좋은 조언 감사합니다..
      좋은 전달이 가능하도록 노력하겠습니다...^^

  2. BlogIcon 빨간내복 2009.10.24 23:47 신고

    자꾸 짓궃게 그러신다. ㅋㅋㅋㅋ 에효!!!!

  3. 영웅전쟁 2009.10.25 12:35 신고

    이~~긍
    티자 이게 상책이여 ㅎㅎㅎ

  4. 에스페란토 2009.12.30 06:06 신고

    배열을 선언할때 항상 상수만 입력해야 한다고 했는 데
    const 예약어를 사용해서 변수로도 가능하다고 나와있어서 조금 했갈립니다.
    변수를 사용할 수없는게 아니라 값이 고정된 경우에만 사용할수 있는 건가요?

    그리고 사용할 때
    #include <stdio.h>
    #define max 20
    main(){
    int i, num;
    int arr[max]

    이런식으로 쓰는 데 왜 int arr[20]이라고 하지않는 거죠?

    • BlogIcon PinkWink 2009.12.30 10:32 신고

      음.. 예제는 그냥 예제니까요^^
      define으로 max를 잡고 사용해도 된다는 것을 보여준 것 뿐입니다.
      실제로 어떤 시뮬레이션이나 실험을 할때 자주 변동되는 값은 define으로 두고 앞부분에서 숫자만 변경하는 것을 제가 선호하는 편입니다. (컴파일을 누르면 화면이 제일 앞으로 이동해버릴때가 많아서요^^) 당연히 int arr[20]이라고 해도 상관없습니다만, 그렇게 사용하시면, 나중에 자주 변동되어야하는 경우(각종테스트등으로 인해..) 꽤 귀찮습니다.^^.

  5. 에스페란토 2009.12.31 00:27 신고

    친절한 답변 감사드립니다.

    그런데 위에서 배열을 선언할때 항상 상수만 입력해야 한다고 했는 데
    const 예약어를 사용해서 변수로도 가능하다고 나와있어서 조금 했갈립니다.
    변수를 사용할 수없는게 아니라 값이 고정된 경우에만 사용할수 있는 건가요?

    오늘만 지나면 2010년 이군요.
    09년 잘마무리 하시고 행복한 새해되세요.

    • BlogIcon PinkWink 2009.12.31 07:19 신고

      핫 위에 질문이 두개였는데 제가 하나만 대답했군요..^^
      변수면 안된다입니다.. 비껴가는 법이 있긴하지만
      원칙적으로 배열의 크기를 변경할 수 없습니다. 그러니

      int a;
      int arr[a];

      라고 하면 안됩니다. const는 변수로 지정하는 것이 아니라 상수를 문자로 지정해두는 것이니 되지요^^

  6. 에스페란토 2010.01.04 03:17 신고

    const예약어를 사용하면 변수의 값이 고정되는 이유가
    변수를 상수화하기 때문인가요?
    그리고 배열은 동일한 데이터형을 가지는 변수의 집합이라고 생각하면 되나요?

    • BlogIcon PinkWink 2010.01.04 06:04 신고

      예.. const는 말그대로 변수가 아니라 '상수'입니다
      프로그램 중간에 바꾸지 않는다는 것이죠.

      그리고, 배열을 선언할때 선언된 데이터 유형으로 저장입니다. double형으로 선언된 배열은 그 저장공간에 double형 데이터들을 담겠다는 것이죠^^