Link to home
Start Free TrialLog in
Avatar of G00fy
G00fy

asked on

Pointer to array

Hi,

How can I make a pointer to the following table:

const int test[2][2] = { {1,2}, {3,4} }

Like this?
const int ** ptr = test;


Thanks!
Avatar of boycy
boycy
Flag of United Kingdom of Great Britain and Northern Ireland image

Yes, correct. Remember that test *is* a pointer to the table (an array identifier is the address of the first element, i.e. (test == &test[0][0]) is true).

--Rob
Avatar of jweston1
jweston1

const int test[2][2] = { {1,2}, {3,4} };
const int **ptr = (const int **)&test;
ASKER CERTIFIED SOLUTION
Avatar of Axter
Axter
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
David (Axter) is of course right.

Note also that a reference if often syntactically nicer to use than a pointer...

      const INT2X2& ref = test;
      cout << ref[0][0] << endl;
      cout << ref[0][1] << endl;
      cout << ref[1][0] << endl;
      cout << ref[1][1] << endl;

jweston1's C-style cast was wrong:

      const int** ptr2 = (const int**)&test;

The need to cast should have raised alarm bells. It would still have been wrong but more more honest to use C++ casting, which would make you use the quite rightly much more alarming reinterpret_cast<>, which says I-know-better-than-the-compiler-this-type-really-is-a...

The int** type is a pointer to an array of integer pointers, typically used for a pointer to an array of pointers to arrays of int. You'd use this pointer for the following:

      int** ptr2 = new int*[2];
      ptr2[0] = new int[2];
      ptr2[0][0] = 1;
      ptr2[0][1] = 2;
      ptr2[1] = new int[2];
      ptr2[1][0] = 3;
      ptr2[1][1] = 4;
      cout << ptr2[0][0] << endl;
      cout << ptr2[0][1] << endl;
      cout << ptr2[1][0] << endl;
      cout << ptr2[1][1] << endl;
      delete[] ptr2[1];
      delete[] ptr2[1];
      delete[] ptr2;
Avatar of G00fy

ASKER

Axter solution works like a charm. But rstaveley, yours give this errors:
---
error C2440: 'initializing' : cannot convert from 'const int (*)[2]' to 'const int (&)[2][2]'
Reason: cannot convert from 'const int (*)[2]' to 'const int [2][2]'
There are no conversions to array types, although there are conversions to references or pointers to arrays
---
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of G00fy

ASKER

This compiles like a charm in both DevCPP and Visual C++.

But what I am trying to do is this:

------
#include <iostream>
#include <time.h>
using std::cout;using std::endl;

typedef int INT2X2[2][2];

const INT2X2 test = { {1,2}, {3,4} };
const INT2X2 test2 = { {1,2}, {3,4} };

int main( int argc, char * argv[] )
{
     srand(time(NULL));
     bool bChooseIt = rand()%2 ? true : false;

     const INT2X2& ref = bChooseIt ? test : test2;
     cout << ref[0][0] << endl;

     return 0;
}
--------

And this gives me the errors... Assignment works like a charm, but this give these errors:
D:\tmp\tmp\main.cpp(21) : error C2440: 'initializing' : cannot convert from 'const int (*)[2]' to 'const int (&)[2][2]'
        Reason: cannot convert from 'const int (*)[2]' to 'const int [2][2]'
        There are no conversions to array types, although there are conversions to references or pointers to arrays
Avatar of G00fy

ASKER

Works like a charm in MingW though, but how can I circumvent that problem? Via pointers yes, but otherwise?

Ok, found the solution myself, VisualC == stupid:

const INT2X2& ref = *(bChooseIt ? &test : &test2);

thanks all!
Yes that wouldn't have worked because the construct needs a temporary object, which would mean reassigning the reference, which you can't do.

There are ways around this.

e.g.
--------8<--------
#include <iostream>
#include <time.h>
using std::cout;using std::endl;

typedef int INT2X2[2][2];

const INT2X2 test = { {1,2}, {3,4} };
const INT2X2 test2 = { {5,6}, {7,8} };

template<typename T>
inline T& chooser(T& true_opt,T& false_opt,bool choice)
{
      if (choice)
            return true_opt;
      else
            return false_opt;
}

int main( int argc, char * argv[] )
{
     srand(time(0));
     bool bChooseIt = rand()%2 ? true : false;

     const INT2X2& ref = chooser(test,test2,bChooseIt);
     cout << ref[0][0] << endl;

     return 0;
}
--------8<--------

Interestingly enough T1 (the technical report - which is going-to-be-not-quite-standard) has a wrapper for references to handle some of this clumsiness.