가변인자
가변인자란?
* 자바나 C# 같은 객체지향 언어를 사용했다면 함수 오버로딩을 쉽게 접했을 것이다.
C에서 비슷한 효과를 내기 위해 즉, 매개변수가 몇 개 들어올지 모를 때 사용한다.
(함수 오버로딩이랑 비슷하지만 차이점은 분명히 있다.)
* 구조체나 포인터, 정수형 변수, 실수형 변수 전부 들어간다.
함수의 선언
* count 개수만큼 들어오는 변수를 더하는 함수를 만들어보겠다.
* #include <stdarg.h>를 꼭 해야 한다.
#include <stdarg.h>
int add_all_num(int count, ...) {
va_list ap;
va_start(ap, count);
{
// 코드
va_arg(ap, int);
}
va_end(ap);
}
* 가변인자 함수의 전체적인 흐름이다.
* va_start와 va_end 사이에 괄호는 가독성을 위해 넣었다. (없어도 됨)
* 일단, 고정된 매개변수 1개가 꼭 있어야 한다는 것만 숙지하자.
이상한 녀석들 (천천히 보세요)
<va_list ap;>
* 가변인자 목록을 참조하는 포인터이다.
* 사실 char*이다. (어떤 크기의 매개변수가 들어올지 모르니 젤 작은 char포인터를 사용한다.)
<va_start(ap, a1);>
* 가변인자의 시작점을 찾는다.
* 이제부터 ap 포인터에 가변인자 목록 주소가 넣어져 있을 것이다.
* (가변인자포인터, 가변인자가 시작되기 직전 매개변수)가 매개변수로 들어간다.
(고정된 매개변수가 여러 개일 수 있잖아. 꼭 맨 마지막 고정된 매개변수를 넣어야 해)
<va_arg(ap, 자료형);>
* 가변인자에 무슨 자료형이 올지 모르니 이때 결정함. (자료형을 잘못 결정하면 그냥 망하는 거)
* 자료형을 잘못 결정하면 걍 망함.
자료형 크기만큼 포인터를 옮기니까 크기까지 잘 못 예상하면 뒤에 변수들까지 망함.
* 모든 정수형은 int로 승격
모든 실수형은 double로 승격된다. (printf나 scanf 같은 함수에서 %f만 있는 이유. 짜피 다 double이라구)
<va_end(ap);>
* 가변인자를 다 쓰고 호출한다. 더 이상 포인터를 쓸 수 없도록 값을 수정한다.
* 호출을 안 했을 때의 상황은 정의되지 않음. (케바케)
예제
* count값만큼 들어오는 가변인자 모두 더하는 함수
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdarg.h>
int add_all_num(int count, ...) {
int sum = 0;
va_list ap;
va_start(ap, count);
{
for (int i = 0; i < count; i++) {
sum += va_arg(ap, int);
}
}
va_end(ap);
return sum;
}
int main()
{
printf("%d\n", add_all_num(2, 10, 20));
printf("%d\n", add_all_num(3, 10, 20, 30));
printf("%d\n", add_all_num(4, 10, 20, 30, 40));
return 0;
}
귀여운 그림은 낡은 창고님이 그리셨습니다.
'C' 카테고리의 다른 글
memset 함수 (0) | 2020.12.26 |
---|---|
malloc 함수, calloc 함수 (0) | 2020.12.24 |
공용체 Union (0) | 2020.12.23 |
Bit Flags (0) | 2020.12.23 |
Byte Padding (0) | 2020.12.23 |