Turbo-C
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
터보-C 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
Lua 게시판
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C/C++ 팁&트릭
[29] [STL]vector나 deque의 인덱스의 범위를 검사하는 방법
김백일 [cedar] 10330 읽음    2002-07-11 01:07
안녕하세요, 김백일입니다.

vector나 deque은 operator[] 멤버 함수가 있기 때문에
C/C++의 배열과 같은 방식으로 사용하면 됩니다.

하지만 이 operator[] 는 C/C++ 배열의 [] 연산자와 마찬가지로,
인덱스의 범위를 검사하는 기능이 없습니다.
operator[]는 매우 자주 사용하는 기능(함수, function)이므로,
매번 인덱스의 범위를 검사하면 상당한 속도 저하가 따르기 때문입니다.

하지만 경우에 따라 인덱스의 범위를 검사해야 할 경우가 있습니다.
물론 []를 사용하기 전에, size() 멤버 함수를 if문에서 사용해서
명시적으로 검사할 수도 있습니다.

또 한가지 세련된 방법으로, operator[] 대신 at 멤버함수를 사용하는 방법이 있습니다.
operator[]와 같지만, 범위 체크 기능이 있습니다.
범위를 벗어나면(n > size()), out_of_range 예외를 발생(throw)합니다.

C/C++ 배열에서 범위를 검사하는 방법에 비해, 훨씬 깔끔하지요.

다음은 두 가지 방법을 모두 구현한 예제입니다.

//---------------------------------------------------------------------------
#include <iostream>
#pragma hdrstop
#include <vector>

//---------------------------------------------------------------------------
using namespace std;
#pragma argsused
int main(int argc, char* argv[])
{
    vector<int> v(3);

    size_t i;

    for (i = 0; i < 10; ++i) {
        if (i < v.size()) { // if 문에서 명시적으로 범위 검사
           v[i] = i;
            cout << "v[" << i << "] = " << v[i] << endl;
        } else {
               cerr << "Index " << i << " is out of range!" << endl;
               break;
        }
    }

    try {
        for (i = 0; i < 10; ++i) {
            v.at(i) = i; // at 멤버함수로 범위 검사
            cout << "v[" << i << "] = " << v[i] << endl;
        }
    } catch (out_of_range) {
        cerr << "Index " << i << " is out of range!" << endl;
    }

    cout << "v.size() = " << v.size() << endl;

    return 0;
}

출력은 다음과 같습니다.

v[0] = 0
v[1] = 1
v[2] = 2
Index 3 is out of range!
v[0] = 0
v[1] = 1
v[2] = 2
Index 3 is out of range!
v.size() = 3

---------------------------------------------------------------------------------

여담1) 참고로, 자바를 써보셨던 분이라면 아실테지만,
자바의 배열은 이런 첨자 범위 검사를 무조건 합니다.
범위가 넘어가면 ArrayIndexOutOfBoundsException 예외를 throw합니다.
(헉헉헉... 거참 이름 한 번 기네요. -_-;)
바로 이런 점이 자바가 느린 이유 중에 하나죠.
속도보다는 안정성을 중시하는 자바의 철학이라고 할 수 있죠.

여담2) 자바에도 C++ STL을 흉내낸 컨테이너 클래스 라이브러리가 있습니다.
STL vector와 유사한 클래스로 Vector가 있는데,
자바는 연산자 겹지정(Operator Overloading)이 없으므로, [] 연산자를 쓸 수가 없습니다.
대신, vector::at()과 유사한 elementAt() 메소드를 씁니다.
v[1] 대신 v.elementAt()
물론 이 경우도 무조건 첨자 범위 검사를 합니다. 느릴 수 밖에요.
역시 범위가 넘어가면, 동일한 ArrayIndexOutOfBoundsException 예외를 throw합니다.

여담3) 이런 자바의 컨테이너 클래스 라이브러리는 C++ STL에 비하면 정말 허접합니다. -_-;
반드시 Object 클래스의 후손의 레퍼런스만 저장할 수 있고, int와 같은 기본 자료형을 저장할 수 없습니다.
또한 매번 원소를 액세스할 때 마다, 명시적으로 캐스팅(형 변환)을 해야 하는 지저분하고 위험한 코딩을 해야 합니다.
(마치, C++빌더 VCL의 TList의 허접함과 같죠. TList는 void*만 저장하기 때문에,
원소 삽입하려면 매번 new로 동적할당을 하고, 삭제할 때도 반드시 delete를 해야하며,
액세스할 때마다 캐스팅을 해야 하고요.

하여튼, 결론은 C++/STL이 최고라는거죠! *^^*

+ -

관련 글 리스트
29 [STL]vector나 deque의 인덱스의 범위를 검사하는 방법 김백일 10330 2002/07/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.