python에서는 함수의 가변인자를 *kwarg를 이용해서 만들 수 있다. C에서도 동일하게 함수의 가변인자를 줄 수 있다. 함수의 가변인자를 정의하는 것은 크게 두 가지 방법으로 나뉜다.
a. 가변 전달 인자 매크로 사용
b. 헤더 파일 stdarg.h 사용
1. 가변 전달인자 매크로 (C99)
1) 가변 전달인자 매크로: ...와 __VA_ARGS__
- 매크로 정의 전달인자 리스트의 마지막 전달인자로 생략기호인 "..."를 사용할 수 있음
- 생략기호(생략기호: ...)가 사용된 경우, 대체 리스트에서 그것을 대체하는 것을 지정하기 위해 미리 정의된 매크로 __VA_ARGS__를 사용할 수 있음
2) Appendix 1 참조
2. 헤더 파일 stdarg.h 사용
stdarg.h와 가변전달인자 매크로 비교
stdarg.h는 가변전달인자 매크로에 비해 사용하기는 더 까다롭지만, 가변 전달인자 함수는 적용 범위가 훨씬 더 넓다.
stdarg.h를 이용한 가변인자 정의 절차
1) 생략 기호를 사용하여 함수 프로토타입을 제공
2) 함수 정의 안에 va_list형 변수를 생성
3) 그 변수를 전달인자 리스트로 초기화하는 매크로를 사용함
4) 전달인자 리스트에 접근하는 매크로를 사용
5) 흔적을 깨끗이 지우는 매크로를 사용
1. 가변인자 함수 정의
함수의 정의
int func(<명시적인 매개변수>, int parmN, ...)
//example
int f2(const char *s, int k, ...)
- 예시
double sum(int lim, ...){
va_list ap; // 전달인자를 담을 매개 변수
}
- 변수 lim : parmN 매개 변수
-- 가변 전달인자 리스트에 있는 전달인자의 개수를 나타냄
NOTE 1: va_list형
- 매개 변수 리스트의 생략 기호 부분에 해당하는 매개 변수를 담는데 사용할 하나의 데이터 객체를 나타냄
2) 두번째 단계
- stdarg.h에 정의된 va_start() 매크로를 사용하여, 전달인자 리스트를 va_list 변수에 복사함
- va_start() 매크로는 두 개의 전달인자를 사용함: va_list, parmN
3) 세번재 단계
- 매크로 va_arg()를 사용하여 전달인자 리스트의 내용에 접근
- va_arg()의 두 개의 전달인자: va_list형 변수, 데이터형 이름
-- NOTE: 반드시 데이터형 전달인자는 실제 지정한 것과 일치해야 함. 데이터형 자동변환은 이루어지지 않음
- va_arg() 함수를 호출 할 때마다, 그 다음 항목을 리턴함
NOTE: va_arg는 접근을 한 후, 이전 전달인자로 돌아갈 수 없기 때문에, va_copy()라는 이용해서, 다시 접근을 해야 한다.
va_list ap;
va_list apcopy;
double tic;
int toc;
...
va_start(ap, lim); // ap를 전달인자 리스트로 초기화함
va_copy(apcopy, ap); // ap를 apcopy에 복사함
tic = va_arg(ap, double); // 첫 번째 전달인자를 얻음
toc = va_arg(ap, int); // 두 번째 전달인자를 얻음
4) 마지막 단계
va_end()를 사용하여 전달인자를 담기 위해 사용한 동적으로 할당한 메모리를 해제함
Appendix 1) __VA_ARGS__를 사용한 가변 전달인자의 예시
#include <stdio.h>
#include <math.h>
#define PR(X, ...) printf("Message: #X": __VA_ARGS__)
int main(void){
double x = 48;
double y ;
y = sqrt(x);
PR(1, "x = %g\n", x);
PR(2, "x = %2.f, y = %4.f\n", x, y);
}
1. 첫번째 매크로: PR(1, "x = %g\n", x)
다음과 같이 확장됨
printf("Message 1 : x = %g\n", x)
Appendix 2) stdarg.h를 사용한 가변 전달인자의 예시
#include <stdio.h>
#include <stdarg.h>
double sum(int, ...);
int main(void){
double s,t;
t = sum(3, 1.1, 2.5, 13.3);
s = sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1);
printf("sum(3, 1.1, 2.5, 13.3): %f\n", t);
printf("sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1): %f\n", s);
}
double sum(int lim, ...){
va_list ap; // 전달인자를 담을 객체를 선언
double tot = 0;
int i;
va_start(ap, lim); // ap를 담을 전달인자 리스트로 초기화함
for (int i = 0; i < lim; i ++){
tot += va_arg(ap, double) // 전달인자 리스트에 있는 각 항목에 접근함
}
va_end(ap); // 흔적을 깨끗이 지움
return tot;
}
Appendix 3) stdarg.h
- stdarg.h 헤더파일은 개수가 가변적인 전달인자를 가지는 함수를 정의하는 수단을 제공함
- 가변인자를 가지는 함수의 프로토타입은 하나의 매개변수와 뒤에 생략기호(...)가 붙어있는 매개변수 리스트를 가져야 함
가변 매개변수 리스트 매크로
해당 헤더 파일은 매개변수 리스트의 생략부분에 해당하는 매개변수들을 저장할 데이터 객체들을 나타내기 위해 va_list형을 선언한다.
프로토 타입 | 설명 |
void va_start(va_list ap, paramN) | 이 매크로는 va_arg()와 va_end()가 사용하기 전에 미리 ap를 초기화한다. parmN은 매개변수 리스트에 있는 이름이 지정된 마지막 매개변수를 나타내는 식별자이다. |
void va_copy(va_list dest, va_list src) | 이 매크로는 src의 현재 상태의 사본으로 dest를 초기화한다. |
type va_arg(va_list ap, type) | 이 매크로는 ap로 나타낸 매개변수 리스트에 들어 있는 다음 항목과 동일한 값과 데이터형을 가지는 수식으로 확장한다. type은 그 항목을 나타내는 데이터형이다. 각 호출은 ap에 엤는 다음 항목으로 진행한다. |
void va_end(va_list ap) | 이 매크로는 이 처리를 끝내고 va_start()가 다시 호출될 때까지 ap를 사용할 수 없는 상태로 만든다. |
'프로그래밍 언어 > C, C++의 기본적인 설명' 카테고리의 다른 글
[C 언어] 기억 부류, 연계, 수명, 한정자 (0) | 2022.04.10 |
---|---|
[C언어] C 언어 레퍼런스 및 학습 순서 정리 (1) | 2022.03.28 |
[C 언어] 명령행 전달인자 (argc, argv) (0) | 2022.03.25 |
[표준 ANSI C 라이브러리] complex.h (0) | 2022.03.24 |
[C/C++] 기본적인 파일 입출력 함수 (0) | 2022.03.07 |
댓글