我希望在类中包含 static 和常量二维数组。该数组相对较大,但我只想初始化一些元素,而其他元素可能是编译器初始化它们。
例如,如果类被定义为:
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}
};
我只对初始化标有'7'的元素感兴趣,我如何对相同的元素执行此操作,但是使用较大的数组,如array [1024] [1024]?
答案 0 :(得分:31)
初始化的数组中任何超出初始化的部分都被初始化为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
这意味着您必须初始化的所有内容都是最后一个非零:
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}
};
这不是最佳解决方案,但可以节省一些工作。
答案 1 :(得分:7)
初始化后,无法将const数组赋给const数组。所以你必须编写脚本:
以这种方式包含您的文件:
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.
};
答案 2 :(得分:3)
巧合的是,在阅读了你的问题几个小时之后,我在书中寻找其他内容时遇到了一个可能的解决方案"C - A Reference Manual" 5th ed., Harbison/Steele
(顺便说一句,这是一个很棒的C引用)。
根据这本书,
C99允许您命名要在初始化列表中初始化的聚合(结构,联合或数组)的组件。
......它举了一个例子:
int a1[5] = { [2]=100, [1]=3 }; /* eqv. to {0, 3, 100, 0, 0} */
因此,根据编译器的合规性和数组中非零元素的大小,您可以使用此语法有效地初始化矩阵。也就是说,本书没有给出二维数组的例子。不幸的是,我无法测试这个想法,因为MSVC ++ 2005似乎不支持C99。
答案 3 :(得分:1)
当我这样做时,我使用一种方法来读取数据。通常,它看起来像:
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;
}
答案 4 :(得分:0)
您只能通过访问者函数/宏访问数组并安排内部存储,以便初始化部分先行。
答案 5 :(得分:0)
解决方案是在某处隐藏非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;
}
它(IMO)比脚本生成的巨大阵列更具可读性。
你可以用类似2D数组的类做同样的事情(很容易写)。再次 - 在某处使用非const对象,并使用const引用来访问数据。应该很容易使非const数组完全不可见,只有一个cpp。
另一种方法是使用脚本生成数组。如果您认为大数组是丑陋的,请将整个内容放入* .h文件中(确保它只包含在一个* .cpp文件中),这样就不会吓跑人们了。只要语法正确,编译器就不关心你在代码中写的是什么。
我认为没有其他选择。
答案 6 :(得分:0)
使用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);
答案 7 :(得分:-5)
安装R软件,它是免费的! 然后使用
调用下面定义的函数
writetable(data,"test","myfile.h")
如果数据是你的矩阵那么你就完成了
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)
}