在 C++ 中初始化大型二维数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3460074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:53:20  来源:igfitidea点击:

Initialize large two dimensional array in C++

c++arrays

提问by Matthew Murdock

I want to have staticand constanttwo dimensional array inside a class. The array is relatively large, but I only want to initialize a few elements and others may be whatever compiler initializes them to.

我想在一个类中有静态常量的二维数组。该数组相对较大,但我只想初始化几个元素,其他元素可能是编译器将它们初始化为的任何元素。

For example, if a class is defined like:

例如,如果一个类定义如下:

class A {
public:
  static int const test[10][10];
};

int const A::test[10][10] = {
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 7, 7, 7, 7, 0, 0, 0},
  {0, 0, 0, 7, 7, 7, 7, 0, 0, 0},
  {0, 0, 0, 7, 7, 7, 7, 0, 0, 0},
  {0, 0, 0, 7, 7, 7, 7, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};

and I am interested only to initialize the elements marked with '7', how do I do this on the same elements, but with array of larger size, like array[1024][1024]?

并且我只想初始化标有“7”的元素,如何在相同的元素上执行此操作,但使用更大尺寸的数组,例如数组 [1024][1024]?

回答by James Curran

Any part of an array which is initialized, that is beyond the initialization, is initialized to 0. Hence:

初始化的数组的任何部分,超出初始化的部分,都被初始化为 0。因此:

int const A::test[10][10];           // uninitialized

int const A::test[10][10] = { {0} }; // all elements initialized to 0.

int const A::test[10][10] = {1,2};   // test[0][0] ==1, test[0][1]==2, rest==0

That means all you have to initialize is up to the last non-zero:

这意味着您需要初始化的只是最后一个非零值:

int const A::test[10][10] = { 
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
  {0, 0, 0, 7, 7, 7, 7, 0, 0, 0}, 
  {0, 0, 0, 7, 7, 7, 7, 0, 0, 0}, 
  {0, 0, 0, 7, 7, 7, 7, 0, 0, 0}, 
  {0, 0, 0, 7, 7, 7, 7, 0, 0, 0}
};

It is not the best solution, but will save some work.

这不是最好的解决方案,但会节省一些工作。

回答by C Johnson

There is no way to assign an int to const array after it's been initialized. So you will have to script it up:

在初始化之后,无法将 int 分配给 const 数组。因此,您必须编写脚本:

And include your file this way:

并以这种方式包含您的文件:

class A {
public:
    static const int test[10][10];
};

const int A::test[10][10] = {
#include "data.inc" // points to the file generated by script.
};

回答by ysap

Coincidentally, a couple of hours after reading your question, I bumped into a possible solution while looking for something else in the book "C - A Reference Manual" 5th ed., Harbison/Steele(this is a fantastic C reference, by the way).

巧合的是,在阅读您的问题几个小时后,我在寻找书中的其他内容时遇到了一个可能的解决方案"C - A Reference Manual" 5th ed., Harbison/Steele(顺便说一下,这是一个很棒的 C 参考)。

According to the book,

根据这本书,

C99 allows you to name the components of an aggregate (structs, union or array) to be initialized within an initializer list.

C99 允许您命名要在初始化列表中初始化的聚合(结构、联合或数组)的组件。

... and it gives an example:

...它给出了一个例子:

int a1[5] = { [2]=100, [1]=3 }; /* eqv. to {0, 3, 100, 0, 0} */

So, depending on the compliance of your compiler and on the size of the non-zero elements in your array, you may be able to use this syntax to init your matrix efficiently. That said, the book doesn't give an example for 2D arrays. Unfortunately, I couldn't test this idea since MSVC++ 2005 doesn't seem to support C99.

因此,根据编译器的合规性以及数组中非零元素的大小,您可以使用此语法有效地初始化矩阵。也就是说,这本书没有给出二维数组的例子。不幸的是,我无法测试这个想法,因为 MSVC++ 2005 似乎不支持 C99。

回答by Jess

