返回指向int数组的指针的函数

4

我正在学习第五版的C++ Primer,目前正在学习有关返回数组指针的内容。该函数的声明如下:

 int (*func(int i))[10]; 

预计返回一个数组指针。

我编写了以下代码:

#include <iostream>
#include <string>
using namespace std;

int *func(){
  static int a[]={1,2,3};
  return a;
}
int main (){
  int *p=func();
  for(int i=0;i!=3;++i){
    cout<<*(p+i);
  }
}

它正在起作用。但我想知道我所做的这个与之间的区别。

  int (*func(int i))[10]; 

我该如何使这个函数调用起来?因为在书中,没有任何具体的例子。

1
我认为你可能会混淆a数组名、int*和数组地址&aint(*)[5]的区别。阅读链接中的回答可能会对你有所帮助。 - Grijesh Chauhan
4
@jrok:这个问题比其他的问题好,我不知道为什么要关闭它,因为它表达得很清楚(嗯,在这个网站的质量平均水平上,我会这样说)。 - David Rodríguez - dribeas
1
你正在返回第一个元素的地址。实际上,a 的类型是 int[3],它会衰减为 int*。重要的是,你将地址存储在 int* p 中,并且可以使用 p[i] 访问数组的元素。而如果你的函数是 int (*func(int i))[3],那么你将返回 &a 并分配给 int(*p)[3],并且可以访问 (*p)[i] - Grijesh Chauhan
1
@alin,请让我知道我的回答是否有帮助,如果对我的回答有疑问,请随时提问。 - Grijesh Chauhan
1
@alin(1)请在回答中发表评论,而不是在问题中发表评论(否则会使其他人感到困惑)。 (2)我无法理解您的问题-但是如果您仅声明数组int a [] = {1, 3, 3}而不使用static关键字,则会变成有错误的代码。因为本地数组的生命周期和范围只存在于函数返回之前。 - Grijesh Chauhan
显示剩余8条评论
2个回答

3

阅读什么是sizeof(&array)返回?以了解“数组名称”和“数组地址”的区别。

Q1 我想知道以下内容的区别:

在您的代码中:

  int *func(){
    static int a[]={1,2,3};
    return a;
  }

你正在返回第一个元素的地址。实际上,a 的类型是 int[3],它会退化为 int*。重要的是,你将地址存储在 int* p 中,可以通过 p[i] 访问数组的元素。

然而,如果你的函数是 int int (*func())[3],那么你将返回 &a,并赋值给 int(*p)[3],可以访问 (*p)[i]
注意: &a 的类型是 int(*)[3]

Q2 我该如何使这个函数调用起来?因为在书中没有任何具体的例子。

例如:

int (*func())[3]{
    static int a[]={1,2,3};
    return &a;
}

并且主函数:

int main(){ 
 int i=0;    
 int(*p)[3] = func();
 for(i=0; i<3; i++)
   printf(" %d\n", (*p)[i]);
 return 0;
}

您可以在Ideone上查看代码的第二个版本运行情况。 问题1:我想知道以下两种声明之间的区别:
由于您想了解两者之间的差异,现在请比较两个版本的p的不同声明方式: 1) : int* p;,我们通过p[i]访问数组元素,这等同于*(p + i)2) : int (*p)[i],我们通过(*p)[i]访问数组元素,这等同于*((*p) + i)*(*p + i)。(我在*p周围添加了()来访问数组元素,因为[]运算符的优先级高于*,所以简单的*p[i]意味着对数组元素的保护)。 编辑: 除了返回类型之外,还有其他补充信息:
在两种函数中,我们都返回一个静态变量(数组)的地址,静态对象的生命周期是在程序终止前。因此,在func()之外访问数组不是问题。
如果您返回非静态(和动态分配的)简单数组(或变量)的地址,则会在代码中引入未定义行为,可能会导致崩溃。

非常感谢您的回答,它帮助了我,最终我也理解了。但我还有一个问题,如何通过静态整数a[]进行转义?所以,我想从int main()或任何地方返回一个数组。 - alin
1
@alin 看到了吗,main()函数与其他函数非常不同,它的声明是预定义的,你不能创建一个返回数组指针的main()函数。它的返回类型只能是int。 - Grijesh Chauhan
抱歉 @ Grijesh chauhan,但是当我“发现”这个功能(接受一个答案)时,我会全部接受,并且首先是您的回答,但是当我接受任何回答时,您的回答被取消了接受。对不起,我接受了您的回答。 - alin
@alin 没问题,你可以投票给所有人,但只能接受一个,原因是什么?我给你点赞了。 - Grijesh Chauhan
@GrijeshChauhan 我正在阅读你的答案,然后我想尝试你的第二和第三个代码,但我无法编译它(它告诉我从函数/方法/块返回'int[3]'返回'int[3]*':数组不可分配)。 - Mohammad Abdollahzadeh

2

int(*)[10] 是指向一个包含 10 个 int 的数组的指针。 int* 是指向 int 的指针。这些是不同的类型。

然而,一个数组会 衰变 成为指向其第一个元素的指针,所以你可以这样做:

int a[10];
int(*p)[10] = &a;
int* q = a; // decay of int[10] to int*

但不是:

q = p;
p = q;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接