I'm new to C++, and I have a question that should be easy, but it's making me crazy. I'm trying to set up a 2D array. The array is declared in Solver.h
like so:
protected:
static const int gridSize = 9;
int theGrid[gridSize][gridSize]
int *boxes[gridSize][gridSize];
...
and I'm trying to initialize it in Solver::Solver()
like so:
boxes[0] ={ &theGrid[0][0],&theGrid[0][1],&theGrid[0][2],
&theGrid[1][0],&theGrid[1][1],&theGrid[1][2],
&theGrid[2][0],&theGrid[2][1],&theGrid[2][2]
};
...
But the error I'm getting says "expression must be a modifiable lvalue" and "error: expected an expression". This didn't make sense to me, because I was under the impression that boxes[0]
was a modifiable lvalue.
So I wrote a tiny little (non OOP) program that just has the following in it's main()
:
int test[2][2];
test[0]= {1,2};
cout<<test[0][1]; //outputs "2" as expected.
And now I'm stuck and confused. What is wrong with my assignment routine in the Solver class?
To answer some questions:
I do want a multidimensional array, because eventually I'll be setting up boxes[1]
with another array of pointers to another set of data inside the theGrid
, a third set in boxes[2]
and so on. The idea is to take a 9x9 grid and split it into 3x3 squares (sound familiar? "Solver" should solve sudoku sets simply.) so I can check (and modify) all the values in those 3x3 squares independently.
I'm trying to get this working in VS2010.
I'm sure there's a good algorithm to define which array members are part of each 3x3 "box" based on that boxes number but I haven't hit it yet, and it seems less wasteful to code it once than to have the program re-create those boxes in loops every time it checks an answer. For the scope of this program the size of theGrid
is inalterable开发者_如何学Go, so my conscience will let me get away with a little hard coding.
The problem is that { ... }
is not an expression, it is an initializer. Some compilers have an extension to allow expressions to be formed using {}
, and C++0x adds several new meanings to the braces, but I'm going to keep this to standard C++.
I think the best general solution is to code a loop. You don't really want to write all that redundancy out, right?
Solver::Solver() {
for ( int boxnum = 0; boxnum < 9; ++ boxnum ) {
for ( int cellnum = 0; cellnum < 9; ++ cellnum ) {
boxes[ boxnum ][ cellnum ]
= &grid[ boxnum/3*3 + cellnum/3 ][ boxnum%3*3 + cellnum%3 ];
}
}
}
Checked code… I believe this is the pattern you're going for.
I think it wants the lvalue to be:
&boxes[0][0] = ...
See that you have
int *boxes[gridSize][gridSize];
Just make a test and change it to:
int boxes[gridSize][gridSize];
You can do this for example (I'm using Visual C++ Console Application to test this):
int boxes[gridSize][gridSize] = {
{1, 3, 5}, /* y[0][0], y[0][1], y[0][2] */
{2, 4, 6}, /* y[1][0], y[1][1], y[1][2] */
{3, 5, 7} /* y[2][0], y[2][1], y[2][2] */
};
Visual C++ doesn't accept this:
int test[2][2];
test[0]= { 1, 2 }; // error C2059: syntax error : '{'
cout << test[0][1];
You declare boxes
as boxes[9][9]
so in order to initialize it, you would need to specify boxes[0][0]
. Well at least initialize that memory block.
I may be mistaken but it looks like you didn't want to make boxes
a multi-dimensional array.
I am not sure about the example code given by you works. Atleast my compiler is not able to digest it (gcc 4.2). The reason for that is {...} are used while initialization and what you are doing is assignment.
u can try this
for (unsigned i=0; i < gridSize; ++i) {
for (unsigned j=0; j < gridSize; ++j) {
boxes[i][j] = &theGrid[i][j];
}
}
int main(){
int buf[2][2];
cout << typeid(buf[0]).name();
}
This pseudo program prints the equivalent of int [2]
. This means that the type of buf[0]
is an array of 2 integers
.
In C++ an array is a non modifiable Lvalue. It can be initalized but not assigned to.
Your code attempts to assign to boxes[0]
and this is ill-formed. The solution of course is as suggested by Potatoswatter and many of the above posts
精彩评论