无法将双精度 [] [] 转换为双精度 **
Cannot convert double [] [] to double **
我有一个函数,它接受 3 个参数,第一个是 **double。
normalizeDataZeroMeanUnitSD(double ** trainingActions, int numberOfTrainingActions, int descriptorDimension)
当我从main调用它时,我正在尝试使用normalizeDataZeroMeanUnitSD(data,681,24);但是,我正在接收
cannot convert parameter 1 from 'double [681][24]' to 'double **'
这就是我构造数据数组的方式:
fstream infile;
infile.open("gabor\Data.txt");
double data[681][24];
while (!infile.eof())
{
for(int j=0;j<681;j++)
{
for(int k=0; k<24;k++)
{
infile >> data[j][k];
}
}
}
infile.close();
有没有办法使用**数据做同样的事情?
错误非常明显:数据类型double [681][24]
与double **
不同。虽然double[681]
确实可以衰减到指向其第一个元素的指针(因此,double*
),但这并不意味着double[681][24]
可以衰减到double**
。
可以这样想:double**
意味着指向许多指针的指针。但是double[][]
没有任何指针。充其量,一个 ANY 维度的数组仍然最多只有一个指针:指向其连续存储的开头。
您可以使用模板:
template<std::size_t M, std::size_t N>
void normalizeDataZeroMeanUnitSD(double (&trainingActions)[M][N], int descriptorDimension)
{
for( std::size_t m = 0; m < M; ++m )
{
for( std::size_t n = 0; n < N; ++n )
{
trainingActions[m][n] = ...;
}
}
}
但是,如果您使用许多不同大小的数组调用它,请注意代码膨胀。
使用以下任何声明。两者是等效的。
NormalizeDataZeroMeanUnitSD(double trainingActions[][24], int numberOfTrainingActions, int descriptorDimension)
NormalizeDataZeroMeanUnitSD(double trainingActions[681][24], int numberOfTrainingActions, int descriptorDimension)
当您声明 2D 数组时,它会占用连续的内存位置。因此,您至少需要指定列数(在行主要体系结构的情况下)。
有关行主定义和列主定义,请查看此内容。
对于您编辑的问题,是的,您可以使用 **data
进行声明。动态分配data
数组。但请记住在完成它后释放它。
double **data=new double*[681];
for (int i=0;i<681;i++)
{
data[i]=new double[24];
}
//do what you want to do
for (int i=0;i<681;i++)
{
delete [] data[i];
}
delete [] data;
现在,您的函数原型可以像void func(double **pp)
一样data
因为它是一个指针而不是一个 2D 数组。
2D 阵列是一个连续的存储区域。该函数需要一个指向指针的指针。这些是不兼容的。
该函数需要一个指向数组的指针数组;你有一个数组数组。一些选项是:
- 将函数更改为更友好的类型,也许
double*
指向连续二维数组的第一个元素;或者 - 构建一个单独的指针数组,指向二维数组的每一行;或
- 将数据重构为指向数组的指针数组。
这是如何使其工作的建设性答案。
基本上,您需要生成一个数组,该数组具有指向 2D 数组的每个 1D 切片的指针。
double data[N][M] = {...};
double *dataPtrs[N];
for(size_t n=0; n<N; ++n) {
dataPtrs[n] = data[n];
}
normalizeDataZeroMeanUnitSD(dataPtrs, N, M); // order of N and M might be wrong
是的,我又要咆哮了。
在C++中,尽管具有相似的语法,但二维数组不是交错数组。 二维数组(double foo[681][24]
)在内存中连续分配。当你尊重一个2D数组(foo[j][i]
)时,它实际上是*(foo+24*i+j)。这一切都是在引擎盖下完成的。sizeof(foo)==sizeof(double)*681*24
.
交错数组是 (double** bar;
)。这是一堆不同的数组:首先,分配一个指针数组,长度为 268 个成员。每个指针将指向一个双精度数组,长度为 24 个元素。酒吧只是一个指针,所以sizeof(bar)==sizeof(void*)
.
更烦人的是,2D 数组(或任何维度的静态数组)的行为与C++中的所有其他类型的相反,在以下保护中:它们通过引用隐式传递,导致下面的奇怪现象。
void foo(double bar[24][24]) { std::cout << sizeof(bar) << std::endl;}
int main() {
double test[24][24];
std::cout << sizeof(test) << std::endl;//returns sizeof(double)*24*24
foo(test);//returns sizeof(void*), implicitly passed by reference, opossite of the rest of c++!
double[][]
与double**
不是一回事。
double**
是指向指针的指针。 double[][]
是分配为连续存储的二维数组。
为了将"二维数组"传递给函数,您需要创建一个指向数组的指针数组。例如:
double* array_2d[681];
for(unsigned int i=0; i<681; ++i) {
array_2d[i] = new double[24];
}
normalizeDataZeroMeanUnitSD(array_2d, 681, 24);
记得稍后删除 array_2d
的每个元素 !
更好的是,更改normalizeDataZeroMeanUnitSD
以引用std::vector<std::vector<double>>
,您不再需要担心内存管理,也不必将正确的维度传递给函数。
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 在 c++ 中从双精度转换为字符串
- 使用 sprintf 和 %g 将双精度转换为字符串的意外结果
- 从双精度转换为整数的显式类型是否始终检查整数溢出?
- C++,遇到将双精度转换为整数的问题
- 在C++中将双精度转换为intptr_t
- 将大双精度转换为科学记数法以用作字符串?
- 了解双精度转换与整数转换中的整数与截断关系
- 将 OLE 自动化日期 (OADate) 双精度转换为结构 tm,而不使用 VariantTime到SystemTime
- 无法在赋值中将"双精度 (*)[4]"转换为"双精度**"
- 将大双精度转换为无符号 int 期间堆栈损坏
- 将双精度转换为本地8位
- 警告从"双精度"转换为"int"
- 如何将双精度转换为浮点指针
- 将双精度转换为整数时出错
- 使用并集将双精度转换为十六进制再转换为双精度
- 是否有可以将每个双精度转换为唯一uint64_t,保持精度和顺序的功能?(为什么我找不到?
- 使用定点表示法将双精度转换为字符串,没有尾随零和机智的冲刺
- 在C++中将双精度转换为字符*/字符串
- 无法将双精度 [] [] 转换为双精度 **