我只想创建一个2D数组并为其分配值。我该如何解决? (我在评论中提到了错误。)
using namespace std;
class array{
private:
size_t m; //error: invalid use of non-static data member 'array::m'|
size_t n; //error: invalid use of non-static data member 'array::n'|
int array[m][n];
public:
array():m(0),n(0){
}
array(const int &m,const int &n):m(m),n(n){
}
//method set array
void setArray(){
for (size_t row=0;row<m;row++){
for(size_t col=0;col<n;col++){
cin>>array[row][col]; //error: expected primary-expression before '[' token
}
}
}
};
答案 0 :(得分:1)
最简单的方法是使用vector
。
#include <vector>
#include <iostream>
class array {
private:
std::vector<std::vector<int>> array;
public:
array() {
}
array(int m, int n) : array(m, vector<int>(n)) {
}
void setArray() {
for (size_t row = 0; row < array.size(); row++) {
for (size_t col = 0; col < array[row].size(); col++) {
std::cin>>array[row][col];
}
}
}
};
使用向量意味着您不必自己进行动态内存分配,从而使代码更安全,更易读。
答案 1 :(得分:1)
首先,您不应该将数组命名为“ array”,它是保留的类名。其次,在为它们声明值之前,您尝试使用“ m”和“ n”。您应该先为它们声明一个值。希望有帮助。
答案 2 :(得分:0)
在您的程序中,m和n是非常量的,这意味着它们可以在程序的整个生命周期内发生变化。
如果使用array [m] [n]语法声明了一个数组,则m和n必须为const。您在此处有两个选择:使m和n为const,或使数组动态化(可以更改大小)。到目前为止,最简单的方法是使m和n成为常数:
using namespace std;
class array
{
private:
const size_t m = 10;
const size_t n = 10;
int array[m][n];
public:
array() {}
// method set array
void setArray(){
for (size_t row = 0; row < m; row++){
for (size_t col = 0; col < n; col++){
cin>>array[row][col]; //error: expected primary-expression before '[' token
}
}
}
};
使数组动态化需要了解动态内存分配,指针,堆栈和堆以及new和delete运算符。
您为什么不只使用std::vector
或std::vector<std::vector>
以便它可以为您管理这些内容?
答案 3 :(得分:0)
如果m和n是变量,在大多数情况下,您将无法编写
int foo[m][n];
除非m和n是在编译时已知的const
变量,或者您使用具有这种扩展名的Gnu C ++,或者它们可能是模板参数(也有其自身的问题和解决方法)。
进一步阅读:
Array[n] vs Array[10] - Initializing array with variable vs real number
答案 4 :(得分:0)
我在这里假设在编译时无法知道数组的维数。正如John所描述的,“向量的向量”技术基本上是有效的。但是,缺点是必须分配许多单独的存储块,每个基本向量一个。
例如,如果二维整数数组是一个1920x1080位图图像,每个像素一个整数值,则这意味着我们将在对象创建时调用1080次malloc,并且还将释放对象时,调用释放/删除1080次。这可能是非常昂贵的。另外,现有图形库中的许多功能都将坚持每个图像只有一个存储块。
要解决这些问题,我们可以改用单个私有的一维标准向量,并安排访问函数,以便表达式mat [i] [j]仍能按预期工作。最简单的方法是让mat [i]重载,因此它返回行开头的地址。这样,mat [i]指针值自然可以用[j]重新索引。就像常规的std :: vector对象一样,对数组进行的访问也不受范围检查。
该想法在以下代码示例中得以实现:
#include <vector>
#include <iostream>
#include <fstream>
class array2d {
private:
size_t rowCount, colCount;
std::vector<int> vec;
public:
array2d(size_t m, size_t n) : rowCount(m), colCount(n)
{
size_t size = m*n;
vec = std::vector<int>(size, 0);
int* basePtr = vec.data();
for (size_t i=0; i < size; i++)
basePtr[i] = 0;
}
inline size_t getRowCount() { return rowCount; }
inline size_t getColCount() { return colCount; }
inline int* operator[](size_t rowId) // HERE !
{
// NOT range-checked just like std::vector
return (vec.data() + (rowId*(this->colCount)));
}
void setArrayFromFile(std::istream& file) {
for (size_t row = 0; row < rowCount; row++) {
int* rowStart = (*this)[row];
for (size_t col = 0; col < colCount; col++) {
file >> rowStart[col];
}
}
}
// specialized version to read from standard input:
void setArray()
{
setArrayFromFile(std::cin);
}
};
//---------------------------------------------------------
// EXAMPLE OF USE:
void printIntegerMatrix(array2d& matrix)
{
size_t rowCount = matrix.getRowCount();
size_t colCount = matrix.getColCount();
for (size_t row = 0; row < rowCount; row++) {
for (size_t col = 0; col < colCount; col++) {
std::cout << matrix[row][col] << " ";
}
std::cout << std::endl;
}
}
void processIntegerMatrix(array2d& matrix, const std::string& fileName)
{
// fill in matrix from a text file then print its contents on stdout:
std::ifstream inputStream{fileName};
if (!inputStream) {
std::cerr << " Cannot open file " << fileName << std::endl;
exit(EXIT_FAILURE);
}
matrix.setArrayFromFile(inputStream);
inputStream.close();
std::cerr << "After reading from file." << std::endl;
printIntegerMatrix(matrix);
}
int main(int argc, const char* argv[])
{
size_t rowCount = 3;
size_t colCount = 6;
// have a text file with some numbers in it:
std::string fileName{"numbers1.dat"};
std::cout << "matrix size: " << rowCount << 'x' << colCount << std::endl;
// create zero-filled matrix:
array2d mat1(rowCount, colCount);
processIntegerMatrix(mat1, fileName);
return EXIT_SUCCESS;
}