42Seoul/Printf

[C] printf() 구현하기 (1) - introduction (가변 인자)

  • -
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
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.