void는 자료형이 없음을 의미합니다.
void 포인터는 자료형이 아직 정해지지 않은 포인터를 말하며,
자료형이 없기 때문에 어떠한 형태의 주소값도 저장할 수 있습니다.
다음 예제는 void 포인터를 선언하고 여러 형태의 주소를 저장하여 출력합니다.
#include <stdio.h>
int sum(int, int);
int main(void) {
int num = 10;
double arr[3];
void *ptr;
ptr = sum; // 함수의 주소를 저장
printf("%p\n", ptr);
ptr = # // num 변수의 주소 저장
printf("%p\n", ptr);
ptr = arr; // arr 배열의 주소 저장
printf("%p\n", ptr);
return 0;
}
int sum(int a, int b) {
return a + b;
}
이렇게 void 포인터에는 자료형의 종류와 관계없이 주소를 저장할 수 있습니다.
하지만 자료형이 정해 지지 않기 때문에 자료에 접근 하거나, 포인터 연산은 할 수 없습니다.
#include <stdio.h>
int main(void) {
int a = 10;
void *ptr = &a;
*ptr = 20; // 컴파일 에러
*ptr++; // 컴파일 에러
return 0;
}
이유은 자료형이 없기 때문에 주소에 접근하여 얼만큼의 byte를 읽어야 하는지 알수 없고,
포인터 연산시 얼만큼 이동해야 하는지 알 수 없기 때문입니다.
void 포인터는 일단 주소를 저장하고 사용할때 포인터의 자료형을 결정하여 사용해야 합니다.
#include <stdio.h>
int main(void) {
int a = 10;
void *ptr = &a;
// 포인터를 사용하기 전 자료형에 맞는 포인터 변수에 자료형을 변환하여 주소값 전달
int *iPtr = (int*)ptr;
*iPtr = 20;
printf("%d\n", *iPtr);
return 0;
}
이것은 나중에 배우게될 메모리 동적할당에서 사용의 예를 볼 수 있습니다.