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?

+3


source to share


3 answers


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 bytes unsigned char *

    .

+9


source


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 ;
}

      

+1


source


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.

0


source







All Articles