Simple Array Question...

Started by
8 comments, last by JSCFaith 22 years, 5 months ago
Hey, Say I had this: int Shapes[4] = {Line_1[4][4], Line_2[4][4], Line_1[4][4], Line_2[4][4]}; Now I want to access Shape[2], which is Line_2[4][4], and then access Line_2[1][2]. Would it be like this? Shape[2][1][2]? Well if you could help I would appreciate it. Edited by - JSCFaith on November 13, 2001 6:55:31 PM Edited by - JSCFaith on November 13, 2001 6:55:56 PM
Advertisement
Shape[2] is the 3rd element, 0,1,2
so Shape[2] is Line_1[4][4]
and Line_2[1][2] would be
Shape[1][1][2]
life is unfair, take advantage of it.UNMB2 - if the link doesn't work, try clicking it :)
Well, thunded I tried what you said on my array.

All those Arrays are already defined.

int Shapes[7][4] = {Line_1[4][4], Line_2[4][4], Line_1[4][4], Line_2[4][4],
Square_1[4][4], Square_1[4][4], Square_1[4][4], Square_1[4][4],
L1_1[4][4], L1_2[4][4], L1_3[4][4], L1_4[4][4],
L2_1[4][4], L2_2[4][4], L1_3[4][4], L1_4[4][4],
Z1_1[4][4], Z1_2[4][4], Z1_1[4][4], Z1_2[4][4],
Z2_1[4][4], Z2_2[4][4], Z2_1[4][4], Z2_2[4][4]};

Now, when I try to access it like so:

Shapes[1][0][1][2] = 1;

I get an error that says: "subscript requires array or pointer type" What does that mean. What am I doing wrong?



Edited by - JSCFaith on November 13, 2001 12:02:23 AM
I honestly don''t know what kind of hallucinogen y''all smoked around here. What gives you the impression that you can use an array element as a base from which you may access another element?

An array is a sequence of elements, guaranteed to be contiguously stored in memory. A pointer is an address of a single memory element, so it can be used to hold the address of an array. If a pointer ptr is the address of an array (the address is the location of element 0 in C/C++), then any element can be accessed using the array subscript operator:
ptr[index] 

What actually happens for simple C-style arrays is that the value of index is added on to the value of ptr (the address of the first array element) and this sum is the address of the desired element. This works because pointers are always the same size, no matter what they are pointing to (in Win32 this size is 4).

Let''s assume we have an array referenced by ptr at the address 32. Element 0 is at 32; element 1 is at ptr[1]. Because of the way the subscript operator is handled for pointers, it knows to add index * sizeof(ptr) to obtain the new address, and then return the value at that address. So element 1 is at 36. Why is this important to you? Well, Line_1 and Line_2 above appear to be 2-dimensional arrays (arrays of arrays). That means that Line_2[2][2] is an element, not an array, so you can''t try to access it''s own "elements" because it has none. Example:
int array[4][4];// assume array is initialized hereint j = array[2][1];int k = j[2]; // Error! j is a scalar, not an array! 

Since you assign the elements of your Shapes to specific elements of your arrays Line_1 and Line_2, they can''t be used as arrays.

I think you''re confusing initialization/assignment with declaration. What you''re trying to do, I believe, is assign each element in Shapes to be a 4x4 2D array. Here''s the proper statement for that:
int **Shapes[4] = { Line_1, Line_2, Line_1, Line_2 };// Shape[2] is Line_1, Line_2[1][2] can be accessed as follows:Shape[1][1][2]; // the two values are the sameShape[3][1][2]; 

Of course, this is basically useless code. I suggest you say what you''re trying to do and then someone can show you the correct way to do it. In the meantime, read up on pointers and arrays (and note the fact that the first element is at an index 0, and the last is at N - 1 for an N-element array).

Good luck.


I wanna work for Microsoft!
quote:Original post by Oluseyi
I honestly don''t know what kind of hallucinogen y''all smoked around here. What gives you the impression that you can use an array element as a base from which you may access another element?

An array is a sequence of elements, guaranteed to be contiguously stored in memory. A pointer is an address of a single memory element, so it can be used to hold the address of an array. If a pointer ptr is the address of an array (the address is the location of element 0 in C/C++), then any element can be accessed using the array subscript operator:
ptr[index]  

What actually happens for simple C-style arrays is that the value of index is added on to the value of ptr (the address of the first array element) and this sum is the address of the desired element. This works because pointers are always the same size, no matter what they are pointing to (in Win32 this size is 4).

