2013-05-06 90 views
0

我试图声明一个指向二维浮点矩阵的指针,以便获得我的图像数据的动态行为,但是Im有一个编译错误C2057:预期的常量表达式。我认为一个指针必须以这种方式铸造,但显然不是。请任何人都可以帮助我?谢谢!!如何声明一个指向2d浮点矩阵的指针?

//Image size input 

int imheight; 
int imwidth; 

cout << "Please, enter image height: \n>"; 
scanf ("%d",&imheight); 
cout << "Please, enter image width: \n>"; 
scanf ("%d",&imheight); 

const int imheight2 = imheight; 
const int imwidth2 = imwidth; 

float *zArray[imheight2][imwidth2]; 

这是我的其他功能之一,我试图hace访问zArray。我不是获取数据正确读出:

void LoadRIS(char* inputFileName , float** zArray, int imageHeight , int imageWidth){ 

    // Load input RIS file 
FILE* lRis = fopen (inputFileName, "rb"); 

// Jump to data position 
for (int i = 0; i < 88; i++){  
    uchar a = getc (lRis); 
} 

// Read z array 
size_t counter = fread (*zArray , 1 , imageHeight * imageWidth * sizeof(zArray) , lRis); 

//Get max value of RIS 
float RISmax = zArray [0][0]; 
float RISmin = zArray [0][0]; 
for (int i=0; i<imageHeight; i++) 
{ 
    for (int j=0; j<imageWidth; j++) 
     { 
      if (zArray[i][j] > RISmax) 
      RISmax = zArray [i][j]; 
      if (zArray[i][j] < RISmin) 
      RISmin = zArray [i][j]; 
     } 
} 
std::cout<<"The max value of the RIS file is: "<<RISmax<<"\n"; 
std::cout<<"The min value of the RIS file is: "<<RISmin<<"\n"; 
Beep(0,5000); 


// Close input file 
fclose (lRis); 

}

+0

除了回答说些什么,该类型是指针的二维数组,而不是一个指向二维数组的指针。你会想'float(* zArray)[imheight2] [imwidth2];'。 – 2013-05-06 10:11:24

+0

这个问题被标记为C和C++,但答案是不同的。 C支持可变长度数组已经有一段时间了,所以小的可变长度数组可以并且应该用'float foo [r] [c];'定义。其中一个标签应该被删除。 – 2013-05-06 11:43:37

回答

0

尝试此(动态分配)

//Image size input 

int imheight; 
int imwidth; 

cout << "Please, enter image height: \n>"; 
scanf ("%d",&imheight); 
cout << "Please, enter image width: \n>"; 
scanf ("%d",&imwidth); 

float** zArray = new float*[imheight]; 
for(int i=0;i<imheight;i++){ 
    zArray[i] = new float[imwidth]; 
} 

当然,你需要释放分配:

for(int i=0;i<imheight;i++){ 
    delete[] zArray[i]; 
} 
delete[] zArray; 

希望这有助于:)

附:正如@FrankH所说,这称为太多new s和delete s,浪费了很多时间。更好的想法应该是一起分配imwidth * imheight空间。

+0

工作很好,谢谢!顺便说一下,我如何从另一个函数访问双指针float **的值?它崩溃了 – Nicolai 2013-05-07 08:54:44

+0

@Nicolai你的意思是访问2d数组中的值?只需使用zArray [i] [j]即可。我想知道整个代码,你能编辑这个问题并粘贴你的'另一个函数'代码吗? – hongtao 2013-05-07 09:54:17

+0

嗨洪涛,只是在问题中贴了一个函数。我现在没有崩溃,但我无法正确读取文件并将其加载到我的zArray – Nicolai 2013-05-07 11:08:23

2
const int imheight2 = imheight; 
const int imwidth2 = imwidth; 

它不会使常量表达式。你不能用这样的边界创建数组。您应该使用dynamic-allocationvector

2

