C++ 如何在不复制数据的情况下在平面数组和多维数组之间进行转换?

C++ 如何在不复制数据的情况下在平面数组和多维数组之间进行转换?,c++,arrays,multidimensional-array,C++,Arrays,Multidimensional Array,我将一些数据结构化为多维数组,即double[][],我需要将其传递给一个函数,该函数需要一个double[]线性数组以及多维表示的多维元数据 例如,我可能有一个3 x 5多维数组,我需要将其作为15个元素的平面数组以及高度和宽度参数传递,以便函数知道它是一个3x5数组而不是5x3数组 然后,该函数将返回一个平面数组和大小元数据,我需要使用它将数据转换回多维类型 我相信对于平面和多维表示,内存中的数据布局是完全相同的;唯一的区别是如何执行索引操作。所以我想用类型转换来进行转换,而不是复制数组值

我将一些数据结构化为多维数组,即double[][],我需要将其传递给一个函数,该函数需要一个double[]线性数组以及多维表示的多维元数据

例如,我可能有一个3 x 5多维数组,我需要将其作为15个元素的平面数组以及高度和宽度参数传递,以便函数知道它是一个3x5数组而不是5x3数组

然后,该函数将返回一个平面数组和大小元数据,我需要使用它将数据转换回多维类型

我相信对于平面和多维表示,内存中的数据布局是完全相同的;唯一的区别是如何执行索引操作。所以我想用类型转换来进行转换,而不是复制数组值

在总大小相同的多维数组和平面数组之间进行类型转换,最正确和可读的方法是什么


我实际上知道多维数组在编译时的维数。数组大小不是动态的。

我认为最常用的方法是:

双*平=&多[0][0]

这是在C中完成的,您可以使用简单的C数组进行操作


您还可以在编译时已知的用例维度中查看std::array,但该维度不是多维的,因此如果将其级联,将丢失连续布局。

我认为最常用的方法是:

双*平=&多[0][0]

这是在C中完成的,您可以使用简单的C数组进行操作

您还可以查看编译时已知的用例维度中的std::array,但该维度不是多维的,因此如果将其级联,将丢失连续布局

在总大小相同的多维数组和平面数组之间进行类型转换,最正确和可读的方法是什么

第一个数组元素的地址与数组的地址一致。您可以传递第一个元素的地址,无需强制转换

在总大小相同的多维数组和平面数组之间进行类型转换,最正确和可读的方法是什么


第一个数组元素的地址与数组的地址一致。您可以传递第一个元素的地址,无需强制转换。

您可以使用强制转换来引用数组。这需要使用一些奇特的C++类型语法,但作为回报,它允许使用所有在数组上工作的特性,比如每个循环。
#include <iostream>

using namespace std;

int main()
{
    static constexpr size_t x = 5, y = 3;
    unsigned multiArray[x][y];
    for (size_t i = 0; i != x; ++i)
        for (size_t j = 0; j != y; ++j)
            multiArray[i][j] = i * j;

    static constexpr size_t z = x * y;
    unsigned (&singleArray)[z] = (unsigned (&)[z])multiArray[0][0];
    for (const unsigned value : singleArray)
        cout << value << ' ';
    cout << endl;

    return 0;
}

考虑到这种方法和其他基于cast的方法只适用于真实的多维数组。如果它是一个数组数组,如无符号**multiArray;,它不是在一个连续的内存块中分配的,转换不能绕过它。

您可以使用转换来引用数组。这需要使用一些奇特的C++类型语法,但作为回报,它允许使用所有在数组上工作的特性,比如每个循环。
#include <iostream>

using namespace std;

int main()
{
    static constexpr size_t x = 5, y = 3;
    unsigned multiArray[x][y];
    for (size_t i = 0; i != x; ++i)
        for (size_t j = 0; j != y; ++j)
            multiArray[i][j] = i * j;

    static constexpr size_t z = x * y;
    unsigned (&singleArray)[z] = (unsigned (&)[z])multiArray[0][0];
    for (const unsigned value : singleArray)
        cout << value << ' ';
    cout << endl;

    return 0;
}
考虑到这种方法和其他基于cast的方法只适用于真实的多维数组。如果它是一个数组数组,如无符号**multiArray;,它不是在一个连续的内存块中分配的,强制转换不能绕过它。

最正确的方法是@Maxim Egorushkin和@ypnos:double*flat=&multi[0][0];。它可以与任何一个好的编译器配合使用。但不幸的是,C++代码无效,调用了未定义的Baavivi.

问题是,对于一个数组,双多[N][M];N和M是编译时contant表达式,&multi[0][0]是大小为M的数组的第一个元素的地址。因此,只对M进行指针运算是合法的。有关更多详细信息,请参见另一个。

最正确的方法是@Maxim Egorushkin和@ypnos:double*flat=&multi[0][0];。它可以与任何一个好的编译器配合使用。但不幸的是,C++代码无效,调用了未定义的Baavivi.


问题是,对于一个数组,双多[N][M];N和M是编译时contant表达式,&multi[0][0]是大小为M的数组的第一个元素的地址。因此,只在M之前进行指针算术是合法的。有关更多详细信息,请参阅另一个。

我认为只需将多维数组视为平面数组就可以了。如果您有双a[5][5],那么a[8]应该返回a[1][3]的值。我认为您可以简单地将多维数组视为平面数组。如果有双a[5][5],则a[8]应返回a[1][3]的值。我需要将其转换回具体的多维数组类型,而不是指针,以便与提供和期望这些类型的外部代码进行互操作。我需要将其转换回具体的多维数组类型,而不是指针,以便进行互操作
带有外部代码的ion,它正在提供和期望这些。多维数组不保证在一个连续的内存块中吗?是的。但根据标准的措辞,这还不足以使其成为一个数组。长话短说,数组必须是一个连续的元素组,但作为一个连续的元素组并不构成一个声明的数组。这很有趣。不过,我想不出这里会出什么差错。我相信,除非他们有充分的理由,否则他们不会写任何符合标准的东西,但也许,这只是一个疏忽。或者他们明确表示这种数组转换是不允许的?好吧,没有任何东西明确指出它是不正确的。简单地说,由于它没有定义,使用它意味着未定义的行为。。。当然,它过去在旧的C代码中很常见,为了不破坏庞大的代码库,编译器仍然接受它。这取决于您是否想在新代码中使用它……多维数组不是保证在一个连续的内存块中吗?是的。但根据标准的措辞,这还不足以使其成为一个数组。长话短说,数组必须是一个连续的元素组,但作为一个连续的元素组并不构成一个声明的数组。这很有趣。不过,我想不出这里会出什么差错。我相信,除非他们有充分的理由,否则他们不会写任何符合标准的东西,但也许,这只是一个疏忽。或者他们明确表示这种数组转换是不允许的?好吧,没有任何东西明确指出它是不正确的。简单地说,由于它没有定义,使用它意味着未定义的行为。。。当然,它过去在旧的C代码中很常见,为了不破坏庞大的代码库,编译器仍然接受它。这取决于你是否想在新代码中使用它。。。