C - 가변 인자 함수

업데이트:

가변 인자 함수

정해지지 않은 수의 매개변수(가변인자)를 허용하는 함수

  • 반드시 최소 한 개의 정해진 자료형의 매개변수가 필요함

언제 사용할까

  • 메모리에 블록을 크게 잡아 두고 거기에 여러 가지 자료형을 저장하는 함수
    • printf(), scanf()
#include <stdarg.h>
int add_ints(const size_t count, ...) {
  va_list ap;
  int sum;
  size_t i;
  
  sum = 0;
  va_start(ap, count);
  {
    for(i=0; i<count; i++){
      sum += va_arg(ap, int)
    }
  }
  va_end(ap);
  
  return sum;
}

va_list

  • 가변 인자 목록
  • va_start(), va_arg(), va_end() 매크로 함수를 사용할 때 필요한 정보가 포함
  • 명시되지 않은 자료형

va_start()

  • va_start(<가변인자목록>, <가변인자 시작하기 직전 매개변수>)
  • 매크로 함수
  • 가변 인자에 접근하기 전 반드시 호출해야 함
  • va_list에 필요한 초기화를 수행
    • 가변 인자가 스택 메모리의 어디서부터 시작하는지 찾아냄
    • 그래서 가변인자 시작 직전 매개변수가 필요
va_start(ap, count);
// 전처리기가 아래로 대체한다
ap.data = (char*)&count + sizeof(count); // 가변인자 시작 직전 매개변수로 첫 번째 가변인자 주소를 찾음

va_end()

  • 매크로 함수
  • 가변 인자들의 접근이 끝난 뒤 반드시 호출해야 함
  • 가변 인자 목록을 정리함
    • 더 이상 가변 인자를 사용할수 없도록 값을 수정함

va_arg()

  • va_arg(<가변인자목록>, <얻어올 가변 인자의 자료형>)
  • 매크로 함수
  • 다음 가변 인자를 가져옴
  • 표준상의 문제로 가변 인자 목록의 기본 자료형 인자들은 다음과 같이 승격(promotion) 됨
    • 모든 정수형은 int
    • 모든 부동소수점은 double
    • 따라서 두 번째 매개변수에는 intdouble을 써야 함 (char사용 시 문제 있을수도)

매크로 함수

  • 함수처럼 보이나 함수가 아님
    • 스택 프레임 생성 X
    • 매개변수 전달 X
    • 함수 주소로 점프 X
    • 전처리기가 매크로 함수의 구현 코드로 대체시켜 줌
val = va_arg(ap, int);
// 아래로 대체한다
val = *(int*)ap.data;
((int*)ap.data)++;

첫 번째 매개변수로 가변인자 못 쓰는 이유

  1. 가변인자가 몇 개인지 함수는 모름 단, 스택 메모리의 어느 위치부터 가변 인자가 시작되는지 앎
  2. 가변 인자의 자료형을 가변 인자 함수는 모름
    • 자료형은 실행중에 결정됨.
    • 그래서 스택의 어떤 위치를 어떤 형으로 읽어야할 지 모름
    • 따라서 정해진 자료형으로 넘겨주는 매개 변수로부터 알아내야 함

태그: ,

카테고리:

업데이트:

댓글남기기