일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- France
- comic agile
- django
- Spain
- hbase
- Italy
- management
- essay
- programming_book
- erlang
- QT
- Programming
- leadership
- Kuala Lumpur
- RFID
- MySQL
- Linux
- psychology
- hadoop
- Book review
- Book
- agile
- web
- Malaysia
- ubuntu
- Python
- Java
- Software Engineering
- history
- program
- Today
- Total
variable argument list, va_list, 가변형 인자 본문
gcc 3.4.5 (mingw), Windows XP
가변 길이의 매개변수 리스트(Variable-length Argument Lists)
이 절에서는 printf의 최소 버전(Version)인 minprintf를 소개한다. 이 함수는 가변 길이 매개 변수를 포터블(portable : 다른 컴퓨터 상에도 쉽게 이식 가능한)하게 처리할 수 있는 함수이다.
우리들은 주로 매개변수의 처리만에 관심을 가지고 있으므로, minprintf 함수는 출력형식 지정 문자열과 매개변수를 처리하기 위해서 printf를 호출하여 사용할 것이다. printf에 대한 선언은 다음과 같이 한다.
int printf(char *fmt, …)
여기서 …의 의미는 매개변수의 형과 개수가 변할 수 있음을 뜻한다. …은 매개변수 리스트의 끝에만 나타날 수 있다. minprintf는 다음과 같이 정의한다.
void minprintf(char *fmt, …)
표준헤더 <stdarg.h>는 매개변수 리스트를 어떤 식으로 처리하느냐가 정의된 매크로를 포함하고 있다. 이 헤더는 기종마다 다르게 만들어지지만 헤더를 사용하는 방법은 기종에 상관없이 동일하다.
va_list 형(type)은 매개변수를 차례로 가리키는 포인터 변수를 정의할 때 사용된다. minprintf에서 이 변수는 매개변수 포인터(argument pointer)의 첫 글자만을 따와서 ap라 명명했다. 매크로 va_list는 첫번째 이름없는 매개변수를 지시하게 끔 ap의 초기값을 설정한다. ap가 사용되기 전에 va_start를 한번 호출해야 한다. 매개변수 중에는 이름을 가진 것이 적어도 하나 있어야 한다. 이름 붙여진 매개 변수중 마지막 것은 va_start를 시작하기 위해 사용되어진다.
va_arg를 호출하면 하나의 매개변수를 리턴하고 ap가 다음 매개변수를 가리키게 한다. va_arg는 어떤 형이 리턴될 것이며, ap가 얼마나 전진해야 될지를 결정하기 위해 형 이름을 참고한다. 마지막으로, va_end는 청소 작업을 한다. 이것은 함수가 리턴되기 전에 호출되어야 한다.
이런 동작을 하는 minprintf 함수는 다음과 같다.
// cf : vprintf, vfprintf, vsprintf, vsnprintf
#include <stdarg.h>
// minprintf : minimal printf with variable argument list
void minprintf(char* fmt, ...)
{
va_list ap; // points to each unnamed arg in turn
char *p, *sval;
int ival;
double dval;
va_start(ap, fmt); // make ap point to 1st unnamed arg
for ( p = fmt; *p; p++ )
{
if ( *p != '%' )
{
putchar(*p);
continue;
}
switch ( *++p )
{
case 'd':
ival = va_arg(ap, int);
printf("%d", ival);
break;
case 'f':
dval = va_arg(ap, double);
printf("%f", dval);
break;
case 's':
for ( sval = va_arg(ap, char*); *sval; sval++ )
putchar(*sval);
break;
default:
putchar(*p);
break;
}
}
va_end(ap); // clean up when done
}