Let''s assume we have an array referenced by ptr at the address 32. Element 0 is at 32; element 1 is at ptr[1]. Because of the way the subscript operator is handled for pointers, it knows to add index * sizeof(ptr) to obtain the new address, and then return the value at that address. So element 1 is at 36. Why is this important to you? Well, Line_1 and Line_2 above appear to be 2-dimensional arrays (arrays of arrays). That means that Line_2[2][2] is an element, not an array, so you can''t try to access it''s own "elements" because it has none. Example:
int array[4][4];// assume array is initialized hereint j = array[2][1];int k = j[2]; // Error! j is a scalar, not an array!  

Since you assign the elements of your Shapes to specific elements of your arrays Line_1 and Line_2, they can''t be used as arrays.

I think you''re confusing initialization/assignment with declaration. What you''re trying to do, I believe, is assign each element in Shapes to be a 4x4 2D array. Here''s the proper statement for that:
int **Shapes[4] = { Line_1, Line_2, Line_1, Line_2 };// Shape[2] is Line_1, Line_2[1][2] can be accessed as follows:Shape[1][1][2]; // the two values are the sameShape[3][1][2];  

Of course, this is basically useless code. I suggest you say what you''re trying to do and then someone can show you the correct way to do it. In the meantime, read up on pointers and arrays (and note the fact that the first element is at an index 0, and the last is at N - 1 for an N-element array).

Good luck.


I wanna work for Microsoft!



You should work for microsoft.
Ok, well basically, I am making a Tetris game. I had the code working earlier, but it had to many switch statements. Switching between the different type of shapes and loading the appropriate array. I was just trying to find a more efficient way to access those shapes. For example:

void CPiece::CreateShape(int ShapeType) {

// Other Stuff

switch(ShapeType) {
case SQUARE:
// Use this array
break;
case LINE:
// Use this array
break;
case //etc..
}

// Other Stuff
}

Basically, I was just trying to find an alternative to using switch statements. Just a lot of repeated code. Its no big deal, the code runs fine. I just don''t like lots of ifs'' or switches.

Well, thanks... Answers my question if "Can arrays be in arrays?"

BTW, "Now I want to access Shape[2], which is Line_2[4][4], and then access Line_2[1][2]. Would it be like this?" Was a typo, supposed to be Line_1.

Later.
James
Okay, how about rethinking the way you represent pieces? here''s a little bit of code off the top of the head:
class tetrii{public:  // constructor and methodsprivate:// tetrii are always 4 blocks; the only difference is how they// connect one to the next: up, down, left, right  int blocks[4][4];  int x, y; // coordinates  enum { up = 1, right, down, left };}; 

Creating a piece would now be a case of randomly selecting a direction to connect the next piece:
tetrii::terii(){  // first clear all blocks  int x, y;  for(x = 0; x < 4; ++x)    for(y = 0; y < 4; ++y)      blocks[x][y] = 0;  //  // starting block  x = rand() %4, y  = rand() %4;  blocks[x][y] = 1;  // next connection  int next, c = 1;  bool done = false;  while(!done)  {    // select connection to next block    next = rand() % 4;    switch(next)    {    case up:      // make sure up is valid, otherwise loop without changing c      if((y + 1) >= 4)      {        --c;        break;      }      else        blocks[x][++y] = 1;      break;      //    case right:      // do similar to up      break;      //    case down:      // ditto      break;      //    case left:      // ditto      break;      //    }  if(++c >= 4)    return;  }} 

This creates random blocks of all possible configurations. During the game itself, you can check whether the tetris has hit the barrier by checking if the bottom row has any ones; if it does, check whether the column with the one in that row has another block right beneath it. If yes, stop at the next advance time. The good thing about the method is tha the check is the same for all pieces.


I wanna work for Microsoft!
Well, that code would be nice, it doesn''t allow the game to think ahead. It can''t just randomly generate pieces. Well, I think I have an idea I am going to try. It won''t eliminate the swtiches all together, but it will get rid of most of them. Well, thanks for the help.

Later...
quote:Original post by JSCFaith
Basically, I was just trying to find an alternative to using switch statements. Just a lot of repeated code. Its no big deal, the code runs fine. I just don''t like lots of ifs'' or switches.

One way to eliminate "switch on type" in C++ is to use an inheritence structure with virtual functions. In fact, this is the main problem inheritence solves. It might be a little much for you to tackle, though.
Darn it! I was typing a really long response and then accedentaly pushed refresh. This is the 3rd time I have done that. Very annoying.

Well anyway, I decided to go with the classes and inheritance. I wrote out the code and it looks good. Its not as complicated as what I think your thinking of, but it works well.

Thanks again guys.

Later,
James

This topic is closed to new replies.

Advertisement