[C++] range-based-for 범위 기반 for문 _ 미완성
- Archive2/C&C++
- 2022. 3. 17.
*개인적인 공부 내용을 기록하는 용도로 작성한 글 이기에 잘못된 내용을 포함하고 있을 수 있습니다.
#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
'Archive2 > C&C++' 카테고리의 다른 글
[C++] 알파벳 대소문자 관련 함수_ islower & isupper & tolower & toupper (0) | 2022.05.27 |
---|---|
[C++ STL] find() - 범위(Vector, Array..) 내에서 값을 탐색하는 함수 (0) | 2022.05.19 |
[C++] #3.1 멤버 초기화 리스트 _ Member Initializer List (0) | 2022.02.23 |
[C++] #3 생성자 (Constructor) (0) | 2022.02.23 |
[C++] #2 getter setter 함수 (0) | 2022.02.22 |