问题是您声明了2 const int变量,但您并未指定它们的const值。 imheightimwidth不是恒定的。

如果你罚款STL:

std::vector<std::valarray<float> > floatMatrix; 

编辑:只是为了您的信息,我在上面的代码行放在>之间的空间没有任何与我的编码风格。您的编译器可能会假设>>是正确的移位运算符而不是2个模板参数列表结束符。 Angew的评论总结如下。

+1

“>>”的“旧”解释不是一个错误,C++ 03是这样定义的(尽管许多编译器支持将'>>'作为扩展名)。第一个C++ 11使得这个解析是合法的,所以现在编译器必须在适用时将'>>'理解为模板终结符。 – Angew 2013-05-06 10:18:33

+1

看到它应该是一个矩阵,我会考虑'std :: valarray'而不是'std :: vector'。 – Angew 2013-05-06 10:19:49

+0

我想我可以将最后一条语句改写为更一般,这样我就可以避免误报任何人 – 2013-05-06 10:20:40

0

您不能使用具有动态大小的数组(您的宽度和高度变量不是编译时间常量)。

您可以使用malloc()或new运算符以动态方式分配内存。

+0

你说得对,但我认为Nicolai很可能使用C++,因为变长数组不会导致C中的编译器错误C2057。因此,这个问题的答案是正确的。 – Pixelchemist 2013-05-06 12:17:53

+0

那cplusplus。com引用是不好的...即使代码示例是buggy('FreeDynamicArray'泄漏'(nRows-1)* nCols'单元的'T')。在C/C++中使用'dynamic multidimensional arrays'是不对的。坚持'std :: vector'和/或使用/实现一个合适的'matrix'类 - 用'operator(int,int)'而不是'[] []'。 – 2013-05-08 00:03:05

+0

你的网站确实是对的。我会删除链接,因为此功能可能会让人们感到困惑。但是:由于我们得到了STL,所以没有人应该了解如何使用动态内存? :X每个人都使用C++(特别是在使用C时)当然应该知道如何处理一维或多维数组!即使你(尽力)避免在你自己的代码中使用它,你迟早会被要求知道这些东西。 – Pixelchemist 2013-05-08 09:26:46

-1

float *pMatrix = new float[imheight2*imwidth2];

这样

float f = pMatrix[x*y];

+1

我想你的意思是'y * width + x' – 2013-05-06 10:29:15

2

代替float *zArray[imheight2][imwidth2]; 然后访问元素应该是:

float **zArray = new float*[imheight2]; 

for(int i=0; i<imheight2; i++) 
{ 
    zArray[i] = new float[imwidth2]; 
} 
1

如果要做到这一点,那么至少为它编写代码:

float **zArray = new float*[imheight]; 
float *tmp = new float[imheight*imwidth]; 

for(int i=0; i<imheight; i++, tmp += imwidth) 
    zArray[i] = tmp; 

... 
delete[] *zArray; 
delete[] zArray; 

这至少避免了做两个以上的new/delete[]电话。并且它保留了fread(*zArray, ...)的功能,如果内存不是连续的,那么会中断(如果通过多个new调用初始化它,通常不会发生)。

一个适当的包装类会做一个new/malloc,如:

template <class T> class Array2D { 
private: 
    size_t m_x; 
    T* val; 
public: 
    Array2D(size_t x, size_t y) : 
     m_x(x)), 
     val(new T[x*y]) {} 
    ~Array2D() { delete[] val; } 
    T* operator[](size_t y) { return val + y*m_x; } 
} 

你还是这样的实例不能分配给float**。它仍然在堆上分配,普通的常量维数组可以放在堆栈上。 float**的额外分配的唯一优点是您不必使用乘法操作 - 而是使用单独的内存访问;该类型的行为可以被模板化/引入包装类。

一般地,我更想要的multidimensional arrays are evil侧面(另见https://stackoverflow.com/a/14276070/512360,或C++ FAQ, 16.16),但口味也不尽相同......