[C++] range-based-for 범위 기반 for문 _ 미완성

    반응형

    *개인적인 공부 내용을 기록하는 용도로 작성한 글 이기에 잘못된 내용을 포함하고 있을 수 있습니다.

     

    #1 range-based-for

    #2 range-based-for & auto

    #3 range-based-for 단점

    #4 range-based-for & reference

    #5 range-based-for & const


    #1 range-based-for

    int main(void) {
    	int ary[5] = {10, 20, 30, 40, 50};
    	for (int i = 0 ; i < 5 ; i++) {
    		cout << ary[i] << " ";
    	}
     	return 0;
    }
    [출력결과] 10 20 30 40 50

    for문을 이용해 배열의 원소를 모두 탐색한 간단한 코드이다. 반복문을 사용하면 간단하고 유연하게 배열의 원소에 접근할 수 있지만, 프로그래머의 실수로 인해 오류를 발생시킬 위험이 있다.

    C++11 부터는 이러한 단점을 보완하기 위한 보다 편리한 range-based-for 문법을 제공한다.

     

    range-based-for의 기본 형식은 다음과 같다. 순회가능한 데이터 리스트에는 배열 뿐 만 아니라 STL의 vector, list, map.. 등이 모두 들어갈 수 있다.

    for(데이터타입 변수이름 : 순회가능한 데이터 리스트) {
    	...
    }

    range-based-for을 이용해 배열을 탐색해 보았다. 단순 for반복문을 사용하는 것 보다 안전하고 깔끔하게 배열의 원소에 접근할 수 있다.

    int main(void) {
    	int ary[5] = {10, 20, 30, 40, 50};
    	for (int iter : ary) {
    		cout << iter << " ";
    	}
     	return 0;
    }

    #2 range-based-for & auto

    range-based-for문법을 사용할 때 데이터타입에 auto키워드를 사용해 자료형을 추론하게 하는 것이 이상적이다.

    자료형을 명확하게 알고 있는 상황이라면 크게 문제되지 않지만, 혹여나 그렇지 않다면 강제 자료형 변환이 발생할 수 있기 때문이다.

    for(auto 변수이름 : 순회가능한 데이터리스트) {
    	...
    }
    int main(void) {
    	int ary[5] = {10, 20, 30, 40, 50};
    	for (auto iter : ary) {
    		cout << iter << " ";
    	}
     	return 0;
    }

    #3 range-based-for 단점

    range-based-for은 몇 가지 단점을 가지고 있다. (물론 이를 보완할 수 있는 여러가지 방법이 있다. 이에 대해서는 바로 소개할 예정이다.) 

    range-based-for 내부에서 요소의 값을 변경하는 것이 불가능하다. 왜냐하면 range-based-for은 요소를 복사한 값으로 취급하기 때문이다. 

    int main(void) {
    	int ary[5] = {10, 20, 30, 40, 50};
    	for (auto iter : ary) {
    		iter += 100;
    	}
    	for (auto iter : ary) {
    		cout << iter << " ";
    	}
     	return 0;
    }
    [출력결과] 10 20 30 40 50

    반면에 for문을 직접 원소에 접근하기에 배열 내부의 원소의 값을 변경할 수 있다.

    int main(void) {
    	int ary[5] = {10, 20, 30, 40, 50};
    	for (int i = 0 ; i < 5 ; i++) {
    		ary[i] += 100;
    	}
    	for (int i = 0 ; i < 5 ; i++) {
    		cout << ary[i] << " ";
    	}
     	return 0;
    }

    다음으로 range-based-for은 요소를 복사된 값으로 취급하기에 for문과 달리 "복사비용"이 발생한다. 이는 배열의 크기가 작다면 크게 문제가 되지 않겠지만, 배열의 크기가 커질 경우 loop를 할 때 마다 매번 복사비용이 발생하기에 심각한 메모리 낭비가 야기된다.


    #4 range-based-for & reference

    사실 앞서 설명한 단점은 C++의 참조자(&)를 사용하면 해결 가능하다. 자료형 뒤에 &키워드를 붙여주면 원소에 직접 접근하기에 배열 내부 원소의 값을 변경할 수 있으며 복사 비용 또한 발생하지 않는다.

    for (auto& 변수이름 : 순회가능한 데이터리스트) {
    	...
    }
    int main(void) {
    	int ary[5] = {10, 20, 30, 40, 50};
    	for (auto& iter : ary) {
    		iter += 100;
    	}
    	for (auto& iter : ary) {
    		cout << iter << " ";
    	}
     	return 0;
    }
    [출력결과] 110 120 130 140 150

    #5 range-based-for & const

    배열의 원소를 변경하지 않고 탐색만 하고자 하는 경우에는 const 키워드를 사용하는 것이 바람직하다.

    자료형 앞에 const 키워드를 사용하면 원래의 원소를 변경하지 못하기에 에러가 발생할 여지를 차단할 수 있고, 참조자를 사용하기에 복사비용도 발생하지 않는다. 

    for (const auto& iter : 순회 가능한 데이터리스트) {
    	...
    }
    int main(void) {
    	int ary[5] = {10, 20, 30, 40, 50};
    	for (const auto& iter : ary) {
    		cout << iter << " ";
    	}
     	return 0;
    }
    [출력결과] 10 20 30 40 50

     

    #6 range-based-for & initializer list

    반응형

    댓글

    Designed by JB FACTORY