고흐의 연구실/C언어와 C++

[C언어] 함수에서 가변인자 사용하기

전고흐 2020. 8. 30. 01:38
728x90

 

ㅇ 함수에서 가변인자를 정의할 때는 고정 매개변수가 한 개 이상 있어야 한다.

ㅇ 가변 매개변수는 ...을 붙여 매개변수의 개수가 정해지지 않았다는 표시를 해준다.

    (단, ...뒤에 다른 매개변수 지정 불가)

반환값자료형 함수이름(자료형 고정매개변수, ...)
{
}
#include <stdio.h>
#include <stdarg.h> // va_list, va_start, va_arg, va_end가 정의된 헤더 파일

void printNumbers(int args, ...) // 가변 인자의 개수를 받음, ...로 가변 인자 설정
{
    va_list ap; // 가변 인자 목록 포인터
    va_start(ap, args); // 가변 인자 목록 포인터 설정
    for (int i = 0; i < args; i++) // 가변 인자 개수만큼 반복 
    {
        int num = va_arg(ap, int); // int 크기만큼 가변 인자 목록 포인터에서 값을 가져옴
                                          // ap를 int 크기만큼 순방향으로 이동
        printf("%d ", num); // 가변 인자 값 출력 }
        va_end(ap); // 가변 인자 목록 포인터를 NULL로 초기화
        printf("\n"); // 줄바꿈
    }

int main()
{
    printNumbers(1, 10); // 인수 개수 1개
    printNumbers(2, 10, 20); // 인수 개수 2개
    printNumbers(3, 10, 20, 30); // 인수 개수 3개
    printNumbers(4, 10, 20, 30, 40); // 인수 개수 4개
    return 0; 
}

 

ㅇ ...로 들어온 가변 인자를 사용하려면 stdarg.h 헤더파일을 사용해야 한다.

ㅇ stdarg.h 에 정의된 가변 인자 처리 매크로

   - va_list : 가변 인자 목록. 가변 인자의 메모리 주소를 저장하는 포인터

   - va_start : 가변 인자를 가져올 수 있도록 포인터 설정

   - va_arg : 가변 인자 포인터에서 특정 자료형 크기만큼 값을 가져옴

   - va_end : 가변 인자 처리가 끝났을 때 포인터를 NULL로 초기화

 

 

ㅇ 가변형이 다른경우!!!!! : switch와 가변인자를 함께 사용하면 됨.

ㅇ 가변 인자를 처리할 때의 각 자료형의 약칭

   - 정수(int) : i

   - 실수(double) : d

   - 문자(char) : c

   - 문자열(char *) : s

#include <stdio.h>
#include <stdarg.h> // va_list, va_start, va_arg, va_end가 정의된 헤더 파일

void printValues(char *types, ...) // 가변 인자의 자료형을 받음, ...로 가변 인자 설정
{
    va_list ap; // 가변 인자 목록
    int i = 0;
    va_start(ap, types); // types 문자열에서 문자 개수를 구해서 가변 인자 포인터 설정
    while (types[i] != '\0') // 가변 인자 자료형이 없을 때까지 반복
    {
        switch (types[i]) // 가변 인자 자료형으로 분기
        {
            case 'i': // int형일 때
                printf("%d ", va_arg(ap, int)); // int 크기만큼 값을 가져옴
                                                     // ap를 int 크기만큼 순방향으로 이동
                break;
            case 'd': // double형일 때
                printf("%f ", va_arg(ap, double)); // double 크기만큼 값을 가져옴
                                                          // ap를 double 크기만큼 순방향으로 이동
                break;
            case 'c': // char형 문자일 때
                printf("%c ", va_arg(ap, char)); // char 크기만큼 값을 가져옴
                                                       // ap를 char 크기만큼 순방향으로 이동
                break;
            case 's': // char *형 문자열일 때
                printf("%s ", va_arg(ap, char *)); // char * 크기만큼 값을 가져옴
                                                         // ap를 char * 크기만큼 순방향으로 이동
                break;
            default:
                break;
        }
        i++;
    }
    va_end(ap); // 가변 인자 포인터를 NULL로 초기화
    printf("\n"); // 줄바꿈
}

int main()
{
    printValues("i", 10); // 정수
    printValues("ci", 'a', 10); // 문자, 정수
    printValues("dci", 1.234567, 'a', 10); // 실수, 문자, 정수
    printValues("sicd", "Hello, world!", 10, 'a', 1.234567); // 문자열, 정수, 문자, 실수
    return 0;
}
실행결과
10
a 10
1.234567 a 10
Hello, world! 10 a 1.234567

 

출처 : 코딩도장(dojang.io/mod/page/view.php?id=581)

728x90