본문 바로가기

c++

[c++] Range-based for loop (범위 기반 for 문)

 

공부를 하는 입장이기 때문에, 내용에 오류가 있을 수 있습니다. 오류가 있다면 적극적으로 알려주시면 감사합니다!

 

Range-based for loop

 "표현식(expression)의 각 요소에 대해 문장(statement)을 반복적으로 순차적으로 실행합니다." 라는 범위 기반 for문은 배열이나 vector 등 순회가 가능한 expression속 요소들을 순회하는 기능을 한다. 

 

 기존의 for문과 다르게 시작지점과 끝지점을 정해주지 않아도 data list를 전부 순회한다. (파이썬의 for문 순회와 비슷)

 

for ( for-range-declaration : expression )
  statement

 

 위와 같은 방법으로 사용한다. expression 속 요소가 declaration 복사되어서 사용된다. for-range-declaration는

<data type>을 지정해줘야 하고, expression의 앞에는 ' : '가 와야 한다. 아래는 내가 직접 지뢰찾기를 만들 때 사용했던 예제이다. 

 

for (int element : mine_indices) {
    CELL::Cell* cell = this->map_list->GetData(element);
    cell->SetMine();
    std::cout << "mine num : " << element << std::endl;
    //cell->ShowMember();
}

 

 mine indices라는 배열에 지뢰의 위치 정보를 담고 순회하면서 map에다가 지뢰를 심는 구문이었다. 이 처럼 데이터를 순회할 때 범위 기반 for 루프가 많이 쓰인다. 

 

// Basic 10-element integer array.
int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// Range-based for loop to iterate through the array.
for( int y : x ) { // Access by value using a copy declared as a specific type.
    // Not preferred.
    cout << y << " ";
}
cout << endl;

 

 조금 더 간단한 microsoft에서 제공하는 예제이다. 예시를 보면은 "Not preferred." 라는 주석이 눈에 띈다. 범위 기반 for 문에는 가장 큰 문제가 존재하는데, declaration이 요소를 복사를 한다는 것이다. 깊은 복사를 하기 때문에 요소를 바꿀 수가 없고, 메모리를 점유한다는 문제점이 있다. 

 

#include <iostream>
#include <vector>
using namespace std;

int main(void) {
    int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    cout << "auto y : x 구문 출력 " << endl;
    for (auto y : x) { 
        y = y + 10;
        cout << y << " ";
    }
    cout << endl;

    cout << "배열 x 출력 " << endl;
    for (auto y : x) {
        cout << y << " ";
    }
    cout << endl;

	return 0;
}

 

 위에 코드를 살펴보면, 첫번째 for문에서 y에 10을 더 했지만 y는 복사된 값이기 때문에 x요소들에는 적용이 되지 않은 것을 알 수 있다. 

결과 값

 

 이런 문제를 해결하는 방법은, reference 즉 참조를 이용하는 것이다 참조를 이용하면 직접적으로 요소를 사용할 수 있고, 새로운 메모리를 생성하지 않는다는 특징이 있다.

 

cout << "auto& y : x 구문 출력 " << endl;
for (auto& y : x) { 
    y = y + 10;
    cout << y << " ";
}
cout << endl;

 

첫 번째 for문을 참조를 사용하게 된다면 직접적으로 요소를 사용할 수 있다.

결과 값2

 

이러한 장점 때문에 reference를 사용하는 것이 권장되고 있다. 

#include <iostream>
#include <vector>
using namespace std;

int main(void) {
    int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    cout << "auto& y : x 구문 출력 " << endl;
    for (auto& y : x) { 
        y = y + 10;
        cout << y << " ";
    }
    cout << endl;

    cout << "배열 x 출력 " << endl;
    for (const auto& y : x) {
        cout << y << " ";
    }
    cout << endl;

	return 0;
}

 

이와 같이 referenceconst를 적절하게 사용하는 것을 권장하고 있다. 

'c++' 카테고리의 다른 글

[c++] __VA_ARGS__, parameter pack  (0) 2024.04.30
[c++] 복사 생성자와 복사 대입 연산자  (1) 2024.04.29
04. C++만의 특징 2  (0) 2024.01.14
03. C언어 복습  (0) 2024.01.04
02. C++만의 특징 1  (0) 2024.01.03