가변 인자

Mr.뉴트리아·2020년 12월 4일
0

42Seoul 삽질노트

목록 보기
8/10

시작 하기 전...

보통 우리가 쓰는 함수들은 매개변수의 개수가 정해져있어, 지정한 개수와 다른 인자를 넣게되면 오류를 뿜어낸다. 그렇다면 하나에 의문이 든다. 우리가 평소에 자주쓰는 printf또한 함수인데, 이는 어떻게 각종 타입의 변수를, 개수에 상관없이 넣을 수 있는 것인가?

그 해답은 바로 가변 인자에 있다.

가변 인자(variable argument)란?

가변 인자는 이름 그대로, 변할 수 있는 인자란 뜻이다. 아래 코드를 보자.

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

void    PrintNumbers(int argc, ...)
{
    va_list ap;
    int     i;

    va_start(ap, argc);
    for (i = 0; i < argc; i++)
    {
        printf("%d ", va_arg(ap, int));
    }
    printf("\n");
    va_end(ap);
}

int main()
{
    
    PrintNumbers(1, 10);
    PrintNumbers(2, 10, 100);
    PrintNumbers(3, 10, 100, 1000);
    PrintNumbers(4, 10, 100, 1000, 10000);

    return 1;
}

가변 인자 매크로

va_start, va_arg, va_end얘네들에 대해 설명하기 전에 짚고 넘어갈 것은, 얘네들은 함수가 아닌 매크로라는 것이다. 비주얼 스튜디오에서는 함수를 노란색, 매크로를 보라색으로 표시하는데 이미지를 보면 가변 인자 관련된 녀석들은 모두 보라색인걸 알 수 있다.

va_start(ap,마지막 고정 인수)

이 명령은 가변 인수를 읽기 위한 준비를 하는데, ap가 첫번째 가변 인수를 가리키도록 초기화한다. 여기서 마지막 고정 인수라고 한 이유는 va_start내부에서 ap가 마지막 고정 인수 다음부터 가변 인수를 읽을 수 있기 때문이다.

va_arg(ap, 인수타입)

가변 인수를 실제로 읽어오는 매크로. va_start가 ap를 첫번째 가변 인수 번지로 맞춰주기 때문에, ap위치에 있는 값을 읽기만 하면 된다. 단, 인자로 들어온 값이 어떤 타입인지를 명시해주어야 이 매크로가 값을 제대로 읽을 수 있기에 두번째 인수로 읽고자 하는 값의 타입을 지정해준다. 변수의 타입을 매개로 전달할 수 있는 이유는 이가 매크로이기 때문이다. 내부적으로 sizeof연산자와 캐스트 연산자로 전달되기 때문에 타입명이 될 수 있다.

저렇게말이다.

va_end(ap)

가변인수를 읽는 것을 마치겠다는 명령. read후 close를 해주는 것과 비슷하다고 보면 된다.

가변 인수 함수의 조건

가변 인수를 활용한 함수를 제대로 작성하기 위해선 몇가지 조건이 필요하다.

1.가변 인수 함수는 반드시 하나 이상의 고정 인수를 가져야 한다. 왜냐면 가변 인수를 읽기 위한 포인터 ap를 초기화 하기 위해서 마지막 고정 인수의 번지를 알아야 하기 때문이다.

2.함수 내부에서 자신에게 전달된 가변 인수의 개수를 알 수 있도록 해야한다. 전달될 수 있는 인수의 개수에는 제한이 없으며 컴파일러는 함수가 호출될 때 인수의 개수를 점검하지 않는다. 그렇기때문에 호출하는 쪽에서 가변 인수의 개수를 알려주지 않으면 함수 내부에서는 인수의 개수를 알 수 있는 방법이 없다. 함수에서 인수의 갯수를 알 수 있도록 호출쪽에서 정보를 제공해야한다.

3.함수의 개수와 마찬가지로 가변 인수의 타입 또한 알 수 있어야한다. 2,3번을 대표적으로 보여주는것이 바로 printf인데, 예를 들어

printf("%s %d","HELLO WORLD!!!",15);

구문을 보면, 우리는 첫번째 인수에서 2개의 변수를 받고, 각각 문자열과 정수형 타입의 변수가 순서대로 들어간다는 정보를 함수에게 알려준 것이다.

참고한 자료 및 사이트

C언어 가변인자
코딩도장

profile
뉴트리아는 가시쥐과에 속하는 설치류의 일종이다. 오랫동안 뉴트리아과의 유일종으로 분류했지만, 현재는 가시쥐과에 포함시킨다. 늪너구리, 해리서 또는 코이푸라고도 한다. 뉴트리아는 스페인어로 수달을 의미하고, 출생지 남미에서는 이 종류를 코이푸라고 부른다.

0개의 댓글