@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.
So, 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 p
is int *
, then 4 bytes (assuming int
takes 4-byte) of data is fetched/accessed/looked-into. If the type of p
is char *
, then 1 byte of data is looked-into. If the type of p
is 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 qsort_int
, qsort_char
etc.)
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.
Best regards,
Tijo