63.2 void 포인터 매개변수 사용하기
void 포인터 매개변수를 사용하면 자료형 변환을 하지 않아도 모든 자료형을 함수에 넣을 수 있습니다. 이번에는 char, int, float형을 매개변수로 받아서 값을 서로 바꿔보겠습니다.
parameter_void_pointer.c
#include <stdio.h> enum TYPE { TYPE_CHAR, TYPE_INT, TYPE_FLOAT }; void swapValue(void *ptr1, void *ptr2, enum TYPE t) // 반환값 없음, void 포인터 매개변수 두 개와 { // 변수의 자료형을 알려줄 열거형을 받음 switch (t) { case TYPE_CHAR: // 문자면 char *로 변환한 뒤 역참조하여 값을 서로 바꿈 { char temp; temp = *(char *)ptr1; *(char *)ptr1 = *(char *)ptr2; *(char *)ptr2 = temp; break; } case TYPE_INT: // 정수면 int *로 변환한 뒤 역참조하여 값을 서로 바꿈 { int temp; temp = *(int *)ptr1; *(int *)ptr1 = *(int *)ptr2; *(int *)ptr2 = temp; break; } case TYPE_FLOAT: // 실수면 float *로 변환한 뒤 역참조하여 값을 서로 바꿈 { float temp; temp = *(float *)ptr1; *(float *)ptr1 = *(float *)ptr2; *(float *)ptr2 = temp; break; } } } int main() { char c1 = 'a'; char c2 = 'b'; swapValue(&c1, &c2, TYPE_CHAR); // 변수의 메모리 주소와 TYPE_CHAR를 넣음 printf("%c %c\n", c1, c2); // b a: swapValue에 의해서 값이 서로 바뀜 int num1 = 10; int num2 = 20; swapValue(&num1, &num2, TYPE_INT); // 변수의 메모리 주소와 TYPE_INT를 넣음 printf("%d %d\n", num1, num2); // 20 10: swapValue에 의해서 값이 서로 바뀜 float num3 = 1.234567f; float num4 = 7.654321f; swapValue(&num3, &num4, TYPE_FLOAT); // 변수의 메모리 주소와 TYPE_FLOAT를 넣음 printf("%f %f\n", num3, num4); // 7.654321f 1.234567: // swapValue에 의해서 값이 서로 바뀜 return 0; }
실행 결과
b a 20 10 7.654321 1.234567
swapValue 함수에 매개변수를 void 포인터 두 개로 지정합니다. 단, void 포인터는 역참조를 할 수 없으므로 어떤 자료형으로 역참조할지 알려주기 위해 TYPE 열거형도 함께 받습니다. 함수 안에서는 TYPE에 따라 각 자료형의 포인터로 변환한 뒤 역참조하여 값을 서로 바꿉니다.
void swapValue(void *ptr1, void *ptr2, enum TYPE t) // 반환값 없음, void 포인터 매개변수 두 개와 { // 변수의 자료형을 알려줄 열거형을 받음 switch (t) { case TYPE_CHAR: // 문자면 char *로 변환한 뒤 역참조하여 값을 서로 바꿈 { char temp; temp = *(char *)ptr1; *(char *)ptr1 = *(char *)ptr2; *(char *)ptr2 = temp; break; } case TYPE_INT: // 정수면 int *로 변환한 뒤 역참조하여 값을 서로 바꿈 { int temp; temp = *(int *)ptr1; *(int *)ptr1 = *(int *)ptr2; *(int *)ptr2 = temp; break; } case TYPE_FLOAT: // 실수면 float *로 변환한 뒤 역참조하여 값을 서로 바꿈 { float temp; temp = *(float *)ptr1; *(float *)ptr1 = *(float *)ptr2; *(float *)ptr2 = temp; break; } } }
swapValue 함수를 사용할 때는 자료형 변환을 하지 않아도 다양한 자료형의 포인터(메모리 주소)를 넣을 수 있습니다. 여기서는 & (주소 연산자)를 사용하여 char, int, float형 변수의 주소를 구해서 swapValue 함수에 넣었습니다. 물론 어떤 자료형인지 알려줘야 하므로 TYPE 열거형 값도 넣어줍니다.
char c1 = 'a'; char c2 = 'b'; swapValue(&c1, &c2, TYPE_CHAR); // 변수의 메모리 주소와 TYPE_CHAR를 넣음 printf("%c %c\n", c1, c2); // b a: swapValue에 의해서 값이 서로 바뀜 int num1 = 10; int num2 = 20; swapValue(&num1, &num2, TYPE_INT); // 변수의 메모리 주소와 TYPE_INT를 넣음 printf("%d %d\n", num1, num2); // 20 10: swapValue에 의해서 값이 서로 바뀜 float num3 = 1.234567f; float num4 = 7.654321f; swapValue(&num3, &num4, TYPE_FLOAT); // 변수의 메모리 주소와 TYPE_FLOAT를 넣음 printf("%f %f\n", num3, num4); // 7.654321f 1.234567: // swapValue에 의해서 값이 서로 바뀜
void 포인터 매개변수에는 변수의 메모리 주소뿐만 아니라 메모리를 할당한 포인터도 넣을 수 있습니다. 또한, 일반 자료형의 포인터뿐만 아니라 구조체, 공용체, 열거형 등의 포인터도 넣을 수 있습니다.