2010년 1월 29일 금요일

가변인수 : stdarg.h

1. 생략기호를 사용하는 함수 원형을 제공한다. ( ...을 사용한다는 말이다.)
2. 함수 정의에서 va_list형 변수를 만든다.
3. 인수 리스트에 대한 변수를 초기화하기 위해서 매크로를 사용한다.
4. 인수 리스트에 접근하는데 매크로를 이용한다.
5. 지우기 위해 매크로를 이용한다.

void f1(int n, ...);    // 유효
int f2(int n, const char *s, ...);   //유효
char f3(char 1, ..., char c2);  //무효
double f3();   // 무효

첫번째 선언의 맨오른쪽 인수인 "..."은 표준 명칭으로 parmN 이라고 한다.
parmN은 첫째는 n이 되고, 두번째는 s가 된다. 다음과 같이 사용될 수 있다.

f1(2, 200, 400);          // 2개의 추가 인수
f(4, 13, 117, 18, 23);  // 4개의 추가 인수

인수의 맨앞 숫자는 뒤 따라올 인수들의 수를 나타낸다.

double sum(int lim,...)
{
   va_list ap;               // 생략된 인수를 담을 객체를 선언한다.
   ...
}

stdargs.h에 선언된 va_start()매크로를 사용해서 선언된 va_list변수에 인수 리스트를 복사한다.

va_start(ap, lim);   // 인수 리스트에 대한 ap를 초기화

다음으로 넘겨준 인수를 가져와야 할 것이다. 그래야 지지고 볶고 할것 아닌가..
va_arg()를 사용하여 데이터에 엑세스 한다.

int toc;
double tic;
tic = va_arg(ap, double);
toc = va_arg(ap, int)

인수의 형식은 va_arg()의 두번째 인수인 규격에 정확히 맞아야 한다.

마지막으로 리스트 선언된 객체를 지운다

va_end(ap);    // 해제

인수를 해제하기전 데이터를 백업 받아야 한다면 다음 매크로를 사용하면된다.

//arg_copy();
va_list ap;
va_list apcopy;
double
double tic;
int toc;
...
va_start(ap, lim);             // 인수 리스트로 ap를 초기화한다.
va_copy(apcopy, ap);        // ap를 ap copy에 복사한다.
tic = va_arg(a, double);    // 첫 번째 인수를 검색한다.
toc = va_arg(ap, int);       // 두 번째 인수를 검색한다.

  1 #include <stdio.h>
  2 #include <stdarg.h>
  3 double sum(int, ...);
  4
  5 int main(void)
  6 {
  7    double s, t;
  8    s = sum(3,1.1,2.2,3.3);
  9    t = sum(6,1.1,2.1,3.1,4.1,5.1,6.1);
 10    printf("%g %g\n", s, t);
 11    return 0;
 12 }
 13
 14 double sum(int lim, ...)
 15 {
 16    va_list ap;
 17    double tot = 0;
 18    int i;
 19    va_start(ap, lim);
 20    for(i=0;i<lim;i++)
 21       tot += va_arg(ap, double);
 22    va_end(ap);
 23    return tot;
 24 }

va_arg는 별도의 카운터를 하지 않아도 다음 값을 가져오는 걸로 확인되었다.

댓글 없음:

댓글 쓰기