문제
range-based for문 을 완벽하게 이해했다면, 지금 배울 auto 까지 이해해보자.
auto 는 영어로 "자동" 이라는 뜻이다. 즉, 자동으로 자료형을 추측해서 맞춰준다!
아래 코드를 보자.
int main(){
auto three = 3; // three 의 자료형은 int
auto pi = 3.14; // pi 의 자료형은 double
auto str = "apple"; // str 의 자료형은 const char* ( 즉, const 라서 수정할 수 없음 )
}변수 three 의 자료형을 auto 로 해놓고 3 을 대입하면,
컴퓨터는 대입 되는 값인 3 이 정수(int) 이기 때문에 자동으로 three 의 자료형을 int 로 설정한다!
잘 쓰면 굉장히 편리하지 않을까?
이처럼 auto 는 오른쪽에 대입 되는 값의 자료형에 맞추어, 변수의 자료형을 자동으로 맞춘다.
단, 주의할 점이 있다.
int main(){
auto a; // Compile Error! 대입 되는 값이 없어 자료형 추측을 못 함
a = 3; // 이미 윗 줄에서 Compile Error 발생했음... 뒤늦게 대입해도 소용 없음
auto pi = 5; // pi 의 자료형은 int 로 맞춰짐
pi = 3.14; // pi 는 이미 int 기 때문에, 3만 저장됨
}첫 번째 예시인 a 처럼, auto 로 선언만 하고 즉시 값을 대입 안 하면 컴파일 에러가 난다.
대입 되는 값이 없기에, 자료형을 맞춰줄 수 없기 때문이다.
두 번째 예시에서는, pi 에 5 가 대입 됐기에 pi 의 자료형은 자동으로 int 가 된다.
따라서 이후 pi 에 3.14 를 담아줘도, pi 는 이미 int 로 돼있기에 3 만 저장된다.
auto 를 이용하면 다양한 작업을 매우 편하게 할 수 있다.
우선, 기본적인 range-based for문도 auto 로 짤 수 있다.
밑 코드에서 element 의 자료형은 자동으로 int 가 된다. 대입 되는 배열 A 의 자료형이 int 기 때문이다.
int A[5] = {1, 2, 3, 4, 5};
for(auto element : A){ // element 의 자료형은 자동으로 int
printf("%d ", element);
}만약 앞서 배운 pair 자료형 배열에 이를 적용하면?
밑 코드에서 element 의 자료형은 자동으로 pair<int, int> 가 될 것이다.
그러므로 앞 원소를 보고 싶다면 element.first, 뒷 원소를 보고 싶다면 element.second 를 해주면 된다.
pair <int, int> A[3] = { {1, 2}, {3, 4}, {5, 6} };
for(auto element : A){ // element 의 자료형은 자동으로 pair <int, int>
printf("%d %d\n", element.first, element.second);
}
// 출력 결과
1 2
3 4
5 6그런데, 여기서 중요한 점은, A 의 자료형은 pair 이기 때문에, 항상 ( 변수, 변수 ) 형태의 순서쌍이라는 것이다.
auto 로 이를 두 개의 변수로 자동 분리하는 것도 가능하다!
아래 코드를 보고 이해해보자.
pair <int, int> A[3] = { {1, 2}, {3, 4}, {5, 6} };
for(auto [x, y] : A){ // x 는 자동으로 앞 숫자, y 는 자동으로 뒷 숫자가 된다.
printf("%d %d\n", x, y);
}
// 출력 결과
1 2
3 4
5 6대괄호를 이용하여 [x, y] 를 지정해주면,
x 와 y 는 자동으로 A 배열에 들어있는 순서 쌍의 값이 된다.
즉, 아까는 처음에 element = {1, 2} 가 됐다면,
이번엔 처음에 [x, y] = {1, 2} 가 되는 것이다. 자동으로 x = 1 , y = 2 가 된다.
굳이 처음 코드처럼 .first, .second 를 붙이지 않아도 되는 것이다!
array 자료형도 마찬가지다. 아래 코드처럼 단일 변수 element 로 해도 되고, [x, y, z]로 변수 분리를 해도 된다.
array <int, 3> A[3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
for(auto element : A){
printf("%d %d %d\n", element[0], element[1], element[2]);
}
for(auto [x, y, z] : A){
printf("%d %d %d\n", x, y, z);
}구조체에서도 적용 된다. 이 코드를 실행시켜보자.
#include <stdio.h>
struct Data{
int x, y;
double z;
};
int main(){
Data arr[3] = { { 1, 2, 0.1 }, { 3, 4, 0.2 }, { 5, 6, 0.3 } };
for(auto element : arr){ // element 의 자료형은 자동으로 Data 가 된다.
printf("%d %d %.1f\n", element.x, element.y, element.z);
}
printf("\n");
for(auto [a, b, c] : arr){ // a, b 의 자료형은 자동으로 int, c 의 자료형은 자동으로 double
printf("%d %d %.1f\n", a, b, c);
}
}첫 번째 for 문처럼 단일 변수 element 로 써주면 element 의 자료형은 자동으로 Data 가 되고,
두 번째 for 문처럼 3 개의 변수 [ a, b, c ] 로 써주면, Data 에 들어있는 세 개의 변수 x, y, z 가 순서대로 a, b, c 에 담기는 것이다.
주의 사항
단, 살짝 주의할 점은, 입력을 받는 것처럼 배열의 값을 수정할 때는 & 를 붙여야 하는데,
for ( auto &[a, b, c] : arr ) 처럼, 변수들을 분리했을 경우에는 대괄호 앞에 & 기호를 붙여야 한다.
다른 방법으로는, for ( auto &element : arr ) 처럼 단일 변수로 참조해도 된다.
<응용 문제>
이제 이를 활용하여 문제를 풀어보자.
string name(이름), int age(나이) 를 10개 담는 배열을 만들자.
이들의 정보를 입력 받고,
1 순위 : age 의 내림차순, 2순위 : string 의 오름차순(사전순)으로
정렬된 결과를 출력하자.
학습을 위하여, for 문을 쓸 때는 반드시 auto 를 활용한 range-based for 문을 사용해보자.
입력
10줄에 걸쳐 name 과 age 가 입력된다.
출력
문제에서 요구한 정렬 기준으로 정렬한 후 출력하자.
예제
mbappe 26
haaland 24
ronaldo 40
vinicius 24
messi 38
yamal 18
sancho 24
alvarez 24
hakimi 26
suarez 38
ronaldo 40
messi 38
suarez 38
hakimi 26
mbappe 26
alvarez 24
haaland 24
sancho 24
vinicius 24
yamal 18