티스토리 뷰
C언어 - 가변 인자 함수, 동적 인자 함수(Variable Argument Functions)
Unikys 2007. 12. 8. 11:39C언어 중 한 가지 재밌는 기능이 바로 이 가변 인자 함수이다.
처음에는 이러한 것에 대해서 전혀 의문을 품고 있지 않다가 나중에 한참 C를 배우다가
'어? 이거 어떻게 구현했지?'
라는 의문을 품게 되는 재미있는 요소이다.
C언어를 처음으로 하게 되면 배우게 되는 구문..
{
printf("Hello World!");
}
뭐, 여기서는 그렇게 의문을 가지진 않을 것이다. 헬로월드는 뻔한 내용이기도 하니깐. 그런데 이것을 이렇게 바꿀 수도 있다..
{
printf("%s" , "Hello World!");
}
그래..여기까진 좋다 이거지...그런데 printf를 아무 생각없이 이렇게 쓰다가 문득 앞에 있는 format string("%s")이 %d, %c, %s 등등 의 무한하게 설정이 가능하고 그 수에 따라 뒤에 따라오는 인자의 수가 매번 달라지는 것을 깨닫게 되는 순간 뒤통수를 딱 맞는 기분이 들 것이다.
어떻게 구현한 것일까?
처음엔 이렇게 생각했다..인자를 한 255개까지 제한하고 있지 않을까..-_-
뭐...그냥 이렇게 생각하고 보니 인자가 int만 들어오는게 아니잖아! char, float, double등등 기본형의 조합을 255가지 하려면...header파일의 용량이 몇 메가는 될듯 하다...
그럼 도대체 아무 생각없이 막 써왔던 이런 printf, scanf 등은 어떻게 구현했을까?
툴을 이용해서 이들 인자를 살펴보게 되면
이라고 되어있다..도대체 '...'이 뭐길래?
이 '...'은 바로 '가변 인자 함수(Variable argument function)'을 나타내는 것이다.
그럼 어떻게 쓰느냐? 간단하게 살펴보자...
선언은 위와 같이 ...으로 하고..예제 소스를 보자..(CodeProject 참고)
{
va_list list;
//initialize the va_list i.e char*
// variable 'list' by the address
// of first unknown variable argument
// by a call of va_start() macro
va_start(list,x);
int result=0;
for(;;)
{ // in loop, retreive each argument
// Second argument to va_arg is datatype
// of expected argument
int p=va_arg(list,int);
if(p==0)
break;
result+=p;
}
va_end(list); // cleanup , set 'lsit' to NULL
return result;
}
딱 봐도 간단하다...
변수 va_list가 있고
사용하는 함수들은 va_start , va_arg, va_end가 있다..
va_list는 stdio.h에 정의 되어있고..
으로 정의 되어있다. va_start는 매크로로 설정되어서 아래와 같다..
이거의 의미는 va_list를 인자로 받고, &v로 v의 주소를 구해서 _INTSIZEOF(v)를 더함으로써 인자로 넘어온 v의 다음인자의 주소값을 가져오는 것이다. _INTSIZEOF(v)는 주소값만큼 나누어 떨어지게 하는 것으로, 아래와 같이 정의되어있다.
주소는 4바이트씩 끊어서 계산하므로(32bit OS 상에서) 그것을 논리 연산자를 통해서 나누어 떨어지게 하는 것이다.
va_arg는 ap에 t의 타입 크기만큼 ap를 옮기고, 그 결과에 다시 t의 크기만큼 뺀다. 이 말은 ap를 다음 인자의 포인터로 넘기고 다시 앞으로와서 그 값을 리턴하는 것이다. 타입의 종류를 잘 설정해야겠다.
그리고 va_end는 ap를 초기화하게 된다.
이용의 예는 위에 예제소스만 가지고도 충분히 구현이 가능할 것이다.그럼 아래는 MSDN에서 제시하고 있는 requirements이다..
Routine | Required header | Optional headers | Compatibility |
---|---|---|---|
va_arg |
<stdio.h> and <stdarg.h> |
<varargs.h>* |
ANSI, Windows 95, Windows 98, Windows 98 Second Edition, Windows Millennium Edition, Windows Millennium Edition, Windows NT 4.0, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 |
va_end |
<stdio.h> and <stdarg.h> |
<varargs.h>* |
ANSI, Windows 95, Windows 98, Windows 98 Second Edition, Windows Millennium Edition, Windows Millennium Edition, Windows NT 4.0, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 |
va_start |
<stdio.h> and <stdarg.h> |
<varargs.h>* |
ANSI, Windows 95, Windows 98, Windows 98 Second Edition, Windows Millennium Edition, Windows Millennium Edition, Windows NT 4.0, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 |
http://www.codeproject.com/KB/cpp/argfunctions.aspx?df=100&forumid=15556&exp=0&select=503481
위키피디아 참고할만한 내용..다른 언어들도 많이 나와있다!
http://en.wikipedia.org/wiki/Varargs
- Total
- Today
- Yesterday
- Android
- 샷
- K100D
- HTML5
- 자바스크립트
- GX-10
- 사진
- 삼식이
- 안드로이드
- google app engine
- Writing
- gae
- gre
- Javascript
- php
- 뽐뿌
- ny-school
- 안드로이드 앱 개발 기초
- c++
- 강좌
- lecture
- mini project
- 팁
- HTML5 튜토리얼
- 속깊은 자바스크립트 강좌
- java
- Python
- TIP
- 서울
- 탐론 17-50
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
29 | 30 | 31 |