我是C ++编程的新手,所以我需要有关2D数组的帮助。是否有可能从两个真正的数组创建复杂的数组与两个for循环?我试图在我的代码中这样做,但...我不知道该怎么做。 感谢帮助! 这是我的代码::
#include <iostream>
#include <fstream>
#include <complex>
#include <cmath>
using namespace std;
int const BrGr = 15, BrCv = BrGr + 1, BrSat = 24;
//(BrCv=number of nodes,BrSat=number of hours)
int main()
{
// Every array must be dynamic array.It is a task.Is this correct way?
auto *Ipot = new double[BrCv - 1][BrSat];
auto *cosfi = new double[BrCv - 1][BrSat];
auto *S_pot = new complex<double>[BrCv - 1][BrSat];
auto *I_inj = new complex<double>[BrCv - 1][BrSat];
auto *V_cvo = new complex<double>[BrCv][BrSat];
ifstream reader("Input.txt");
if (reader.is_open())
{
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
reader >> Ipot[i][j];
}
}
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
reader >> cosfi[i][j];
}
}
}
else cout << "Error!" << endl;
reader.close();
// Here i want to create 2D array of complex numbers - Is this correct way?
// Also in same proces i want to calculate a value of S_pot in every node for every hour
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
S_pot[i][j] = complex<double>(Ipot[i][j]*cosfi[i][j],Ipot[i][j]*sqr(1-pow(cosfi[i][j],2)));
}
}
// Here i give a value for V_cvo in nodes for every single hour
for (int i = 0;i < BrCv;i++)
{
for (int j = 0;j < BrSat;j++)
{
V_cvo[i][j] = 1;
}
}
// Here i want to calculate a value of I_inj in every node for every hour
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
I_inj[i][j] = conj(S_pot[i][j] / V_cvo[i][j]);
}
}
// Here i want to delete all arrays
delete[] Ipot, cosfi, S_pot, I_inj, V_cvo;
system("pause");
return 0;
答案 0 :(得分:4)
注意:我在这些示例中使用了double,但您可以用任何类型替换double。
老实说,你可能不想使用2D数组。
在C ++中创建2D动态大小的数组是一个多阶段操作。你不能只是
double twoDArray [nrRows][nrColumns];
或
auto twoDArray = new double[nrRows][nrColumns];
这有几个问题,但最重要的是行和列不是常量,在编译时定义值。有些编译器允许第一个,但这不能保证。我不知道是否有任何编译器允许第二个。
相反,首先创建一个行数组来保存列,然后分别创建每一列。呸。
这是设置:
double * arr[] = new double*[nrRows]; // create rows to point at columns
for (size_t index = 0; index < nrRows; index++)
{
arr[index] = new double[nrColumns]; // create columns
}
这是清理
for (size_t index = 0; index < nrRows; index++)
{
delete[] arr[index]; // delete all columns
}
delete[] arr; // delete rows
对于你的努力,你会得到糟糕的spacial locality和性能命中(Cache miss),因为你的许多数组可能在RAM中的任何位置,并且你会遇到糟糕的内存管理问题。一个搞砸,一个意外的例外,你有内存泄漏。
下一个选项具有更好的局部性,因为有一个大数据数组可以读取而不是很多,但仍然存在相同的泄漏问题。
double * arr2[] = new double*[nrRows]; // create rows to point at columns
double holder[] = new double[nrRows* nrColumns]; // create all columns at once
for (size_t index = 0; index < nrRows; index++)
{
arr[index] = &holder[index * nrColumns]; // attach columns to rows
}
并清理:
delete[] arr2;
delete[] holder;
在C ++中,理智的人选择std :: vector而不是动态大小的数组,除非非常明确地给出 非常 令人信服的理由。为什么在整个SO和整个互联网上都记录了死亡事件,并证明互联网上有被劫持的计算机可能会堆积垃圾邮件和其他肮脏的东西。
std::vector<std::vector<double>> vec(nrRows, std::vector<double>(nrColumns));
用法正是阵列用户习惯的用途:
vec[i][j] = somevalue;
这实际上没有内存问题,但又回到了糟糕的地方,因为矢量可以在任何地方。
但是...!
还有一种更好的方法:使用One Dimensional数组并将其包装在一个简单的类中,使其看起来像2D。
template <class TYPE>
class TwoDee
{
private:
size_t mNrRows;
size_t mNrColumns;
vector<TYPE> vec;
public:
TwoDee(size_t nrRows, size_t nrColumns):
mNrRows(nrRows), mNrColumns(nrColumns), vec(mNrRows*mNrColumns)
{
}
TYPE & operator()(size_t row, size_t column)
{
return vec[row* mNrColumns + column];
}
TYPE operator()(size_t row, size_t column) const
{
return vec[row* mNrColumns + column];
}
};
这个小小的野兽将完成你需要2D矢量的大部分工作。你可以复制它,你可以移动它。你可以随心所欲。 Jay Leno会做更多。
我直接跳到模板版本,因为我很难理解两次解释TwoDee课程。
构造函数很简单。你给它数组的尺寸,它构建一个漂亮,安全的1D向量。没有麻烦,没有大惊小怪,也不需要Zayn。
operator()函数获取行索引和列索引,执行一个简单的算术运算将索引转换为单个索引,然后返回对索引值的引用以允许修改或索引值的副本不变的情况。
如果您觉得需要额外的安全性,请添加范围检查。
TYPE & operator()(size_t row, size_t column)
{
if (row < mNrRows && column < mNrColumns)
{
return vec[row* mNrColumns + column];
}
throw std::out_of_range("Bad indices");
}
行。 OP如何使用它?
TwoDee<complex<double>> spot(BrCv - 1, BrSat);
创建并准备好了。加载它:
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
Spot(i,j) = complex<double>(7.8*Ipot(i,j),2.3*cosfi(i,j));
}
}
答案 1 :(得分:3)
为premitive类型声明动态2D数组与std::complex<T>
相同。
锯齿状阵列:
complex<int> **ary = new complex<int>*[sizeY];
//run loop to initialize
for (int i = 0; i < sizeY; ++i)
{
ary[i] = new complex<int>[sizeX];
}
//clean up (you could wrap this in a class and write this in its destructor)
for (int i = 0; i < sizeY; ++i)
{
delete[] ary[i];
}
delete[] ary;
//access with
ary[i][j];
//assign index with
ary[i][j] = complex<int>(int,int);
它的重量比它需要的重一点,它分配的块比你需要的多。 多维数组只需要一个内存块,每行不需要一个块。
矩形阵列:
complex<int> *ary = new complex<int>[sizeX * sizeY];
//access with:
ary[y*sizeX + x]
//assign with
ary[y*sizeX+x] = complex<int>(int,int);
//clean up
delete[] ary;
分配一个连续的块是要走的路(对分配器的影响较小,更好的位置等等)但是你必须牺牲干净和好的下载。