본문 바로가기

C언어

Chapter 11. 가변 인자

Chapter 11.가변 인자

마을 풀어보면 "인자가 변한다"가 될것이다.

정학한 뜻은 인자의 개수가유동적으로 변한다는 것이다.

따라서, 지금까지 인자의 개수를 한정지어 작성되었던 프로그램(인자의 개수에 따라 처리 함수가 여러개 존재하는)을 훨씬 간단하게 작성할 수 있다.

가변 인자 사용 단계

1. 함수의 원형 정의

int function(int, ...);

인자 리스트에"..."을 사용한다.

2. 함수의 본체 작성

int function(intcount, ...)

{

}

함수본체에서는 원형에서 생략했던 변수명을사용해야 한다는 것을 제외하고는원형과 크게 다르지 않다.

3. 헤더 파일 포함

#include <stdarg.h>

위처럼 헤더 파일을 포함해야 가변 인자를 사용할 수 있다.

가변 인자를 위한 매크로

가변 인자를 위한 매크로는 다음의 3가지만 알면 충분하다.

1.void va_start(va_list list,last);

va_start() 함수는list를 초기화 한다. 포인터를 맨 처음으로 돌린다는 의미이다.

만약이 함수가 없다면 va_arg()를 이용하여 인자들을 다 사용했을 때 처음으로 되돌릴 방법이 없다.

  • va_list list

    typedefvoid *va_list

    void형 포인터.void형 포인터를 아무것도 지정할 수 없는 포인터로 오인하지 말자.
    void형 포인터로 선언되어 있기 때문에어떤 형(type)도 사용 할 수 있다.
  • last
    함수에 전달되는 마지막 고정 인자

2.type va_arg(va_list list, type);

고정 인자를 제외한 나머지 인자들을 얻기 위해 사용.

보통 for()문을 이요하여 처리.

사용할 때마다 list의 포인터는 하나씩 증가하기 때문에 인자로 넘어온 값들을 읽어 들일 수 있게 된다.

type은 인자로 넘어오는형(type)을 지정.

3.void va_end(va_list list);

가변 인자의 사용을 끝낼 때 사용하며 보통은 사용하지 않는다.

가변 인자의 사용

11_1.c

#include <stdio.h>
#include <stdarg.h>

int add(int count, ...)
{
va_list list;
int sum = 0;
int i;

va_start(list, count);

for(i=0;i<count;i++)
sum += va_arg(list, int);

va_end(list);

return sum;
}

main()
{
int add(int, ...);
int sum;

sum = add(2, 284, 945);
printf("sum : %d\n", sum);

sum = add(5, 456, 74, 24, 826, 34);
printf("sum : %d\n", sum);
}

gcc -o 11_1 11_1.c

./11_1

sum : 1229
sum : 1414

count가 인자의 개수를 받아들여 for()문에서 이를 이용하고 있다.

정수형 인자들을 받아 들이기때문에va_arg()에서int를사용하고 있다.

주의 사항

va_start()를 사용하려면 적어도 하나 이상의 고정 인자가 있어야 한다.다음과 같은 형식은 에러가 난다.

int function(...);

가변 인자의 집합으로만 선언할 수 없다.

printf("%s", imsi);

printf()문을 보면 항상 맨 앞의 인자는 문자열을 전달하고 있음을 알 수 있으며 좋은 본보기다.

첫번째 인자를 이용하여뒤에 나오는 인자의 개수를 예측할 수 있는데, 첫번째 문자열 안에 있는 '%'기호가 이 예측을 가능하게 한다.

'C언어' 카테고리의 다른 글

Chapter 14. void형 포인터  (0) 2011.10.16
Chapter 10. 바로알자 getchar()  (0) 2011.10.16
Chapter 12. 될 것 같으면서 안 되는 코드  (0) 2011.10.16
Chapter 7. strcpy()의 비밀  (0) 2011.10.16
Chapter 8. 뒤죽박죽 포인터  (0) 2011.10.16