[42서울] ft_printf : 가변인자

jabae·2022년 3월 30일
0

42Seoul

목록 보기
3/20

🤔 가변인자란?

c언어에서 printf와 같이 매개변수의 갯수가 정해지지 않는 함수가 있다. 이렇게 함수에 들어가는 인수의 갯수가 변하는 것을 가변인자(가변 인수, variable argument)라고 한다.

  • 헤더 : <stdarg.h>
  • 사용법 : 고정 매개변수(필수인자)가 한 개 이상 있어야 한다. 고정 매개변수 뒤에 ... 을 붙여 매개변수의 개수가 정해지지 않았다는 표시를 해준다.
    예를 들어, printf 함수의 경우,
    printf("My name is %s. Her name is %s. His name is %s\n", name1, name2, name3);
    " " 로 묶여진 첫번째 문자열 인자가 필수 인자가 되는 것이고, name1부터 name3가 가변인자이다. 일반적으로 필수 인자에서 가변인자를 몇 개 받았는지 명시하여 정지신호를 찾을 수 있게 해준다. printf에서는 서식지정자의 개수로 알 수 있다.

⚙️ 가변인자 처리 매크로

  • va_list : 가변인자 목록 포인터, 가변인자의 메모리 주소를 저장한다.
  • va_start : 가변인자를 가져올 수 있도록 포인터를 초기화한다. 쉽게 말해서, 가변인자를 가져올 수 있도록 가변인자 시작 주소를 포인터에 담는다.
  • va_arg : 가변인자포인터에서 특정 자료형 크기만큼 값을 가져온다.(*값을 가져온 뒤 자료형 크기만큼 포인터 이동)
  • va_end : 가변인자 처리가 끝났을 때, NULL로 포인터를 초기화 해준다.

코드 예시

#include <stdio.h>
#include <stdarg.h>    // 가변인자 매크로가 정의된 헤더 파일

void ft_printNumbers(int args, ...)    // ...로 가변 인자 설정
{
    va_list ap;            // 가변 인자 목록 포인터
    int i = 0;

    va_start(ap, args);    // 가변 인자 목록 포인터와 가변인자와 연결
    while (i < args)       // 가변 인자 개수만큼 반복
    {
        int number = va_arg(ap, int);    // int 크기만큼 값을 가져온 뒤,
                                         // ap를 int 크기만큼 이동
        printf("%d ", number);           // 가변 인자 값 출력
        i++;
    }
    va_end(ap);            // 가변 인자 목록 포인터를 NULL로 초기화
}

int main()
{
    ft_printNumbers(5, 10, 20, 30, 40, 50); // 필수인자로 가변인자의 개수를 받음

    return (0);
}

🛠 자료형이 다른 가변인자 처리

각 자료형에 맞게 분기해주면 된다.

  • 정수(int): 'i'
  • 실수(double): 'd'
  • 문자(char): 'c'
  • 문자열(char *): 's'

코드 예시

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

void ft_printMultiple(char *types, ...)    // 가변 인자의 자료형을 필수인자로 받음
{
    va_list ap;    // 가변 인자 목록 포인터
    int i = 0;

    va_start(ap, types);        // types 문자열에서 문자 개수를 구해서 가변 인자 포인터 설정
    while (types[i] != '\0')    // 가변 인자 자료형이 없을 때까지 반복
    {
		if (types[i] == 'i')    // 가변 인자 자료형으로 분기  
        {                          
            printf("%d ", va_arg(ap, int));         
		}
        else if (types[i] == 'd')
		{                   
            printf("%f ", va_arg(ap, double));   
		}
        else if (types[i] == 'c')   
		{           
            printf("%c ", va_arg(ap, int));  // GCC에서 char형 문자일 때 int를 사용해야 함! 
		}                                    
        else if (types[i] == 's') 
		{                  
            printf("%s ", va_arg(ap, char *));  
		}                                        
		else
			return ;
        i++;
    }
    va_end(ap);    // 가변 인자 포인터를 NULL로 초기화
}

int main()
{
    ft_printMultiple("sicd", "Hello!", 2022, 'a', 3.30);   // 필수인자로 가변인자의 개수와 자료형을 받음

    return (0);
}

👀 참고

피신을 준비할 때 참 많이 보면서 공부했던 사이트인데, 역시 없는 게 없었다...!👍

c언어 코딩도장 - 66.1 가변인자 함수 만들기
c언어 코딩도장 - 66.2 자료형이 다른 가변 인자 함수 만들기

profile
it's me!:)

0개의 댓글