Developer

27.(C언어) 함수(3) 본문

Programming Language/C

27.(C언어) 함수(3)

DPhater 2020. 8. 1. 22:20

함수 포인터

함수의 이름도 포인터이므로 함수도 메모리 주소를 가지고 있다. 따라서 함수 포인터를 사용해 함수 자체를 배열에 넣거나, 매개변수로 넘겨줄 수 있다.

함수 포인터는 다음과 같이 선언할 수 있다.

리턴자료형 (*함수포인터이름)(매개변수자료형,매개변수자료형..);

위와 같이 선언한 함수 포인터는 리턴자료형이 같고, 매개변수자료형과, 갯수가 같은 함수를 가리킬 수 있다.

 

#include<stdio.h>

int add(int a,int b) {
	return a + b;
}
int sub(int a, int b) {
	return a - b;
}

int main() {
	int fnum, a, b;
	int (*fp)(int, int)=NULL;
	scanf("%d %d %d", &fnum, &a, &b);
	switch (fnum) {
	case 1:
		fp = add;
		break;
	case 2:
		fp = sub;
		break;
	default:
		break;
	}

	printf("%d\n", fp(a, b));
	return 0;
}

코드1 실행 결과(1)
코드1 실행 결과(2)

반환타입이 int형이고 매개변수가 int두개인 함수 포인터 fp를 선언하였다.

입력으로 fnum에 1을 받으면 함수포인터는 add를 가리키고, 2를 받으면 sub를 가리킨다. 함수 포인터를 사용하면 코드1과 같이 상황에 따라 함수를 바꾸어 사용할 수 있다.

하지만 함수의 종류가 너무 많을 경우 하나하나 switch문을 작성하는 것은 매우 귀찮은 일이다. 함수 포인터 배열을 사용하면 더 쉽게 함수를 사용할 수 있다.

#include<stdio.h>

int add(int a,int b) {
	return a + b;
}
int sub(int a, int b) {
	return a - b;
}

int main() {
	int fnum, a, b;
	int (*fp[2])(int, int)={add,sub};
	scanf("%d %d %d", &fnum, &a, &b);
	printf("%d\n", fp[fnum](a, b));
	return 0;
}

코드2 실행 결과(1)
코드2 실행 결과(2)

코드2에서는 함수 포인터 배열을 선언해 초기화해주었지만. 요소별로 따로 함수를 넣어줄 수도 있다.

가변 인자

지금까지는 매개변수의 개수가 고정된 함수만 사용하였다. 가변 인자는 인자의 개수가 변하는 것을 말한다. 가변 인자를 정의할 때는 고정된 매개 변수가 하나 이상 있어야 한다. 그런 후 고정된 매개변수 뒤에 ... 을 작성해 가변인자를 받는다는 표시를 해준다. 가변 인자를 사용하려면 stdarg.h헤더를 포함해 줘야한다. stdarg.h에는 가변 인자를 처리하기 위한 매크로가 정의되어 있다.

va_list : 가변 인자 주소를 저장하는 포인터

va_start : va_list로 선언한 포인터가 첫 번째 가변인수를 기리키도록 초기화

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

va_end : 다 사용한 뒤 포인터를 NULL로 초기화 시켜줌

#include<stdio.h>
#include<stdarg.h>
void f(int num, ...) {  //첫 번째 인자 하나만 num으로 받고 나머지는 ...에
	va_list ap;          //가변인자 포인터 ap선언
	va_start(ap, num);    //ap가 가변인자 시작 주소를 가리키도록 초기화, 고정인자 중 마지막 인자를 넣어준다.
	int i;
	for (i = 0; i < num; i++) {
		printf("%d ", va_arg(ap, int));      //ap에서 int형만큼 자료를 가져온뒤 포인터 이동
	}
	printf("\n");
    va_end(ap);
}
int main() {
	f(3, 1, 2, 3);
	f(2, 5, 6);
	f(5, 6, 53, 23, 12, 33);
	return 0;
}

코드3 실행 결과

num은 고정 매개변수로 가변 인자의 개수를 받는 변수로 사용 하였다.

가변인자 포인터 ap를 선언해 va_start(ap,num);으로 ap가 가변 인자 시작 수로를 가리키도록 해주었다.

va_start의 사용은 va_start(가변인자 포인터, 마지막 고정 매개변수); 와 같이 사용한다.

va_arg(ap,int)는 현재 ap에서 int형 만큼 값을 읽어어고, 포인터도 int형만큼 증가시키는 것이다. 참고로 GCC에서는 va_arg를 가변인자의 자료형이 int형 보다 작다면(char,short) int로 flaot이라면 double로 지정해 주어야한다.

visual studio에서는 그냥 맞는 자료형을 사용하면 된다.

'Programming Language > C' 카테고리의 다른 글

28.(C언어) 파일 입출력  (0) 2020.08.01
26.(C언어) 함수(2)  (0) 2020.08.01
25.(C언어) 함수(1)  (0) 2020.08.01
24.(C언어) 지역변수와 전역변수  (0) 2020.08.01
23.(C언어) 공용체, 열거형  (0) 2020.08.01
Comments