해당 벨로그 주인장은 보너스를 구현하지 않았다. 나중에 해볼 의향이 있으나 그거 할 시간에 다음 과제를 밀겠다.
The prototype of ft_printf should be int ft_printf(const char *, ...);
You have to recode the libc’s printf function
It must not do the buffer management like the real printf
It will manage the following conversions: cspdiuxX%
It will manage any combination of the following flags: ’-0.*’ and minimum field width with all conversions
It will be compared with the real printf
You must use the command ar to create your librairy, using the command libtool is forbidden.
-> 그냥 %+(cspdiuxX%)의 기능을 잘 구현하시면 됩니다.
-> 고정인수는 반드시 하나 이상 있어야한다!
va_list ap
함수로 전달되는 인수들은 스택(stack)이라는 기억 장소에 저장되며 함수는 스택에서 인수를 꺼내 쓴다. 스택에 있는 인수를 읽을 때 포인터 연산을 해야 하는데 현재 읽고 있는 번지를 기억하기 위해 va_list형의 포인터 변수 하나가 필요하다. 변수 이름은 ap로 되어 있는데 ap는 어디까지나 지역 변수일 뿐이므로 이름은 마음대로 정할 수 있되 관습적으로 가변 인수를 다루는 매크로에서는 ap라는 이름을 사용한다. va_list타입은 char *형으로 정의되어 있다. 가변 인수를 읽기위한 포인터 변수를 선언했다고 생각하면 된다.
va_start(ap, 마지막고정인수)
이 명령은 가변 인수를 읽기위한 준비를 하는데 ap 포인터 변수가 첫 번째 가변 인수를 가리키도록 초기화한다. 첫 번째 가변 인수의 번지를 조사하기 위해서 마지막 고정 인수를 전달해주어야 한다. va_start 내부에서는 마지막 고정 인수 다음 번지로 ap를 맞추어 주므로 이후부터 ap 번지를 읽으면 순서대로 가변 인수를 읽을 수 있다.
va_arg(ap,인수타입)
가변 인수를 실제로 읽는 명령이다. va_start가 ap를 첫 번째 가변 인수 번지로 맞추어 주므로 ap위치에 있는 값을 읽기만 하면 된다. 단, ap번지에 있는 값이 어떤 타입인지를 알아야 하므로 두 번째 인수로 읽고자 하는 값의 타입을 지정해주어야 한다. 에를 들어 ap위치에 있는 정수값을 읽고자 한다면 va_arg(ap,int)를 호출하고 실수값을 읽고자 한다면 va_arg(ap,double)이라고 호출하면 된다. 이 명령은 ap위치에서 타입에 맞는 값을 읽어 리턴해주며 또한 ap를 다음 가변 인수 위치로 옮겨준다. 그래서 va_arg를 반복적으로 호출하면 전달된 가변 인수를 순서대로 읽을 수 있다.
va_arg함수는 매크로 함수이므로 인수타입에 int, double 같은 타입 이름을 인수로 전달할 수 있다. va_arg의 두 번째 인수는 내부적으로 sizeof 연산자와 캐스트 연산자로 전달되기 때문에 타입명이 될 수 있다.va_end(ap)
이 명령은 가변 인수를 다 읽은 후 뒷정리를 하는데 별다른 동작은 하지 않고 실제로 없어도 상관이 없다. 이 명령이 필요한 이유는 호환성 때문인데 플랫폼에 따라서는 가변 인수를 읽은 후에 뒷처리를 할 필요가 있기 때문이다. intel계열의 CPU에서는 아무 일도 하지 않는다. 하지만 호환성을 위해 관례적으로 넣어주는 것이 좋다.