Holla Tech - Learn

The void Pointer
 

A void pointer is used to refer to any address type in memory and has a declaration that looks like:
void *ptr;

The following program uses the same pointer for three different data types: 

int x = 33;
float y = 12.4;
char c = ‘a’;
void *ptr;
 
ptr = &x;
printf(“void ptr points to %d\n”, *((int *)ptr));
ptr = &y;
printf(“void ptr points to %f\n”, *((float *)ptr));
ptr = &c;
printf(“void ptr points to %c”, *((char *)ptr)); 

 

When dereferencing a void pointer, you must first type cast the pointer to the appropriate data type before dereferencing with *.

NOTE!
You cannot perform pointer arithmetic with void pointers.

Functions Using void Pointers
 

Void pointers are often used for function declarations.
For example:

void * square (const void *); 

 

Using a void * return type allows for any return type. Similarly, parameters that are void * accept any argument type. If you want to use the data passed in by the parameter without changing it, you declare it const.

You can leave out the parameter name to further insulate the declaration from its implementation. Declaring a function this way allows the definition to be customized as needed without having to change the declaration.

Consider the following program:

#include <stdio.h>

void* square (const void* num);

int main() {
  int x, sq_int;
  x = 6;
  sq_int = square(&x);
  printf(“%d squared is %d\n”, x, sq_int);

  return 0;
}

void* square (const void *num) {
  int result;
  result = (*(int *)num) * (*(int *)num);
  return result;

 

This square function has been written to multiply ints, which is why the num void pointer is cast to an int. If the implementation were to be changed to allow square() to multiply floats, then only the definition need be changed without having to make changes to the declaration.


Function Pointers as Arguments
 

Another way to use a function pointer is to pass it as an argument to another function.
A function pointer used as an argument is sometimes referred to as a callback function because the receiving function “calls it back”.
The qsort() function in the stdlib.h header file uses this technique.

Quicksort is a widely used algorithm for sorting an array. To implement the sort in your program, you need only include the stdlib.h file and then write a compare function that matches the declaration used in qsort:

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *)) 

 

To breakdown the qsort declaration:
void *base  A void pointer to the array.
size_t num  The number of elements in the array.
size_t width  The size of an element.
int (*compare (const void *, const void *) A function pointer which has two arguments and returns 0 when the arguments have the same value, <0 when arg1 comes before arg2, and >0 when arg1 comes after arg2.

The actual implementation of the compare function is up to you. It doesn’t even need to have the name “compare”. You have the opportunity to designate a sort from high to low or low to high, or if an array contains structure elements, you can compare member values.

The following program sorts an array of ints from low to high using qsort:

#include <stdio.h>
#include <stdlib.h>

int compare (const void *, const void *);

int main() {
  int arr[5] = {52, 23, 56, 19, 4};
  int num, width, i;
 
  num = sizeof(arr)/sizeof(arr[0]);
  width = sizeof(arr[0]);
  qsort((void *)arr, num, width, compare);
  for (i = 0; i < 5; i++)
    printf(“%d “, arr[ i ]);
   
  return 0;
}

int compare (const void *elem1, const void *elem2) {
  if ((*(int *)elem1) == (*(int *)elem2))
    return 0;
  else if ((*(int *)elem1) < (*(int *)elem2))
    return 1;
  else
    return 1;

 

NOTE!
We used the function name in the qsort call because a function name acts as a pointer.

BACK  NEXT

CLICK ON THE BUTTON BELOW TO GO TO THE C MAIN COURSE PAGE. 

C MAIN COURSE PAGE

 


© License: All Rights Reserved 


CONTACT HOLLA TECH – LEARN SUPPORT