<함수 로직을 짜보자>
- 구조체
typedef struct s_list
{
int minus_flag;
int plus_flag;
int zero_flag;
int space_flag;
int shap_flag;
int width;
int precision;
} t_list;
: 구조체안에 변수들은 -, +, 0, ' ', # 와 같은 flag와 min-width, precision이고, 역활은 flag나 min-width, precision이 갱신되었을 때 저장
- 메인 로직인 ft_printf
int ft_printf(const char *args, ...)
{
va_list ap;
int val;
t_list *flag;
flag = (t_list *)malloc(sizeof(t_list));
va_start(ap, args);
val = 0;
while (*args)
{
if (*args == '%')
ft_print_check((char **)&args, flag, ap, &val);
else
ft_putchar(*args);
args++;
}
va_end(ap);
free(flag);
return (val);
}
위에서 아래로 로직 설명
<변수 선언>
- 가변인자를 받기 위해서는 가변인수들을 저장할 공간이 필요하게 된다.
따라서 va_list라는 타입이 가변공간을 의미하기 때문에 위에서와 같이 va_list ap를 선언해준다. 여기서 ap는 가변인수를 저장하는 스택 주소 포인터를 의미함.
- 정의한 구조체를 사용하기위해 구조체 포인터 변수를 선언.
- ft_printf 함수의 반환값이 출력문자의 길이를 의미하므로 그 길이를 셀 변수 선언
<변수 초기화>
- 구조체 크기만큼 malloc함수를 사용해 할당해 줌.
- va_start(ap, args) 의미 :
args를 인자로 받는 이유는 첫 번째 가변인자 주소를 알려면 고정인수가 필요하기 때문
ap를 인자로 받는 이유는 va_list로 선언한 ap를 초기화 하기 위해서임.
- val를 0으로 초기화 해 줌
<while문 로직>
- args의 주소를 하나씩 증가시키면서 args의 변수 중 '%'가 있는지 확인하고 있으면 그때의 주소값과 구조체 flag, 가변인수 포인터, 출력문자 길이를 셀 val변수의 주소를 ft_print_check함수에 넘김.
- 이 함수에 들어가서 서식지정자를 만나면 그때의 주소값을 가지고 빠져나옴.
- '%'가 아니면 ft_putchar함수에 args의 변수를 넘겨 그대로 출력
- args의 주소값을 1증가시키고 널값이 아닐때 까지 위 과정 반복
<할당해제>
- va_list타입을 널로 초기화해줌. why? 가변인자 다 읽었으니까.
- malloc으로 할당해준 구조체 변수를 해제시켜줌.
<반환>