Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指定指向二维数组的指针_C++_Arrays_Pointers - Fatal编程技术网

C++ 指定指向二维数组的指针

C++ 指定指向二维数组的指针,c++,arrays,pointers,C++,Arrays,Pointers,如果我声明一个2D数组 int A[sz][sz]; 如何创建指向此对象的指针 我之所以这样做,是因为我想通过指向函数指针int**的指针返回一个数组,但我想在事先不知道数组大小的情况下构建数组。大小将作为参数传递。我想知道是否有一种不使用动态分配的方法可以做到这一点 问题是,如果我在函数中执行类似于int**A的操作,这将不会提供A有关所需大小的信息 如果该数组是二维数组,如何创建该数组并为其分配指针 我应该更清楚。我想返回一个指向指针的指针,这样它就不会是指向2D数组的指针,而是一个类似i

如果我声明一个2D数组

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]