Menu
Coddy logo textTech

이터레이터 패턴

Coddy C 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 61개 중 56번째.

반복자 패턴(Iterator pattern)은 컬렉션의 내부 구조를 노출하지 않고 요소들에 순차적으로 접근할 수 있는 방법을 제공합니다. 사용자에게 배열에 직접 접근하게 하는 대신, 데이터를 한 번에 하나씩 순회하는 방법을 알고 있는 객체를 제공합니다.

반복자(iterator)는 일반적으로 두 가지 정보가 필요합니다: 컬렉션에 대한 참조와 현재 위치입니다. C 언어에서는 이 상태를 유지하기 위해 구조체(struct)를 생성합니다:

typedef struct {
    int* data;      // 배열을 가리키는 포인터
    int size;       // 전체 요소의 개수
    int current;    // 현재 위치
} IntIterator;

이 이터레이터는 두 가지 주요 함수를 제공합니다. has_next()는 읽을 요소가 더 있는지 확인하며, next()는 현재 요소를 반환하고 위치를 이동시킵니다:

int has_next(IntIterator* it) {
    return it->current < it->size;
}

int next(IntIterator* it) {
    return it->data[it->current++];
}

이터레이터를 사용하면 코드가 깔끔해 보이고 배열의 세부 사항을 숨길 수 있습니다:

IntIterator it = create_iterator(numbers, 5);
while (has_next(&it)) {
    printf("%d\n", next(&it));
}

호출자는 numbers가 배열이라거나 인덱싱이 어떻게 작동하는지 알 필요가 전혀 없습니다. 이러한 추상화는 나중에 이터레이터를 사용하는 코드를 변경하지 않고도 기본 데이터 구조를 — 예를 들어, 배열에서 연결 리스트로 — 쉽게 변경할 수 있게 해줍니다.

challenge icon

챌린지

쉬움

정수 배열의 내부 구조를 노출하지 않고 컬렉션을 순회할 수 있는 깔끔한 추상화 도구인 NumberList 반복자(iterator)를 만들어 봅시다.

코드는 다음 세 개의 파일로 구성합니다:

  • iterator.h: 정수 배열에 대한 포인터, 컬렉션의 전체 크기, 그리고 현재 위치를 저장하는 IntIterator 구조체를 정의합니다. 세 가지 함수를 선언하세요: create_iterator (배열 포인터와 크기를 받아 초기화된 반복자를 반환), has_next (남은 요소가 있는지 확인), next (현재 요소를 반환하고 위치를 이동). 인클루드 가드(include guards)를 잊지 마세요!
  • iterator.c: 반복자 함수들을 구현합니다. create_iterator 함수는 현재 위치가 0으로 설정된 IntIterator를 값으로 반환해야 합니다. has_next 함수는 읽을 요소가 더 있으면 1을, 그렇지 않으면 0을 반환합니다. next 함수는 현재 위치의 요소를 반환한 후 위치를 증가시킵니다.
  • main.c: 요소의 개수를 읽은 다음, 각 정수 값을 배열에 읽어 들입니다. 이 배열에 대한 반복자를 생성한 후, has_nextnext를 사용하는 while 루프를 통해 각 요소를 순회하며 한 줄에 하나씩 출력합니다.

프로그램은 다음을 입력받습니다:

  1. 배열의 요소 개수
  2. 각 정수 값 (각각 별도의 줄에 입력됨)

반복자 패턴을 사용하여 모든 요소를 출력하세요. 순회 루프 내에서 배열 인덱스에 직접 접근해서는 안 됩니다!

입력이 4이고, 이어서 10, 20, 30, 40일 때의 출력 예시:

10
20
30
40

입력이 3이고, 이어서 -5, 0, 100일 때의 출력 예시:

-5
0
100

입력이 1이고, 이어서 42일 때의 출력 예시:

42

반복자는 데이터가 저장되는 방식을 숨깁니다. 메인 루프는 배열 인덱스나 메모리 레이아웃에 대해 전혀 알 필요 없이 단순히 "더 있나요?"와 "다음 요소를 주세요"라고 요청하기만 하면 됩니다.

치트 시트

반복자 패턴(Iterator pattern)은 컬렉션의 내부 구조를 노출하지 않고 요소들에 순차적으로 접근할 수 있는 방법을 제공합니다.

반복자 구조체는 컬렉션 참조, 크기 및 현재 위치를 보유합니다:

typedef struct {
    int* data;      // pointer to the array
    int size;       // total number of elements
    int current;    // current position
} IntIterator;

반복자는 두 가지 주요 함수를 노출합니다:

int has_next(IntIterator* it) {
    return it->current < it->size;
}

int next(IntIterator* it) {
    return it->data[it->current++];
}

반복자를 사용하면 배열의 구현 세부 사항을 숨길 수 있습니다:

IntIterator it = create_iterator(numbers, 5);
while (has_next(&it)) {
    printf("%d\n", next(&it));
}

이러한 추상화를 통해 클라이언트 코드를 수정하지 않고도 내부 데이터 구조를 변경할 수 있습니다.

직접 해보기

#include <stdio.h>
#include "iterator.h"

int main() {
    int n;
    scanf("%d", &n);
    
    int arr[n];
    
    // TODO: n개의 정수 값을 배열로 읽어오기
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    
    // TODO: 배열을 위한 iterator 생성하기
    
    // TODO: 순회하기 위해 has_next와 next를 사용하는 while 루프 사용하기
    // 그리고 각 요소를 개별 줄에 출력하기
    // 순회 루프에서 직접적인 배열 인덱싱을 사용하지 마세요!
    
    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Object Oriented Programming의 모든 레슨