Pointing to an array without changing it?

int* ptr = ary; of course does not work.

Please explain how and or give an example.

I wrote a program to sort an array, with ptrs to an array (the entire point was to not change the original array) but I do not understand and or know how to code pointers so that what they're pointing to can only be read. I've tried different syntax from books and online but I keep getting conversion errors which means I'm doing it wrong, and casting is more confusing in this case, if not impossible.

Comments

  • C or C++? I'll give you a C answer here. But hang onto your hat...it gets ugly ;-)

    If you want to sort an array of pointers, then you need an array of pointers. That's why int *ptr doesn't work. It's a single pointer. You need a pointer to point to each of your ints. Then you want to rearrange those pointers so they are in sorted order. But you have to start with an ARRAY of pointers to your ints.

    *** Here's some sample code ***

    int compare (const void * a, const void * b)

    {

      return ( **(int **)a - **(int **)b );

    }

    int main()

    {

      int ary[] = {1,3,7,5,7,8,6};

      #define ARYSIZE (sizeof(ary)/sizeof(int))

      int *pary[ARYSIZE];

      for(int i=0;i<ARYSIZE;i++)

       pary[i] = &ary[i];

      qsort(pary,ARYSIZE,sizeof(int *),compare);

      for(int i=0;i<ARYSIZE;i++)

       printf("%d: %d\n",i,*pary[i]);

      return 0;

    }

    *** Here's how it works ***

    You start with an array of ints:

    int ary[] = {1,3,7,5,7,8,6};

    You need another array of the same size, and you need the size in other places, so I #defined it:

    #define ARYSIZE (sizeof(ary)/sizeof(int)) // This will just evaluate to 7 here.

    Now you need an array for the pointers:

    int *pary[ARYSIZE]; // Array of pointers to int.

    But pary doesn't point to anything yet. You need to initialize each element to point to each int:

      for(int i=0;i<ARYSIZE;i++)

       pary[i] = &ary[i]; // Each pary element points to an int in ary

    Now you can sort it using qsort. qsort wants: the thing you want to sort. The number of elements in that thing. The size of each element, and a pointer to a function that will do the compare. We want to sort pary. It has ARYSIZE elements. Each element is an int *. And we have a function called compare, so:

    qsort(pary,ARYSIZE,sizeof(int *),compare);

    compare is where the black magic happens. qsort will call compare, and it will pass a POINTER to the elements in the array it wants to compare. Remember, we are sorting pary, which is an array of pointers to ints. So compare gets called with POINTERS to POINTERS to int. Yikes!

    compare needs to return 0 if a==b, <0 if a < b and > 0 if a > b. If you just subtract the 2 ints, you get the right results (you can work out why that works as a side exercise). But how do you get to the ints you want to compare? Well, a and b are POINTERS to POINTERS, so you need to dereference twice, using **. But first you need to cast, because a and b are declared as void *. So:

    **(int **)a // Gives you the int pointed to by the pointer to int, after you tell the compiler that a is really a pointer to a pointer to an int. (I told you to hang onto your hat here ;-)

    Finally, you can print out the result:

      for(int i=0;i<ARYSIZE;i++)

       printf("%d: %d\n",i,*pary[i]);

    Note: *pary[i] -- Take the i'th element in pary. It's an int pointer, so use * to dereference and get the value that it points to.

    HTH

Sign In or Register to comment.