C++ 指定指向二维数组的指针
如果我声明一个2D数组C++ 指定指向二维数组的指针,c++,arrays,pointers,C++,Arrays,Pointers,如果我声明一个2D数组 int A[sz][sz]; 如何创建指向此对象的指针 我之所以这样做,是因为我想通过指向函数指针int**的指针返回一个数组,但我想在事先不知道数组大小的情况下构建数组。大小将作为参数传递。我想知道是否有一种不使用动态分配的方法可以做到这一点 问题是,如果我在函数中执行类似于int**A的操作,这将不会提供A有关所需大小的信息 如果该数组是二维数组,如何创建该数组并为其分配指针 我应该更清楚。我想返回一个指向指针的指针,这样它就不会是指向2D数组的指针,而是一个类似i
int A[sz][sz];
如何创建指向此对象的指针
我之所以这样做,是因为我想通过指向函数指针int**
的指针返回一个数组,但我想在事先不知道数组大小的情况下构建数组。大小将作为参数传递。我想知道是否有一种不使用动态分配的方法可以做到这一点
问题是,如果我在函数中执行类似于int**A
的操作,这将不会提供A
有关所需大小的信息
如果该数组是二维数组,如何创建该数组并为其分配指针
我应该更清楚。我想返回一个指向指针的指针,这样它就不会是指向2D数组的指针,而是一个类似
int**的指针。你的问题是,格式为int**
的2D数组需要一个int*
的数组来进行两步解引用,而当你用int[sz][sz]声明数组时,这个数组根本不存在代码>
您可以像这样自己构建它:
int* pointers[sz];
for(size_t i = sz; i--; ) pointers[i] = A[i];
这似乎很荒谬,但根源在于C处理数组的方式:A[i]
的类型是int()[sz]
,它是行i
的子数组。但当您在赋值中使用该数组时,它会衰减为指向该子数组中第一个元素的指针,该子数组的类型为int*
。在循环之后,A
和指针
是两个截然不同的东西(A
的类型是int()[sz][sz]
)
旁注:你说你想从函数返回这个。如果在堆栈上分配了数组,则不能返回指向其数据的指针,该指针将在函数返回时消失。您只能返回指向具有静态
存储或是另一个现有对象的一部分的对象的指针/引用。如果您未能遵守这一点,则可能会导致堆栈损坏
编辑:
关于C的一个鲜为人知的事实是,实际上可以传递指向真实C数组的指针,而不仅仅是数组衰减到的指针类型。下面是一个小程序来演示这一点:
#include <stddef.h>
#include <stdio.h>
int (*foo(int size, int (*bar)[size][size], int y))[] {
return &(*bar)[y];
}
int main() {
int mySize = 30;
int baz[mySize][mySize];
int (*result)[mySize];
result = foo(mySize, &baz, 15);
printf("%ld\n", (size_t)result - (size_t)baz);
}
#包括
#包括
int(*foo(int-size,int(*bar)[size][size],int-y])[]{
返回(*条)[y];
}
int main(){
int mySize=30;
int baz[mySize][mySize];
int(*结果)[mySize];
结果=foo(mySize和baz,15);
printf(“%ld\n”,(size\t)结果-(size\t)baz);
}
该示例程序的预期输出为1800。重要的是数组的实际大小必须是已知的,要么是编译时常量,要么是与数组指针一起传递(如果它与数组指针一起传递,则size参数必须出现在数组指针之前)。让我把你的问题具体化一点。你提到:
我问这个问题是因为我想从函数返回数组[…],但我
希望在事先不知道大小的情况下构建阵列。大小
将作为参数传递。我想知道有没有办法
这不需要使用动态分配
对于我希望从作为参数传递的函数[…]size返回数组的例子,我认为可以在任何地方使用std::vector
,并在需要访问基础数组(保证是连续的)时调用其.data()
方法。例如:
std:vector<double> myfun(size_t N) {
std::vector<double> r(N);
// fill r[0], r[1], ..., r[N-1]
return r;
}
// later on:
r.data(); // gives you a pointer to the underlying double[N]
一般来说,我会使用一个能够处理任意容器的模板函数:
template<typename T>
void myfun(T& data) {
for(int k=0; k<data.size(); k++) {
// do stuff to data[k]
}
}
// call as, for example:
std::vector<double> data(10);
myfun(data);
// or equally valid:
std::array<double, 10> data;
myfun(data);
然后您可以通过调用数据[i*ncols+j]
来引用矩阵的元素(i,j)
。例如:考虑一个三乘四的矩阵:
a b c d
e f g h
i j k l
元素(2,2)
(即:第三行,第三列,因为我们假设基于零的C型索引)计算为:M[2][2]=M[2*4+2]=M[10]=k
。这种情况是因为它存储为:
[a b c d e f g h i j k l]
[0 1 2 3 4 5 6 7 8 9 10 11]
而k
是索引为10
的元素。对你的问题的回答很奇怪。只要这样做:
int A[2][2];
int**p =NULL;
*p = A[0]; // **p==A[0][0] , *(*p+1)==A[0][1]
&A
是指向此对象的指针,但可能不是您想要的。我尝试了int**L=&(&A)
,但我收到一个错误,说它不是左值。没错&A是指针,它是右值。我认为除非声明一个“Array2D”类,否则没有办法。但是在类的实现中,仍然存在动态分配。我尝试了这个方法,但由于您提到的原因,我得到了一个错误。
[a b c d e f g h i j k l]
[0 1 2 3 4 5 6 7 8 9 10 11]
int A[2][2];
int**p =NULL;
*p = A[0]; // **p==A[0][0] , *(*p+1)==A[0][1]