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

时间:2022-11-20 21:34:25

I want to have static and constant two 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'的元素,我如何在相同的元素上进行初始化,但是使用更大的数组,比如array[1024][1024]?

8 个解决方案

#1


26  

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.

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

#2


7  

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.
};

#3


3  

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 -参考手册》第五版中找到了一个可能的解决方案。

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。

#4


1  

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;
}

#5


0  

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

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

#6


0  

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数组隐藏在某处,从文件或资源中加载它,然后使用const引用访问它。即。

#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.

它(在我看来)比脚本生成的巨大数组更具可读性。

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.

您可以对类似2D数组的类做同样的事情(编写起来很容易)。同样——在某处有非const对象,并使用const引用访问数据。在一个cpp之外,使非const阵列完全隐形应该很容易。

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文件(确保只包含在一个*中)。所以它不会把人们吓跑。编译器并不关心你在代码中写什么,只要它在语法上是正确的。

I don't think there are any other options.

我认为没有其他选择。

#7


0  

It only takes four lines by using std::fill_n

使用std::fill_n只需要4行

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);

#8


-5  

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

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

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

writetable(数据、“测试”、“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)
}

#1


26  

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.

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

#2


7  

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.
};

#3


3  

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 -参考手册》第五版中找到了一个可能的解决方案。

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。

#4


1  

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;
}

#5


0  

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

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

#6


0  

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数组隐藏在某处,从文件或资源中加载它,然后使用const引用访问它。即。

#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.

它(在我看来)比脚本生成的巨大数组更具可读性。

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.

您可以对类似2D数组的类做同样的事情(编写起来很容易)。同样——在某处有非const对象,并使用const引用访问数据。在一个cpp之外,使非const阵列完全隐形应该很容易。

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文件(确保只包含在一个*中)。所以它不会把人们吓跑。编译器并不关心你在代码中写什么,只要它在语法上是正确的。

I don't think there are any other options.

我认为没有其他选择。

#7


0  

It only takes four lines by using std::fill_n

使用std::fill_n只需要4行

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);

#8


-5  

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

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

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

writetable(数据、“测试”、“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)
}