How do you use void pointer in C?
Here are a few function declarations that I am having a hard time figuring out how to complete them. I have looked through the webpages to find out what a void pointer is and I understand that it needs to be distinguished from something useful (because it just points to some block of memory), but I don't see how that helps in completion these declarations.
/* type of comparison function that specifies a unique order.
Returns 1 if pointer1 should come before,
0 if equal to, or -1 if after pointer2. */
typedef int (*compare_function) (const void* pointer1, const void* pointer2);
/* get the data object */
void* get_obj(const void* item_pointer);
There are more features like this, but I think if I figure out how to do it, I should be in good shape. For example, for the second function, how do we overlay item_pointer on anything appropriate that should be returned?
source to share
void *
usually means that you are only interested in the data address regardless of its type, some of the reasons are:
-
internal data representation, which this one
void *
indicates hiding, you should not directly access data, hide information , its function 2 is an example of this case. -
the type is known by some function in the chain of calls, for example,
qsort
and most functions passing arguments to other functions. -
type is not required, since the data to which the pointer points would be handled as different types, e.g., via
memcpy
that can process data in the form of bytesunsigned char *
.
Sorting in C with quicksort uses void pointers so that we can sort any data in arrays. The sort function must return -1, +1, or 0 if b is before, after, or is the same as a
#include <stdio.h>
#include <stdlib.h>
int sort_order( const void *, const void *);
int main(void)
{
int i;
char alfa[6] = { ’C’, ’E’, ’A’, ’D’, ’F’, ’B’ };
qsort( (char*)alfa, 6, sizeof(char), sort_order);
for (i=0 ; i<5 ; i++) // now in order?
printf("\nchar %d = %c",i, alfa[i]);
printf("\n");
system("PAUSE");
return 0;
}
int sort_order( const void* a, const void* b)
{
if ( *((char*)a) < *((char*)b) ) return -1 ;
else if ( *((char*)a) > *((char*)b) ) return 1 ;
else return 0 ;
}
Then you can sort your own data types:
typedef struct { float left; float right;} ears;
typedef struct{ char name[13]; int weight; ears eararea;} monkey;
monkey* Index[4];
for(i=0;i<4;i++)
Index[i]= (monkey* )malloc(sizeof(monkey));
qsort((void* ) Index, 4, sizeof(monkey* ), sort_order);
// Sorted by weight
int sort_order( const void* a, const void* b) {
if((**((monkey** )a)).weight < (**((monkey** )b)).weight) return -1 ;
else if ((**((monkey** )a)).weight > (**((monkey** )b)).weight ) return 1 ;
else return 0 ;
}
Complete program
#include <stdio.h>
#include <stdlib.h>
typedef struct {
float left;
float right;
} ears;
typedef struct {
char name[13];
int weight;
ears eararea;
} monkey;
int sort_monkeys( const void *, const void *);
int main(void)
{ monkey* monkeys[4];
int i;
for(i=0; i<4; i++) {
monkeys[i]= (monkey* )malloc(sizeof(monkey));
monkeys[i]->weight=i*10;
if (i==2)
monkeys[i]->weight=1;
}
for (i=0 ; i<4; i++)
printf("\nchar %d = %i",i, monkeys[i]->weight);
qsort((void* ) monkeys, 4, sizeof(monkey* ), sort_monkeys);
for (i=0 ; i<4; i++) // now in order?
printf("\nmonkey %d = %i",i, monkeys[i]->weight);
return 0;
}
// Sorted by weight
int sort_monkeys( const void* a, const void* b) {
if((**((monkey** )a)).weight < (**((monkey** )b)).weight) return -1 ;
else if ((**((monkey** )a)).weight > (**((monkey** )b)).weight ) return 1 ;
else return 0 ;
}
source to share
Any type of pointer can be assigned void*
, this is useful in cases where the function does not need to know the type, or information about the type is passed in other ways. This allows you to write only one function to work with any pointer type, rather than a separate function for each data type.
As long as you cannot dereference void*
, you can apply it to any type and dereference it - the semantics of this - that is, whether it makes sense is code dependent and is not a forced byte compiler.
Often, a common function is not interested in the contents of some data block, just its address and often its size.
As a simple example:
void memcopy( void* to, void* from, int length )
{
char* source = (char*)from ;
char* dest = (char*)to ;
int i ;
for( i = 0; i < lengt; i++ )
{
dest[i] = source[i] ;
}
}
int main()
{
typedef struct
{
int x ;
int y ;
} tItem
tItem AllItems[256] = {0} ;
tItem AllItemsCopy[256] ;
memcopy( AllItemsCopy, AllItems, sizeof(AllItems) ) ;
}
See that you memcopy()
don't need to know what it tItem
is to copy an array from them, it only needs to know the addresses and size of the array in bytes. It passes pointer arguments void*
to reinterpret the data as an array char
to perform a byte copy. You don't need to know the internal semantics tItem
or any other data object passed to it for this.
source to share