C++ C+;中具有未知数组大小的指针转换+;

C++ C+;中具有未知数组大小的指针转换+;,c++,arrays,pointers,casting,C++,Arrays,Pointers,Casting,当我在编译时不知道数组大小时,如何将void指针转换为2d数组(指向int数组的指针数组)?这有可能吗?(我这样做是因为,我将一个大小未知的2d数组传递给一个func。因此,我将2d数组强制转换为一个空指针,然后在该func中我希望它重铸回来。) int tab1[i][i]是用于可变长度数组的非标准编译器扩展。最好避免这种情况,因为它不像您看到的那样便于携带和处理。你最好是: std::vector<std::vector<int>> tab1(i, std::vect

当我在编译时不知道数组大小时,如何将void指针转换为2d数组(指向int数组的指针数组)?这有可能吗?(我这样做是因为,我将一个大小未知的2d数组传递给一个func。因此,我将2d数组强制转换为一个空指针,然后在该func中我希望它重铸回来。)


int tab1[i][i]
是用于可变长度数组的非标准编译器扩展。最好避免这种情况,因为它不像您看到的那样便于携带和处理。你最好是:

std::vector<std::vector<int>> tab1(i, std::vector<int>(i));
std::vector tab1(i,std::vector(i));
然后你的函数可以简单地取这个向量:

void foo(const std::vector<std::vector<int>>& array) { ....
void foo(const std::vector&array){。。。。

这里的问题是数组的大小必须在编译时定义

在您的情况下,您有多个选项:

  • 使
    i
    a
    constexpr
    类似
    constexpr int i=5;
  • 改用
    int**

    int i = 5;
    
    int tab1[i][i];
    
    //cast to void pointer
    void *p = (void *)tab1;
    // cast to int **
    auto tab1_p = (int **)p;
    // use it like it was an array
    tab1_p[1][3] = 5;
    
当我在编译时不知道数组大小时,如何将void指针转换为2d数组(指向int数组的指针数组)

不能。只能强制转换为编译时已知的类型

您可以做的是转换为指向第一行第一个元素的指针:
int*p=static_cast(tab1);
。然后可以将数组视为一维1。将二维索引转换为一维需要一些简单的数学运算:
x,y->x+y*i



1只要您不介意技术上的问题,即标准可能不允许跨子数组边界的指针算法。但这条规则很愚蠢。如果您关心这一点,那么您应该首先创建一个一维数组。

首先,我建议不要在C/C++中对数组使用运行时大小,除非您可以使用STL向量作为数组。因此,不要:

int i = 5;
您必须使用:

const int i = 5;
除了使用比内在数组更安全和更好的向量

当我在编译时不知道数组的大小时,如何将void指针转换为2d数组(指向int数组的指针数组)?这有可能吗

如果我们谈论C内部数组,这是不可能的

为什么不可能呢? 因为C/C++编译器不知道数组的大小、边界等。因此,如果将2d数组转换为1d数组,这是可能的。这就是tab2数组可以访问数组的前5个元素的原因。实际上,C/C++编译器无法区分

int a[3][3]

因此,您必须至少了解阵列的一个维度:

int main() {
    const int i = 3,j = 4;

    int tab1[i][j] = {1,2,3,4,5,6,7,8,9,10,11};

//cast to void pointer
    void *p = (void *)tab1;

    auto a = (int (*)[i][12/i])p;
    return 0;
}
在上面的例子中,我知道了I和total count(12),并计算了第二个维度。 我使用auto关键字,可以很容易地推断数据类型

<> >代码> int i=5;int Tab1[i] [i];是a。它不是标准C++,应该避免。

  • 指向数组(和向量向量)的指针数组的效率不如真正的2D数组,因为它不再是连续的(
    int tab1[5][5]
    是真正的2D数组,并连续存储在内存中,但在编译时必须知道维度)

  • 您可以轻松创建一个自定义2D容器类,该类将数据存储在连续的1D
    向量中,并应用一些简单的数学(
    x+y*width
    )来访问元素

  • 例如:

    class Matrix {
        std::vector<int> data;
    public:
        const int width;
        const int height;
    
        Matrix(int width, int height) : width(width), height(height), data(width*height) {}
    
        int operator()(int x, int y) const {
            return data[y * width + x];
        }
    
        int& operator()(int x, int y) {
            return data[y * width + x];
        }
    
    };
    
    void print(Matrix const& mat) {
        for (int y = 0; y < mat.height; y++) {
            for (int x = 0; x < mat.width; x++)
                std::cout << mat(x, y) << " ";
            std::cout << std::endl;
        }
    }
    
    int main() {
        Matrix mat(5, 5);
        mat(1, 1) = 1;
        mat(2, 2) = 2;
        mat(3, 3) = 3;
    
        print(mat);
    }
    
    类矩阵{
    std::矢量数据;
    公众:
    常数整数宽度;
    常数int高度;
    矩阵(整数宽度,整数高度):宽度(宽度),高度(高度),数据(宽度*高度){}
    int运算符()(int x,int y)常量{
    返回数据[y*宽度+x];
    }
    int运算符()(int x,int y){
    返回数据[y*宽度+x];
    }
    };
    无效打印(矩阵常数和矩阵){
    对于(int y=0;ystd::当
    i
    不是编译时常量时,您不能
    int tab1[i][i];
    注意
    int tab1[i][i]对C++来说,不是标准的C++,是编译器扩展。对于在运行时确定大小的数组,使用<代码> STD::vector < /代码>不能。你需要想出一个不同的解决方案来解决你原来的问题。还有,一个2D数组(int)。不是指向整数数组的指针数组。它是整数数组数组。这不是一回事。是的,考虑过这一点,但我尝试寻找另一种解决方案,然后是一维数组。谢谢你的答复这看起来像我正在寻找的。谢谢you@DanielŠebík这是错误的。最后一行有未定义的行为原因<代码> Tab1P

    代码>并没有指向一个<代码> int */COD>对象。如果程序幸运,是的,“ErRoka你是对的。我忽略了。听起来不错,但是我试着用基本语言选项来解决它。我会看看那个库,谢谢。这不是某个库,它是C++标准的一部分。任何编译器都给你。C++会为你提供这个。哦,第二个评论是我没有意识到的。谢谢你的注意,我不确定,可能会有介词填充。但是我的意思是一个指针数组。更新。

    int main() {
        const int i = 3,j = 4;
    
        int tab1[i][j] = {1,2,3,4,5,6,7,8,9,10,11};
    
    //cast to void pointer
        void *p = (void *)tab1;
    
        auto a = (int (*)[i][12/i])p;
        return 0;
    }
    
    class Matrix {
        std::vector<int> data;
    public:
        const int width;
        const int height;
    
        Matrix(int width, int height) : width(width), height(height), data(width*height) {}
    
        int operator()(int x, int y) const {
            return data[y * width + x];
        }
    
        int& operator()(int x, int y) {
            return data[y * width + x];
        }
    
    };
    
    void print(Matrix const& mat) {
        for (int y = 0; y < mat.height; y++) {
            for (int x = 0; x < mat.width; x++)
                std::cout << mat(x, y) << " ";
            std::cout << std::endl;
        }
    }
    
    int main() {
        Matrix mat(5, 5);
        mat(1, 1) = 1;
        mat(2, 2) = 2;
        mat(3, 3) = 3;
    
        print(mat);
    }