티스토리 뷰

IT/C, C++

[C++11] 범위 기반의 for문 (range based for)

주인장 진빼이

먼저 기존 for문과 비교하여 범위 기반의 for문에 대해 장점 및 단점을 보자.

장점:

  1. 코드가 짧고 편리하다.
  2. std container(vector, list, map...)와 혼합하여 사용할 수 있다.
  3. for문 속도차이도 크게 나지 않는다.
  4. 참조자(reference)와 auto를 이용한다면 더욱 빠르게 코딩할 수 있다.

단점:

  1. 반복 배열의 접근 Index가 없다.
  2. 모든 배열을 0부터 끝까지 탐색해야 한다.

 

사용방법:

for(type element : element_array)

 

왼쪽 항에는 배열 요소에 해당하는 타입과 임시 객체 변수를 적어준다.

임시 객체는 탐색하면서 인덱스 0부터 끝까지 해당하는 요소가 element_array에서 복사된다.

오른쪽 항에는 탐색할 배열 및 리스트 컨테이너를 적어주면 된다.

 

객체가 복사되기 때문에 element 로만 접근했을 때 변수의 주소 값이 서로 다르기 때문에

기존 배열 element_array가 가지고 있는 값들을 변경할 수 없다.

 

 

간단히 0부터 7까지 총 8개의 요소를 출력하는 코드를 적어보자

#include <iostream>
#include <vector>

using namespace std;
int main()
{
    vector<int> numbers_vec = { 0, 1, 2, 3, 4, 5, 6, 7 };
    for(int num : numbers_vec)
    {
        cout << num << ' ';
    }
    
    cout << '\n';
    
    int numbers_arr[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
    for(int num : numbers_arr)
    {
        cout << num << ' ';
    }
}

두 배열(vec, arr)은 요소가 동일하며,  탐색하는 인덱스 모두 같다.

결과도 동일하다.

 

 

기본형 타입이 아닌 구조체 및 클래스로도 사용할 수 있다.

#include <iostream>
#include <vector>

using namespace std;

class Student
{
public:
    int id;
    string name;

    Student(int _id, string _name) {
        this->id = _id;
        this->name = _name;
    }
    Student() {}

    void ShowData()
    {
        cout << "번호: " << this->id << "  이름: " << this->name << '\n';
    }
};


int main()
{
    vector<Student> student_vec = {
        { 10, "찰리"},
        { 20, "제임스"},
        { 30, "미셸"}
    };

    for(Student stu : student_vec)
    {
        stu.ShowData();
    }
}

 

 

 

배열 복사 및 요소 값의 변경:

예제 코드는 너무 단순하고 데이터 크기도 작아서 상관이 없지만

만약 복잡한 시스템이나 프로그램인 경우 오브젝트 및 객체의 크기가 클 수 있다.

 

크기가 큰 객체를 단순히 출력을 하거나 접근을 할 때 다른 메모리 공간에 복사하는 건 시간과 비용 부담이 크다.

참조자(reference)를 이용하면 객체가 복사되지 않고 참조하기 때문에 더 빠르게 처리할 수 있다.

 

타입도 일일이 적어주기보다 프로그램이 큰 경우 네임스페이스 및 상속 영향으로 타입이 복잡하고 길어질 수 있으며

C++11에서 지원하고 있는 auto 타입을 이용해 타입을 자동으로 잡아주도록 하자.

 

for(auto &element : element_array)

위와 같이 코드를 적으면 element 배열 요소에 해당하는 변수는 element_array에서 임시 객체를 복사하는 것이 아니고 참조되는 것이다.

참조자를 이용해서 배열 범위의 주소에서 요소에 해당하는 주소로 참조를 하기 때문에 기존 배열의 값도 변경할 수 있다.

 

 

 

빠른 처리 및 요소 값 변경 방지:

객체는 복사되지 않고 참조로 빠르게 접근하며 단순 값을 출력하는 것이라면 값 변경 시도 자체를 막을 수 있다.

값 변경 시도를 막는 제한자(const)와 빠르게 접근할 수 있는 참조자(reference)를 이용하는 것이다.

 

for(const auto& element : element_array)

const 참조자에 해당하는 객체의 함수를 호출하기 위해서는 함수에도 const 속성이 적용되어야 한다.

 

이젠 C++11, C++14가 메인이 되고 있다.

온라인 컴파일러 사이트에서도 C++11이 기본 컴파일러로 채택되고 있다.

 

 

길고 난해한 iterator보단 C++11에서 새로 도입된 기능을 사용하도록 하자.

만약 배열 요소 접근 Index가 필요하다면 범위 기반의 for문(range based for)은 사용할 수 없으니

이점 유의하도록 하자.

 

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함