728x90
c언어를 공부하다보면 printf()가 함수임을 알게되고, 매개변수가 가변적으로 들어갈 수 있다는 것에 의문이 든다. printf()는 인자를 1개, 2개, 3개, ..... 몇 개를 넣어도 문제없이 돌아간다.
이것을 가능하게 해주는 것이 가변 인자라는 것이다.
printf의 프로토타입을 보면 아래와 같다.
int ft_printf(const char *, ...);
이 매개변수 중 ...이 가변 인자이다.
가변 인자(Variadic Arguments)란?
보통 함수에서 가변 인자를 정의할 때는 고정 매개변수가 한 개 이상 있어야 하며, 고정 매개변수 뒤에 ...을 붙여 매개변수의 개수가 정해지지 않았다는 표시를 해준다. 단, ... 뒤에는 다른 매개변수를 지정할 수 없다.
가변인자에 관련된 변수는 #include <stdarg.h>에 정의되어있다. (va_list, va_start, va_end 등)
va_start(va_list, lastfix)
void va_start(va_list ap, last);
- 스택 상의 첫 가변인수의 위치를 구해서 ap(가변 인자 포인터)에 대입한다. ap는 void 포인터변수(va_list)이며, 함수가 호출되기전에 선언되어 있어야한다.
- 두 번째 인수 lastfix는 고정 인수를 뜻한다. 고정 인수가 필요한 이유는 가변 인수의 시작번지를 찾기 위해서 중요한 역할을 한다. 그 다음의 번지가 가변인수의 시작번지 이기 때문이다.
va_arg(va_list, type)
- 가변인수를 읽는 함수, 첫 번째 인수 ap는 va_start가 사용한 ap와 동일한 변수이고, ap가 가리키는 번지의 데이터를 가변 인수로 읽는다.
- 두 번째 인수 type은 가변 인수의 데이터형을 나타낸다. 데이터형에 따라 데이터를 읽어 리턴한다고 생각하면 된다.
- type의 인수로는 char, float는 사용될 수 없다.
va_end(va_list)
- 가변 인수를 다 읽은 후, 함수가 정상적으로 리턴되도록 도와준다. va_end가 호출되면, ap가 변경되므로 va_start를 호출하지 않고는 가변 인수를 다시 읽을 수 없도록 한다.
va_list
- 가변 인수들에 대한 정보를 홀드 하기 위한 타입이다.
- 각 가변 인자의 시작 주소를 가리킬 포인터.
728x90
300x250