알고리즘 문제를 풀다가 add
연산의 입력이 특이하게 주어지는 문제를 보게 되었다.
cmd | add |
argc | 4 |
argv | 23, 11, 41, 42 |
즉, add 4 23 11 41 42
이렇게 입력이 주어진다는 뜻이다.
단순하게 for문을 이용하여 argc 만큼 반복해주며 args의 요소들을 더해주어도 된다.
하지만, 함수로 구현하고자 한다면, 가변인자라는 것을 활용하여 변하는 데이터들을 인자로 받을 수 있도록 해야한다.
우리가 만든 대부분의 사용자 함수는 고정인자를 많이 사용했을 것이다.
다시 말해서 void func(int a, int b)
라는 함수를 만들었다면,
a와 b를 고정인자로 받는 func 함수
를 만들었다는 뜻이다.
가변인자(Variable argument)는 말 그대로 고정되지 않은 인자 를 뜻한다.
정해지지 않은 개수의 인자를 받을 때 사용하며,
아래와 같이 함수의 매개변수를 ...
로 적어 가변인자를 사용할 수 있다.
void add(int argc, ...)
가변인자를 사용하기 위해선 <cstdarg>
헤더파일이 필요하다.
그리고 해당 헤더파일에는 다음과 같이 4개의 매크로가 지정되어 있다.
#define va_start __crt_va_start
#define va_arg __crt_va_arg
#define va_end __crt_va_end
#define va_copy(destination, source) ((destination) = (source))
typedef char* va_list;
va_list
는 char형 포인터로 가변인자의 주소를 나타내기 위해 사용한다.
va_start(va_list ap, T preV);
va_start
는 ap가 preV(고정인자) 바로 뒤인 가변인자의 시작 위치를 가르키도록 한다.
그리고 다음과 같이 사용하면 된다.
va_list VA_LIST;
va_start(VA_LIST, argc);
va_arg(va_list ap, type);
va_arg
는 ap가 위치한 데이터를 type으로 읽는 함수라고 보면 된다.
va_arg를 호출시키면, va_start로 할당된 ap의 값(가변인자)을 type형식에 맞춰 리턴한 후, ap의 주소를 type만큼 뒤로 이동시켜준다. 그렇게되면 다음 가변인자의 주소값이 ap로 할당된다. 이를 가변인자의 개수만큼 반복하면서 모든 가변인자를 출력하게 만들면 되는 것이다.
for (int i = 0; i < args; i++) {
int n = va_arg(VA_LIST, int);
cout << n << "\n";
}
va_end(va_list ap);
va_end
는 va_list 타입의 변수를 받으며 ap를 초기화 전의 상태로 만든다.
va_end(VA_LIST);
#include <iostream>
#include <cstdarg>
using namespace std;
int add(int argc, ...) {
va_list VA_LIST;
va_start(VA_LIST, argc);
int sum = 0;
for (int i = 0; i < argc; i++) {
sum += va_arg(VA_LIST, int);
}
return sum;
}
int main() {
cout << add(0) << "\n"; // 0
cout << add(1, 2) << "\n"; // 2
cout << add(4, 1, 2, 3, 4) << "\n"; // 10
return 0;
}
0
2
8
https://blankspace-dev.tistory.com/235
https://hydroponicglass.tistory.com/285
https://woo-dev.tistory.com/53