简体   繁体   English

C ++初始化2D结构数组

[英]C++ Initializing a 2D array of structs

I'm writing a program that allows the user to play sudoku puzzles. 我正在写一个程序,允许用户玩数独游戏。 Each puzzle is a 2d array of structs, but I'm unable to intialize the array in one go. 每个难题都是一个二维结构数组,但我无法一次性初始化该数组。 Is there any way to do this without needing to intialize each part of the structure for each element of the array? 有什么方法可以做到,而不必为数组的每个元素初始化结构的每个部分? Here is some of my code. 这是我的一些代码。

class Sudoku {
   protected:
   struct Puzz {
      int Ans;
      // IsClue is used further in the program so the user cannot change the clues given.
      bool IsClue;  
   };
   Puzz Puzzle[9][9]; // I chose a 2D array so represent the 9 rows and columns of a sudoku puzzle
};

I've tried some of the following: 我尝试了以下一些方法:

Puzzle[][9] = {{0, false, 8, true,  0, false, 6, true,  7, true,  0, false, 0, false, 0, false, 0, false}, //...etc, going on for each row
Puzzle[9][9] = // etc, etc, but I get an error saying "Expected an expression

Is the only way to initialize each element to do 是初始化每个元素的唯一方法

Puzzle[x][y].Ans = x; Puzzle[x][y].IsClue = true/false;?

The problem is that you try to assign to an array, and it's simply not possible. 问题在于您尝试分配给数组,而这根本不可能。 You need to actually initialize it, which is something completely different. 您实际上需要对其进行初始化 ,这是完全不同的。

If you don't mind writing lot of lines that are almost the same, then you could use a constructor member initializer list . 如果您不介意编写几乎相同的行,则可以使用构造函数成员初始化器列表 Like eg 像例如

Sudoku::Sudoku()
    : Puzzle{{...}, {... }, ... }
{}

If only a few structures in the arrays differ from some default values, then you could set all entries in the arrays to the same default value, using eg std::fill and then change those few entries that have special values. 如果数组中只有少数结构与某些默认值不同,则可以使用例如std::fill将数组中的所有条目设置为相同的默认值,然后更改这些具有特殊值的少数条目。

To initialize a two-dimensional array, use a for-loop. 要初始化二维数组,请使用for循环。 As in: 如:

 for (int i = 0; i < row_count; i++) {
    for (int j = 0; j < col_count; j++) {
       item[i][j] = initial_value;
    }
 }

If you want to use an initializer list like in the above, you can do so by simply wrapping each instance of the struct in brackets. 如果要像上面一样使用初始化列表,可以通过将每个结构实例包装在方括号中来实现。 However, initializing your sodoku board with a literal is not a particularly scalable approach to generating a sodoku board for the player. 但是,用文字初始化数独板并不是为玩家生成数独板的一种特别可扩展的方法。 That is, instead of: 也就是说,代替:

Puzzle puzz[9][9] = {{0, false, 8, true,  0, false, 6, true,  7, true,  0, false, 0, false, 0, false, 0, false, ...}};

You would use: 您将使用:

Puzzle puzz[9][9] = {
  {  // First row
     {0, false}, // first column
     {8, true}, // second column
     ...
  },
  {  // Second row
     ...
  },
  ...
};

Since this is C++, though, you may wish to consider representing your board using nested vectors (that is vector<vector<Cell>> ). 但是,由于这是C ++,因此您不妨考虑使用嵌套向量(即vector<vector<Cell>> )来表示您的电路板。 While this may be overkill, especially for a Sodoku board (especially if it is always 9x9), that will allow you to more easily represent non-standard board sizes, and the vector data structure comes with the ability to default initialize/fill all members with a pre-specifed value. 尽管这可能是过高的,特别是对于Sodoku主板(尤其是始终为9x9),这将使您能够更轻松地表示非标准主板尺寸,并且矢量数据结构具有默认初始化/填充所有成员的功能具有预先指定的值。 As @paddy aptly notes in the comments, however, there are also other functions (like std::fill that can be used with ordinary arrays to handle common use cases. 正如@paddy在注释中恰当地指出的那样,还有其他功能(例如std::fill可以与普通数组一起使用来处理常见的用例)。

You can initialize with an initializer list in c++11 or higher: 您可以在c ++ 11或更高版本中使用初始化列表进行初始化:

Puzz Puzzle[2][2] = {
    { {8, true}, {9, false} },
    { {10, true}, {11, false} }
};

If in a class you can default construct it the same way: 如果在一个类中,您可以默认以相同的方式构造它:

class PuzzHolder {
    PuzzHolder() : Puzzle{
        { {8, true}, {9, false} },
        { {10, true}, {11, false} }
    } { }

    Puzz Puzzle[2][2];
};

Although, if it is very big, this might get pretty messy. 虽然,如果它很大,可能会变得很混乱。 So the final approach could be to initialize it in a loop. 因此,最终的方法可能是在循环中对其进行初始化。

Live example. 现场示例。

Here's an example showing how a 2 x 2 array can be initialized. 这是显示如何初始化2 x 2数组的示例。 I'll leave it to you to extend that to a 9 x 9 array. 我将它留给您,以将其扩展到9 x 9阵列。

class Sudoku {
   Sudoku();
   protected:
   struct Puzz {
      int Ans;
      bool IsClue;  
   };
   Puzz Puzzle[2][2];
};

Sudoku::Sudoku() : Puzzle{{{0, false}, {1, true}}, {{2, false}, {3, true}}}
{
}

Having said that, it might be easier to create a default constructor of Puzz which does the sensible thing for most objects and then modify only a select elements of Puzzle in Sudoku 's constructor. 话虽如此,创建一个默认的Puzz构造函数可能会更容易,该构造函数对大多数对象执行明智的操作,然后在Sudoku的构造函数中仅修改Puzzle的选择元素。

class Sudoku {
   Sudoku();
   protected:
   struct Puzz {
      int Ans;
      bool IsClue;  
      Puzz() : Ans(0), IsClue(false) {}
   };
   Puzz Puzzle[2][2];
};

Sudoku::Sudoku()
{
   // Change specific elements of Puzzle
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM