如何解决将未知大小的2D数组传递给函数的问题?

时间:2013-03-22 15:54:05

标签: c++ arrays pointers parameter-passing multidimensional-array

我有一个程序,其中对象数组的大小是在运行时确定的,因此它是动态分配的(2D数组,从文件中读取)。我还有一个将这些对象作为参数的函数。问题是如果函数参数是传递给函数的2D数组,则应确定第二维。但是,就我而言,事实并非如此。我的程序将无法编译,因为原型没有提到第二个维度。

以下是我的尝试:

//global variables
int residentCount=0;
int hospitalCount=0;
Resident** residents;
Hospital** hospitals;
bool readFromFiles(const string, const string, const int); //sizes are determined in here
void print(Hospital*[hospitalCount], Resident*[residentCount]); //declaration issue

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

您使用C ++进行编程,因此您应该:
  • 在可能的情况下,始终避免动态分配和处理内存管理
    • 利用具有自动存储持续时间的对象,请点击RAII idiom
  • 避免使用C风格的数组,实际上避免编写一般只能编译为C ++的C代码
    • 使用C ++提供的强大功能,特别是那些捆绑在STL中的功能
  • 当本地等价物足够时,避免使用全局变量

这就是它的样子:

typedef std::vector<Resident> Residents;
typedef std::vector<Hospital> Hospitals;

// passing by const reference:
void print(const std::vector<Hospitals>&, const std::vector<Residents>&);

int main()
{
    std::vector<Hospitals> hospitals;
    std::vector<Residents> residents;
    ...
} // <-- lifetime of automatics declared within main ends here

请注意,hospitalsresidents将是具有自动存储持续时间的对象,可以与C风格的2D数组类似的方式使用。当执行超出main的范围时,这些向量将被破坏,并且内存将自动清除其元素(包括其元素的元素)之前的内存。

另请注意,我建议您传递const引用,即const std::vector<Hospitals>&,这会阻止创建传递对象的副本,并且const关键字明确地告诉调用者:“虽然您通过引用传递此对象,我不会更改它。“

答案 1 :(得分:3)

只需将指针传递给数组的第一个元素和尺寸即可,例如:

void PrintHospitals(Hospital* Hospitals, size_t HospitalRows, size_t HospitalColumns)
{
  size_t i, j;
  Hospital* hospital;

  for (i = 0; i < HospitalRows; i++)
    for (j = 0; j < HospitalColumns; j++)
    {
      hospital = Hospitals + HospitalColumns * i + j;
      PrintHospital(hospital);
    }
}

int main()
{
  Hospital hospitals[10][20];
  // ...
  PrintHospitals(&hospitals[0][0], 10, 20);
  return 0;
}

答案 2 :(得分:0)

这是一个使用模板为现有数据创建二维数组包装器的解决方案:

template<typename T>
class Array2d {
  public:
  int Rows;
  int Cols;
  T** Data;

  Array2d(int rows, int cols, T** data) :
    Rows(rows),
    Cols(cols),
    Data(data) { }
};

void print(Array2d<Hospital> h, Array2d<Resident> r) {
  for (int i = 0; i < h.Rows; i++) {
    for (int j = 0; j < h.Cols; j++) {
      //Print Data[i][j] element here
    }
  }
  // Other print code
}

int main()
{
   Resident** residents;
   Hospital** hospitals;

   //Init data arrays

   Array2d<Hospital> h(10, 10, hospitals);
   Array2d<Resident> r(10, 10, residents);

   print(h, r);
}