在 C++ 中将静态数组声明为指针

Posted

技术标签:

【中文标题】在 C++ 中将静态数组声明为指针【英文标题】:declare a static array as pointer in c++ 【发布时间】:2017-05-02 20:21:31 【问题描述】:

这是我最近看到的几行 C++ 代码。

double a[p][p];
for(i=0;i<p;i++)

    for(j=0;j<p;j++)
    
        a[i][j] = m[i][j]; //m is sth we are given.
    

dgeev_(&jobvl,&jobvr,&p,(double*)a,&lda,(double*)wr,(double*)wi,(double*)vl,
      &ldvl,(double*)vr,&ldvr,(double*)work,&lwork,&info);
// sth else..

dgeev_ 是一个函数,你可以在这里找到它的文档: http://www.netlib.org/clapack/old/double/dgeev.c

dgeev_在header中以如下方式声明,所以我们可以在C++代码中使用C函数。

extern "C" 
void dgeev_(char*, char*, int*, double*, int*, double*, double*, double*,
 int*, double*, int*, double*, int*, int*);

正如我们所见,a 是静态数组,dgeev_ 需要一个 doublereal * 类型的变量作为第四个参数。

(double*)a 在这里做什么?

【问题讨论】:

正在铸造。如果这令人费解,您手头应该有一个很好的 C 或 C++ 参考资料。这是一个异常长的方法签名,但在结构上并不算太疯狂。 这不是 C++ 代码。它是 C。无论是在风格上还是在现实中。查看文件扩展名。 @WeatherVane:不,因为a 是二维的。演员阵容不仅是获得构建的“必要”;这是错误的。 @W.Yang:那为什么文件叫dgeev.c? C++ 代码未写入名为 .c 的文件中。此外,the project's own FAQ says that it is C code。所以我不确定你为什么声称它是 C++。 @BoundaryImposition 你说得对,dgeev.c 是 C。但是我提供的代码的 sn-ps 是 C++。通过声明C函数extern "C"(在C++代码中),所以我们可以直接在C++中使用C。我认为这对于这个问题可能很重要。 【参考方案1】:

要么是一个错误,要么是作者在捉弄你。

他使用 C 风格的强制转换将值 a“破解”为 double* 类型,因此二维数组可以被视为一维数组。 (doublereal is just an alias for double.)

问题是,a 不是 double*,它实际上也不能转换为 double*。我不知道它 可以转换成什么,因为 VLA 仅在 C++ 中作为 GCC 扩展提供;没有标准的措辞可供参考。我将得出结论,该程序具有未定义的行为(尽管它可能看起来有效,因为这些东西实际上是如何在内存中布置的)。

如果作者希望能够使用一维索引安全地读取这个数组,他应该以这种方式开始声明(可选地在数据存储)。

【讨论】:

评论不用于扩展讨论;这个对话是moved to chat。

以上是关于在 C++ 中将静态数组声明为指针的主要内容,如果未能解决你的问题,请参考以下文章

您可以在 C++ 中将指针声明为 extern 吗?

我们可以在 C++ 中有一个静态类吗?

为啥我不能只用前向声明 C++ 声明一个类的静态成员?

在 Swift 中将静态函数声明为私有时的性能和安全问题

在 C++ 中将指针转换为数组形式的问题?

将线程函数声明为静态函数的问题