functions,arrays and everything in between

hi there i have this wierd problem usually when i send an array(one dimentioned)
when i'm writing a code is like this:
x is an array

 
void func(int *x);

and etc but when i've tried to write a function with two dimentional array
let's say x[4][4];
like the method above it's not working
if i change the decleration to
void func(int x[4][4]);
it's working fine but i still prefer to use pointer
so my question is this
if the name of an array represent the address of the first "cell" in the array why it's not working with
void func(int *x);
?
Read this. The info on multi-dimensional arrays is near the bottom. I don't think you want to do this with pointers. the additional dimensions need to be specified to the compiler for this to work properly. It is also better in terms of documentation to use array syntax for declaring your functions. This makes it more clear to the reader that an array is required and not just a pointer to a single int. Also, in your example you do not specify a size. how does the func function know when to stop reading the array?

http://cplusplus.com/doc/tutorial/arrays/
A simple pointer does not provide enough information to access a 2D array. A 2D array is really just a 1D array with 1D arrays as elements. You must know the size of the element arrays in order to access the 2D array. Note that, just like the case of the 1D array, you don't need the size of the "outermost" dimension.

1
2
3
int func( int x[][4] ) {
    return x[1][2];
}

kempofighter it's more about styling rather then the code itself(cause as i said it's working) that's why i was generic with the question i know i can use

void func(int x[][4]);
void func(int x[4][4]);
but in terms of styling and logic because when i send an array to a function it sends the address of the first cell i thought it's just working like a chain in the memory one after another and it's just a represention of groups(the multidimentions) that's why i thought it will also work (like it's working with one dimention) with a pointer:X
still i'm wondering if there's a pointer way to send a multidimentioned array to a pointer

here's the code(method that didn't worked) the error is "subscript requires array or a pointer":
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const int ROW=3;
const int COL=3;
int climbing(int *hill, char *ctrl,int posx=0,int posy=0);

//here comes other functions and the main

int climbing(int *hill, char *ctrl,int posx,int posy)
{
  int steps=0;

  while( (posx<(ROW-1))||
	     (posy<(COL-1))  )
  {
      if(hill[posx+1][posy+1]== hill[posx][posy])
	  {
                 hill[posx][posy] = -30;
		 ++posx;
		 ++posy;
		 ctrl[steps]='u';
		 ++steps;
		 
	  }
	  else if(hill[posx][posy+1]== hill[posx][posy])
	  {
                hill[posx][posy] = -30;
		++posy;
		ctrl[steps]='h';
		++steps;
	  }
	  else if(hill[posx][posy+1]== hill[posx][posy])
	  {
                hill[posx-1][posy+1] = -30;
		++posy;
		--posx;
                ctrl[steps]='d';
		++steps;
	  }
	  else
	   break;
  }
   return steps;
}



basicly if i change the declaration and the name of the function to:
1
2
3
4
5
int climbing(int hill[ROW][COL], char *ctrl,int posx=0,int posy=0);
int climbing(int hill[ROW][COL], char *ctrl,int posx,int posy)
{
  //whatever..
}


it's working great but i mean
char *ctrl is working great(one dimentional)
so how to work with multidimentional and pointer ?
if there's a way i'd like to know it cause i wanna make sure i understand the issue to the fullest

thanks in advanced
2D arrays are 1D arrays -- just with different syntax. Therefore what you want to do is certainly possible with syntax changes. The downside (or upside -- depending on how you look at it) is that the dimensions of the array are unknown.

All you need to do is give a pointer to the start of the array. From there, rather than treating it as a 2D array, think of it as a 1D array, with each row coming after the previous.

IE instead of this:

0 1 2
3 4 5
6 7 8


You'd have this:

0 1 2 3 4 5 6 7 8


You can then get the desired 1D index with (y*width)+x. This is basically what the compiler does automatically when you deal with 2D arrays.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void printxy( int* a2darray, int x, int y )
{
  // assume the width is '3'
  cout << a2darray[ (y*3)+x ];
}

int main()
{
  // note.. [Y][X]!  not [X][Y]!!!!
  int myarray[4][3] = {
    {0,1,2},
    {3,4,5},
    {6,7,8},
    {9,10,11}
  };

  printxy( &myarray[0][0], 2, 1 ); // "5"
  printxy( &myarray[0][0], 1, 2 ); // "7"

  return 0;
}


Seeing as how you have X and Y reversed from the norm, you may need to do things differently. It all depends on how you set up your array. [Y][X] is typcial because that's how arrays are naturally initialized by the language (see initialization of myarray in the code sample), but if you use loops and stuff to initialize, you can switch them if you want. It doesn't matter, really (other than making your code a bit weird to others trying to read it).

--------------------

EDIT:

I don't know if this is 100% kosher according to language standards. It has worked for me every time I've tried it in the past, but the language might allow the compiler to optimize 2D arrays by padding them to a easier-to-compute size.

ie

 
int foo[3][3];


The compiler might make this a [3][4] array in which case the above code wouldn't work (*hack*cough*). If this is the case, then there's no way to accomplish this (which is why I find it unlikely to be the case -- I'm just covering my butt).

Anyway this is just yet another reason I stay as far away from multi-dimensional arrays in my code. They're syntax hell. I prefer to just use 1D arrays everywhere. No muss, no fuss:

1
2
3
int myarray[ 4*3 ];   // vs. [4][3]

printxy( myarray, x, y ); // vs. &myarray[0][0] or an alternative 


Or better yet -- write a simple container class which automates all of this. Here's a simple one (was bored):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

template <typename T>
class Array2D
{
public:
  Array2D(int width,int height)
    : nWd(width), nHt(height), pPtr( new T[width*height] )
  {}

  ~Array2D()
  {
    delete[] pPtr;
  }

  T& operator () (int x, int y)
  {
    return pPtr[ (y*nWd) + x ];
  }

  // make the const version too
  const T& operator () (int x,int y) const
  {
    return pPtr[ (y*nWd) + x ];
  }

protected:
  int nWd;
  int nHt;
  T* pPtr;

private:
  // prevent accidental copying / empty creation
  Array2D();
  Array2D(const Array2D&);
  Array2D& operator = (const Array2D&);
};

//------------------------------

int main()
{
  Array2D<int> myarray(3,4);

  // to print x,y
  cout << myarray(x,y);

  return 0;
}


just be sure to pass such an array by reference when passing to other functions.
Last edited on
Topic archived. No new replies allowed.