가변 인자 함수는 역 어셈 코드를 생각해 보면 간단하다.

함수를 호출하게 되면 그 함수를 위한 ebp가 새로 생긴다.

함수의 인자는 ebp 위에 생기게 된다. (물론 stack이 아래로 주소가 작아 진다는 가정, 인텔...)

 

인자 3

인자 2

인자 1

ebp

 

와 같은 형태가 되므로 첫번째 인자1 로부터 인자 수와 형태를 알게 되면 ebp로 부터 주소를 알아 낼 수 있으므로 하나씩 뽑아서 사용하면 된다.

printf 함수의 원형을 보면

printf(const char *, ...); 이다.

const char *에서 뒤에 오는 인자의 수와 형태를 문자열로 부터 뽑아 낼 수 있으므로 간단하게 생각할 수 있다.

 

[code type=c]#include <stdarg.h> // 가변 인자 함수를 사용하기 위한 헤더 파일
#include <stdio.h>

int plus_func(int, ...); /* 가변 인자 함수 선언 방법. 뒤에 ... 임. 첫번째 인자는 가변이 안됨. 무조건 고정 인자가 와야 함. 즉 int plus_func(...)는 불가능 함. 첫번째 인자는 인자의 갯수와 데이타 형을 알려 줘야 함. */
int max_func(int, ...);

int main(void)
{
 int x = 10, y = 20;

 printf("%d\n", plus_func(2, 3, 2));
 printf("%d\n", plus_func(3, x, y, 3));
 printf("%d\n", max_func(3, x, y, 3));

 return 0;
}

int plus_func(int count, ...)
{
 int i;
 int sum = 0;
 va_list list; /* va_list는 가변 인자 함수 사용시 사용하는 매크로이다. */
 
 va_start(list, count); /* va_list로 정의한 변수 list를 첫번째 인자로 하고 뒤에 인자는 가변 인자 함수의 첫번째 인자를 받는 변수를 적어야 함. 여기서는 count로 받는다. 인자를 하나씩 빼오겠다는 표현이다. */
 for ( i = 0; i < count; i++ )
 {
  sum += va_arg(list, int);
 }
 va_end(list);

 return sum;
}

/**
 * 가변 인자 함수 사용하기
 * 가변 인자로 주어진 값 중에서 가장 큰 값을 넘겨 준다.
 */

int max_func(int count, ...)
{
 int i, num;
 int max = 0;
 va_list list;
 
 va_start(list, count);
 max = va_arg(list, int);
 for ( i = 0; i < count - 1; i++ )
 {
  num = va_arg(list, int); // va_arg(list, int)는 실행될때마다 값을 빼온다.

/*

  if ( max < va_arg(list, int) )

  {

      max = va_arg(list, int);

  }

   와 같이 하면 이상한 결과가 나온다.

*/
  if ( max < num )
  {
   max = num;
  }
 }
 va_end(list);

 return max;
}[/code]


 

실행결과

5

33

20

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.cipher.pe.kr/tt/cipher/rss/response/151

댓글+트랙백 ATOM :: http://www.cipher.pe.kr/tt/cipher/atom/response/151

트랙백 주소 :: http://www.cipher.pe.kr/tt/cipher/trackback/151

트랙백 RSS :: http://www.cipher.pe.kr/tt/cipher/rss/trackback/151

트랙백 ATOM :: http://www.cipher.pe.kr/tt/cipher/atom/trackback/151

댓글을 달아 주세요

댓글 RSS 주소 : http://www.cipher.pe.kr/tt/cipher/rss/comment/151
댓글 ATOM 주소 : http://www.cipher.pe.kr/tt/cipher/atom/comment/151
[로그인][오픈아이디란?]