@damn_me, This was large enough to fit inside a comment. So, I am adding it as a separate answer, and not as a comment/reply to your comment.
Dereferencing means, trying to get to the data in the location pointed to by the pointer.
a = b; and
b = a; are both valid. It is
*a which is invalid, as you don’t kind of data
a points to.
To throw more light on what I said, all kinds of pointer variables take up the same memory (i.e.,
sizeof(int *) == sizeof(char *) == sizeof(Node *)) The type of a pointer is only good to access the data it points to.
So, if you have a pointer variable
p, and if you do a
*p, then, it needs to know how many bytes of data from the memory address pointed to by
p needs to be looked into. If the type of
int *, then 4 bytes (assuming
int takes 4-byte) of data is fetched/accessed/looked-into. If the type of
char *, then 1 byte of data is looked-into. If the type of
Node *, then 259 bytes (assuming that Node is the structure as defined in my first answer) of data is looked-into.
Now, imagine a
void *p; If you do a *p, then it does not know how many bytes of data to look into. Hence, it is forbidden. But, if you cast it into an
int * or a
Node * or more generally, a
<Type> *, then when you do a dereferencing on the type casted pointer,
sizeof(<Type>) bytes starting from the memory location pointed to by it will be looked-into.
void pointers are usually used as a generic type. It is up to the programmer to properly type-cast it and then dereference the pointer when in need.
In the specific
qsort example, this function expects a fourth argument, which is a pointer to a function (yes, there are pointer to functions, in case you didn’t already know – the name of the function is a pointer to itself). This function must return an integer after comparing two data items. Now, when defining the signature of
qsort, it needs to specify what kind of function it expects. Since the fourth argument points to a function, it needs to specify what kind of function it points to (the signature of that function). For that, it needs to give the data types. If not for the generic
void pointers, it would have been impossible in C to do this, as you would need separate declarations for each different data type you would expect
qsort to sort (which also means, you will not be able to use
qsort to sort custom data types) in addition to the added complexity that all those
qsort functions need to be uniquely named (like
From what I understood from your comment, I feel that you are confused about the basics of pointers. I hope this answer might clear up some of that. If you need more clarification/understanding, feel free to reply/ask.