【问题标题】:Assign a whole struct at once in an array在数组中一次分配整个结构
【发布时间】:2012-04-14 13:30:05
【问题描述】:

我正在学习 C++,但我对 struct 和数组有疑问。我的结构是:

struct board
{
    string name;
    string desc;
    int nval;
    int sval;
    int eval;
    int wval;
};

我的数组如下所示:

board field[10][10];

例如,我可以做到:

field[5][6].name = "ExampleName";
field[5][6].desc = "This is an example";
field[5][6].nval = 3;
//and so on...

但我想立即分配给整个结构,如下所示:

field[5][6] = {"ExampleName", "This is an example", 3, 4, 5, 6};
//so I don't have to type everything over and over again...

【问题讨论】:

  • C99 具有允许这种(某种)的复合文字,但我不知道它是否进入了 C++
  • 在 C++11 中,大括号初始化适用于单个 boards 以及数组。
  • 好的,我不能像你们写的那样快地阅读和尝试解决方案,所以非常感谢你们所有人!我真的很喜欢这个网站,但没想到半小时内就得到了这么多答案。

标签: c++ arrays struct


【解决方案1】:

C 标准允许您尝试做的事情。它似乎也在 C++ 中工作。我在 C++11 中验证了它:

struct board
{
string name;
string desc;
int nval;
int sval;
int eval;
int wval;
}field[10][10];

int main()
{    
field[5][6]={"ExampleName","This is an example",3,4,5,6};
cout<<field[5][6].name<<endl;
cout<<field[5][6].sval<<endl;
return 0;
}

打印正确。所以你应该可以做到。

【讨论】:

  • 只有最新的c++标准支持这个。
【解决方案2】:

如前所述,C99 和 C# 支持该语法的一种形式,但标准 C++ 不支持。您可以通过将构造函数添加到您的结构来做到这一点。请注意,这将不再与 ANSI C 兼容。

struct board
{
    string name;
    string desc;
    int nval;
    int sval;
    int eval;
    int wval;

    board()
    {
    }

    board(string name, string desc, int nval, int sval, int eval, int wval)
    {
        this->name = name;
        this->desc = desc;
        this->nval = nval;
        this->sval = sval;
        this->eval = eval;
        this->wval = wval;
    }
};

field[1][2] = board("name", "desc", 1, 2, 3, 4);

【讨论】:

  • 没错,但在实际运行之前你不能完全调用构造函数:)
  • @ScarletAmaranth 这是什么意思?
  • 嗯,就我而言,这并不是提问者想要的。
【解决方案3】:

恐怕你不能这样做。

但在现实生活中这不是问题,因为您通常不需要手动填写此类字段。您通常会循环执行。

如果您不介意运行时初始化,我会这样做:

    // in the beginning make these arrays
string names[10*10] = {
    "example 1 name"
    "example 2 name"
    "blah blah blah "
};

string descriptions[100] = {

};
//and then just loop through that

int i,j;
for (int k = 0; k != 10*10; ++k) { // 10*10 size of a board
        if (j == 10) {
            j = 0;
            i++
        }

        field[i][j].name = names[k]// get it from names
        field[i][j].desc = // get somehow the description,...
        ++j
    }

}

【讨论】:

  • 我认为他的意思是简单地分配类似于初始化的静态数据。在 C99 中可以使用复合文字。
  • 遗憾的是,我必须手动填写。但是感谢您的快速回答!
【解决方案4】:

如果您定义带参数的构造函数,您将能够创建临时并使用它初始化给定元素。您还需要定义默认构造函数:

struct board
{
   string name;
   string desc;
   int nval;
   int sval;
   int eval;
   int wval;

   board():
     name(""),
     desc(""),
     nval(0),
     sval(0),
     eval(0),
     wval(0){}

   board(
     const string& name,
     const string& desc,
     int nval,
     int sval,
     int eval,
     int wval):
   name(name),
   desc(desc),
   nval(nval),
   sval(sval),
   eval(eval),
   wval(wval){}
};

int main()
{
   board field[10][10];
   field[5][6]= board("ExampleName","This is an example",3,4,5,6);
   return 0;
}

【讨论】:

  • 感谢您的回答,但是您的拨号器和拨号器有什么区别,或者我应该使用哪一个?
  • 我在默认 c-tor 中定义显式默认值,通过引用传递参数并通过初始化列表初始化成员(这比在构造函数的主体中分配值更有效)。
【解决方案5】:

如果您确实需要为所有 100 个字段定义手动选择的值,您可以通过将所有参数写入文本文件然后解析文件并用提取的值填充数组来简化操作。 该文件可能看起来像

0 0
Corner field
Here it begins
0 1 2 3

0 1
ExampleName
This is an example
3 4 5 6

等等。 然后在读取文件时,您可以使用istream::getline 提取文本字符串,并使用istream::operator&gt;&gt; 提取数字。

但还是很痛苦。您确定没有自动生成至少大部分值的方法吗?

【讨论】:

    【解决方案6】:

    问题不太清楚,你的意思是一行,所以我将开始提供建议:

    使用聚合初始化:

    board fields[10][10] = { 
                      { {"ExampleName","This is an example",3,4,5,6}, // Element 0,0
                        {"ExampleName","This is an example",3,4,5,6}, // Element 0,1
                    // ...
                      },
                      { {"ExampleName","This is an example",3,4,5,6}, // Element 1,0
                    // ... 
                      }
                    };
    

    这是您可以获得的最接近单线的,它是有效的 C++(在所有变体中,鉴于 board 是一个聚合,因此 board[10][10] 也是一个聚合),但它可能很难阅读。

    下一步是更接近您正在做的事情,即初始化每个元素(而不是数组),因为在 C++11 中,您可以使用与您建议的相同类型的初始化。在 C++03 中,您需要通过构造函数来执行此操作(注意,这会更改类型的属性,并且您需要为数组创建默认构造函数):

     struct board {
        string name;
        string desc;
        int nval;
        int sval;
        int eval;
        int wval;
        board() {}  // [*]
        board( const char* name, const char* desc, int n, int s, int e, int w )
           : name(name), desc(desc), nval(n), sval(s), eval(e), wval(w)
        {}
     };
     board fields[10][10];  // [*] this requires the default constructor [*]
    
     fields[5][6] = board("ExampleName","This is an example",3,4,5,6);
    

    或者通过一个函数:

    board create_board( const char* name, const char* desc, ... ) {
       board res = { name, desc, ... };
       return res;
    }
    

    请注意,在这两种情况下,数组中的元素都会在数组初始化期间进行初始化,然后在它们之上复制一个新对象。

    【讨论】:

      猜你喜欢
      • 2016-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      相关资源
      最近更新 更多