A pointer to void is a "generic" pointer type. A void * can be converted to any other pointer type without an explicit cast. You cannot dereference a void * or do pointer arithmetic with it; you must convert it to a pointer to a complete data type first.
void * is often used in places where you need to be able to work with different pointer types in the same code. One commonly cited example is the library function qsort:
==========================================================
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
==========================================================
base is the address of an array, nmemb is the number of elements in the array, size is the size of each element, and compar is a pointer to a function that compares two elements of the array. It gets called like so:
==========================================================
int iArr[10];
double dArr[30];
long lArr[50];
...
qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt);
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble);
qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong);
==========================================================
The array expressions iArr, dArr, and lArr are implicitly converted from array types to pointer types in the function call, and each is implicitly converted from "pointer to int/double/long" to "pointer to void".
The comparison functions would look something like:
==========================================================
int compareInt(const void *lhs, const void *rhs)
{
const int *x = lhs; // convert void * to int * by assignment
const int *y = rhs;
if (*x > *y) return 1;
if (*x == *y) return 0;
return -1;
}
==========================================================
By accepting void *, qsort can work with arrays of any type.
The disadvantage of using void * is that you throw type safety out the window and into oncoming traffic. There's nothing to protect you from using the wrong comparison routine:
==========================================================
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt);
==========================================================
compareInt is expecting its arguments to be pointing to ints, but is actually working with doubles. There's no way to catch this problem at compile time; you'll just wind up with a missorted array.
example:
/******************************************************************************
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, PHP, Ruby,
C#, VB, Perl, Swift, Prolog, Javascript, Pascal, HTML, CSS, JS
Code, Compile, Run and Debug online from anywhere in world.
*******************************************************************************/
#include <stdio.h>
typedef struct
{
int one;
int two;
int three;
} myStruct2;
typedef struct
{
int one;
int two;
} myStruct;
int
main ()
{
void *a = (void *) sizeof (myStruct2);
char *b = (char *)a;
printf ("a :%p\n", a);
b = b + sizeof (myStruct);
printf ("b :%p\n", b);
// Print the sizeof integer
printf("Size of (void*) = %lu"
" bytes\n",
sizeof(void*));
// Print the size of (int*)
printf("Size of (char*) = %lu"
" bytes\n",
sizeof(char*));
return 0;
}
void体现了一种抽象,这个世界上的变量都是"有类型"的。void的出现只是为了一种抽象的需要,如果你正确地理解了面向对象中"抽象基类"的概念,也很容易理解void数据类型。
No comments:
Post a Comment