When I do this, I use a method to read in data. Generically, it looks like:

当我这样做时,我使用一种方法来读入数据。一般来说,它看起来像:

extern void ReadElements(string sFile, Matrix a)
{
    int x;
    int y;
    double value;

    ifstream myInFile;

    myInFile.open(sFile, ifstream::in);
    while(!myInFile.eof())
    {
        myInFile >> x >> y >> value;
        a[x][y] = value;
    }

    myInFile.close();
    return;
}

回答by Peter G.

You could access the array only through accessor functions/macros and arrange the internal storage so, that the initialzed part goes first.

您只能通过访问器函数/宏访问数组并安排内部存储,以便初始化部分先行。

回答by SigTerm

A solution would be to hide non-const array somewhere, load it from file or resource, and then use const reference to access it. I.e.

一种解决方案是将非常量数组隐藏在某处,从文件或资源中加载它,然后使用 const 引用来访问它。IE

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef int Array[1024][1024];

namespace DontTouch{
    Array arr;
    void initArray(){
        for (int i = 0; i < 1024; i++)
            for (int j = 0; j < 1024; j++)
                arr[i][j] = rand() & 0xff;
    }
}

const Array &arr = DontTouch::arr;

int main(int argc, char** argv){
    DontTouch::initArray();

    //arr[4][4] = 0;//compiler error            
    for (int i = 0; i < 1024; i++){
        for (int j = 0; j < 1024; j++)
            printf(" 0x%02x", arr[i][j]);
        printf("\n");
    }

    return 0;
}

It will be (IMO) more readable than script-generated huge array.

它将(IMO)比脚本生成的巨大数组更具可读性。

You can do same thing with class that acts like 2D array (easy enough to write). Again - have non-const object somewhere, and use const reference to access the data. It should be easy to make non-const array completely invisibile outside of just one cpp.

你可以用像二维数组一样的类做同样的事情(很容易写)。再次 - 在某处拥有非常量对象,并使用 const 引用来访问数据。在仅一个 cpp 之外使非常量数组完全不可见应该很容易。

Another way to do that is to generate array using script. If you think that big arrays are ugly, put entire thing into *.h file (make sure it is included in only one *.cpp file), so it won't scare people away. Compiler doesn't care what you write in your code as long as it is syntactically correct.

另一种方法是使用脚本生成数组。如果你觉得大数组很丑,把整个东西放到 *.h 文件中(确保它只包含在一个 *.cpp 文件中),这样它就不会吓跑人们。编译器并不关心你在代码中写了什么,只要它在语法上是正确的。

I don't think there are any other options.

我不认为还有其他选择。

回答by Deqing

It only takes four lines by using std::fill_n

使用它只需要四行 std::fill_n

using std::fill_n;
using std::begin;

fill_n(begin(test[3])+3, 4, 7);
fill_n(begin(test[4])+3, 4, 7);
fill_n(begin(test[5])+3, 4, 7);
fill_n(begin(test[6])+3, 4, 7);

回答by robin girard

install R software, it's free ! then call function defined below with

安装 R 软件,它是免费的!然后调用下面定义的函数

writetable(data,"test","myfile.h")

writetable(data,"test","myfile.h")

if data is your matrix then you're done

如果数据是你的矩阵,那么你就完成了



writetable<-function(data,varname="test",file="myFile.hpp"){
  cat('const static double CONST_array_',varname," [][] = { \n \t\t\t\t {",file=file,append=TRUE,sep='')
  for (j in 1:(dim(data)[2]-1)){
    for (i in 1:(dim(data)[1]-1) ){
      cat(data[i,j],',',file=file,append=TRUE)
    } 
    cat(data[dim(data)[1],j],'},\n \t\t\t\t\t{',file=file,append=TRUE)
  }
  for (i in 1:(dim(data)[1]-1) ){
    cat(data[i,dim(data)[2]],',',file=file,append=TRUE)
  } 
  cat(data[dim(data)[1],dim(data)[2]],'}\n }; \n',file=file,append=TRUE)
}