페이지가 로드되지 않나요? 여기를 눌러보면 고쳐질 수도 있어요.
Placeholder

#8559

Tutorial : range-based for문 2s 1024MB

문제

5칸의 배열 A를 처음(0번 칸)부터 끝(4번 칸)까지 출력하는 코드는 아래와 같다.

너무 너무 간단한 코드다.

int A[5] = {10, 20, 30, 40, 50};

for(int i = 0; i < 5; i++){
    printf("%d ", A[i]);
}

이번 시간에 배워볼 것은, 약간 다른 형태의 for 문이다.

직접 코드를 보면서 얘기하자.

int A[5] = {10, 20, 30, 40, 50};

for(int element : A){
    printf("%d ", element);
}

위 코드도 처음 코드와 똑같이 작동한다. 다만 for 문의 형태만 살짝 다를 뿐이다.

위 형태의 for 문을 range-based for 문 이라고 한다. ( C++11 부터 도입된 문법이다. )

형태는 아래와 같다. 예시 코드와 대응 시켜보자.

항상 맨 처음에 자료형을 명시한다. ( int, double, char ... 등등 )

우리가 보고 싶은 배열 A 의 자료형은 int 였으니, 이거에 맞춰서 int 를 써준 것이다.

그 후 변수 이름을 써주고, colon ( : ) 을 옆에 써준다. ( 우리가 각 줄 끝에 쓰는 semi - colon ( ; ) 이 아니다 !! )

마지막에, 우리가 살펴보고 싶은 컨테이너 이름을 써준다.

컨테이너(container)란, 원소들을 담을 수 있는 자료형으로, 배열, Map, Vector, Set 등등이 있다. ( 다 뒤에서 배웁니다 !! )

위 예시처럼 A 를 써주면, A 라는 배열의 원소들을 순서대로 모두 살펴보겠다는 뜻이다.

그러면, element 는 배열 A 에 담긴 원소 그 자체의 값이 된다.

무슨 말이냐면, 위 예시에서,

처음에 A[0] 의 값인 10 이 element 에 저장된다.

그 후 A[1] 의 값인 20 이 element 저장되고,

이어서 30, 40, 50 이 element 에 차례대로 저장된다.

마지막 원소까지 element 에 저장되고 나면, for 문이 자동으로 끝나게 된다.

따라서 위 코드처럼 element 를 출력하면, A 배열의 원소들이 처음부터 끝까지 순서대로 출력된다.

( 출력 결과 : 10 20 30 40 50 )


만약 이렇게 코드를 짜면? A 배열이 변할까? 생각해보자.

int A[5] = {10, 20, 30, 40, 50};

for(int element : A){
    element += 5;
}

결론을 말하자면, 아니다.

각 element 에 5 씩 더했더라도, 원본 배열인 A 는 그대로 [10, 20, 30, 40, 50] 이다.

왜 그럴까?

element 는 A 배열의 값을 "복사"해 오기 때문이다.

element 를 바꾼다고 해서 A 배열이 바뀌지 않는다. element 는 단지 "복사본"이기 때문이다.

그렇다면, A 배열이 바뀌게 하려면 어떻게 하면 될까?

element 앞에 & 를 붙이면 된다.

자기주도C언어프로그래밍 함수 단원에서 배운 참조에 의한 전달과 비슷한 개념으로,

element 가 복사본이 아닌, A 배열의 원본 그 자체로 작동한다.

따라서 아래처럼 &element 로 코드를 짜야 A 배열이 실제로 [15, 25, 35, 45, 55] 로 바뀐다.

int A[5] = {10, 20, 30, 40, 50};

for(int &element : A){ // & 기호에 유의!
    element += 5;
}

이를 이용하면 입출력 모두 range-based for 문으로 가능하다.

입력할 때는 element 앞에 & 를 붙여서 A 배열을 실제로 수정하면 된다.

출력할 때는, A 배열의 값을 읽어오기만 하지 수정하지는 않기에, 굳이 & 를 붙일 필요 없다. ( 붙여도 상관은 없음 )

int A[5];

for(int &element : A){
    scanf("%d", &element);
}

for(int element : A){
    printf("%d ", element);
}


아래는 참고 사항이다. range-based for 문을 쓸 때 주의할 점이다.

* 이미 선언된 변수를 넣고, 자료형을 생략하면 안 된다 !

int element;
for(element : A){  // 오류 !!
    printf("%d ", element);
}

위 코드처럼, 미리 element 를 선언해 놓고, int 를 생략한 채로 짜면 컴파일 에러가 난다.

반드시 for 문 안에서 변수를 새롭게 선언해야 한다. ( 자료형 명시가 필수다. )

* 무조건 배열의 처음부터 끝까지 다 돌아보게 된다.

배열의 특정 칸부터 시작해서, 특정 칸까지만 보도록 할 수 없다.

즉, 배열 A가 있을 때, A[1] 부터 돌아보게 할 수도 없다. 무조건 A[0] 부터 출발하기 때문.

따라서, 만약 원소 10개를 입력받고 싶다면, 무조건 배열 A를 정확히 10칸만 만들어 놔야 한다.


이제 range-based for 를 응용하여 아래 문제를 풀어보자.

10개의 정수들을 입력 받고, 각 수에 1 을 더한 결과를 정렬하여 출력하자. ( 정렬 시에는 STL Sort 함수 사용 )

for 문을 쓸 때는, 반드시 방금 배운 range-based for문 만을 사용하여 풀어본다.


입력

10개의 정수들이 차례대로 입력된다. ( 0 이상 1만 이하 )


출력

각 정수들에 1 을 더한 결과를 정렬하여 출력한다.


예제

7 8 3 7 2 10 3 0 3 4
1 3 4 4 4 5 8 8 9 11


출처

againalgo

로그인해야 코드를 작성할 수 있어요.