man 3 stdarg 명령으로 stdarg에 관한 메뉴얼을 읽어봤다.
다음은 메뉴얼 페이지에 있는 각 함수의 원형이다.
#include <stdarg.h>
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_copy(va_list dest, va_list src);
void va_end(va_list ap);
va_list : 각 가변 인자의 시작 주소를 가리킬 포인터. 내부적으로는 char * 로 정의되어 있다.
va_start() : va_list로 만들어진 포인터에게 첫 번째 가변인자의 주소를 가르쳐준다.
va_arg() : 특정 가변인자를 가리키고 있는 va_list의 포인터를 다음 가변인자로 이동시켜준다.
va_arg는 type으로 int 보다 작은 자료형을 받을 수 없다고 한다.
관련 링크는 -> https://stackoverflow.com/questions/28054194/char-type-in-va-arg#:~:text=So%20a%20variadic%20function%20can,all%20functions%20behaved%20this%20way
va_copy() : va_start()에 의해 초기화 되었던 이전의 가변인자 리스트가 복사된다. dest 는 va_start()에 의해 초기화되지 않은 변수여야 한다.
그리고 가변인자를 잘 이해할 수 있는 예제코드
#include <stdio.h>
#include <stdarg.h>
void foo(char *fmt, ...)
{
va_list ap;
va_list ap2;
int d, i;
char c, *s;
i = 0;
va_start(ap, fmt);
va_copy(ap2, ap);
while (fmt[i] != '\0')
switch(fmt[i++]) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* Note: char is promoted to int. */
c = va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
//...
/* use ap2 to iterate over the arguments again */
/* we don't have to use va_start() here */
i = 0;
while (fmt[i] != '\0')
switch(fmt[i++]) {
case 's': /* string */
s = va_arg(ap2, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap2, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* Note: char is promoted to int. */
c = va_arg(ap2, int);
printf("char %c\n", c);
break;
}
va_end(ap2);
}
int main()
{
foo("sddcc", "always", 4, 3, 99, 'p');
return 0;
}
참고
'공부기록 > 42 Seoul' 카테고리의 다른 글
[ft_server] SSL 인증서 작동 원리 (2) | 2020.09.15 |
---|---|
[ft_printf] 03 libft.a 를 다른 프로젝트에서 사용할 수 있게 하기 (0) | 2020.07.18 |
[ft_printf] 01 printf 함수에 대하여 (0) | 2020.07.16 |
get_next_line Valgrind 캡쳐 (0) | 2020.06.07 |
norminette 메시지 (0) | 2020.04.06 |