가변 인자

아따맘마·2020년 11월 6일
0

ft_printf

목록 보기
1/9

일반적인 함수에 매개변수를 쓸 때는 개수가 정해져있다. 예를 하나 들면

size_t	strlen(const char *str);

문자열의 길이를 재는 strlen의 같은 경우에는 매개변수가 하나로 고정되어 있다.
그런데 이런 가정을 해보자. 어떤 경우에는 매개변수를 하나만 쓰고 싶고, 또다른 경우에는 여러개를 쓰고 싶다고 한다면? 각각의 경우마다 함수를 만들기에는 너무 커진다.
그럴때를 대비하여 가변 인자라는 것을 사용한다.

가변 인자 사용 방법

  • 헤더
#include <stdarg.h>

가변인자를 사용하기 위해서는 헤더 stdarg.h를 정의해줘야 한다.

  • 함수에서 사용방법
함수_타입 함수_이름(기본 고정_매개변수, ...)

기본 고정매개변수를 쓰던 함수와는 다르게 두번째 매개변수에 '...' 이 들어간다.
일반적인 printf를 쓰는 예제를 들어보자

# printf 함수 정의 : int	prtinf(const char *format, ...);

printf("size is %d", size);

첫번째 고정 매개변수 format엔 문자열 "size is %d"가 들어가고 가변인자인 ...에는 size라는 변수가 들어간다. 이 때 size는 문자열 내의 %d와 매칭되는 것을 알 수 있다.
이 가변 인자를 커스텀한 ft_printf에서 사용하고자 한다면 함수 내부에서는 어떤 설정을 해줘야 할까

함수 내부에서의 가변인자

int	ft_printf(const char  *format, ...)
{
	va_list ap;
    
    	va_start(ap, format);
        ...
        va_end(ap);
}
  • va_list : 가변 인자 목록. 가변인자의 메모리 주소를 저장하는 포인터
  • va_start : 가변 인자를 가져올 수 있도록 포인터를 설정
  • va_end : 가변 인자에 대한 처리가 끝나면 포인터를 NULL로 초기화
    위에서 쓰인 가변 인자 처리 메크로 외에도
  • va_arg : 가변인자 포인터에서 특정 자료형 크기만큼 값을 가져온다.
    가 있다.

va_list는 어떻게 매개변수들의 메모리 주소를 저장할까??
만약 모든 가변 인자들의 값이 같다면 (예를 들어 모두다 char형이라고 하자)

int	ft_printf(const char *format, ...)
{
	va_list ap;
    
    	va_start(ap, format);
        ...
}

ft_printf("%c %c %c", 'a', 'b', 'c');

printf를 실행하는데 'a', 'b', 'c'를 출력하고자 한다. 그러면 ap라는 가변 인자 리스트에는 va_start(ap, format)라는 메크로로 인해

와 같이 만들어진다. 이 때 va_arg(ap, char)을 이용한다면 1바이트씩 넘기면서 값을 가져올 수 있다.(만약 int형이라면 4바이트씩)
하지만 printf를 쓰다보면 여러가지 변수형을 사용하게 되는데, 그렇다면 서로 다른 가변 인자들은 어떻게 처리를 할까??
printf에는 여러 자료형을 쓸 수 있다. 그 중에는 정수형인 '%d', 실수형인 '%f', 문자열인 '%s', ... 등등이 있다. 그러면 일반적인 생각으로 따지자면 %를 만나고 그 다음에 어떤 문자가 존재하냐에 따라 메모리를 다음으로 넘겨주면 되지 않을까??

ft_printf("%s, %c, %f", "hello wolrd", 'a', 3.141592);


그러면 같은 자료형을 만들었을 때와는 다르게 여러 자료형이 들어있는 리스트가 생성될 것이다.
그러면 각각의 자료형 크기만큼 이동하면서 값을 뽑아내오면 된다.

profile
늦게 출발했지만 꾸준히 달려서 도착지점에 무사히 도달하자

0개의 댓글