无法从’int *’转换为’int ‘?

我知道这可能是一个常见的问题,但我试图搜索但仍然找不到明确的答案。

我有以下代码:

int* f() { int a[] = {1,2,3}; return a; } int main() { int a[] = f(); // Error here getch(); return 0; } 

此代码生成错误消息:“ Cannot convert from 'int *' to 'int []'

我发现这很奇怪,因为我已经读过指针和数组是相似的。 例如,我们可以使用[i]代替*(a + i)。 请问有人给我一个明确的解释吗?

这段代码实际上有两个错误。

首先,您返回临时的地址( f的int数组),因此在函数返回后其内容未定义。 任何尝试访问返回指针指向的内存都将导致未定义的行为。

其次,在C ++中没有从指针到数组类型的隐式转换。 它们相似,但不完全相同。 数组可以衰减到指针,但它不会反过来因为信息在路上丢失 – 指针只代表一个内存地址,而数组代表连续区域的地址,通常具有特定的大小。 您也无法分配给数组。

例如,我们可以用[i]代替*(a + i)

然而,这与数组和指针之间的差异几乎没有关系,它只是指针类型的语法规则。 当数组衰减为指针时,它也适用于数组。

int[]类型实际上并不存在。

定义和初始化数组时

 int a[] = {1,2,3}; 

编译器对初始化程序中的元素进行计数,并创建一个正确大小的数组; 在那种情况下,它神奇地变成:

 int a[3] = {1,2,3}; 

int[]用作函数的参数,相反,它只是简单的int * ,即指向数组第一个元素的指针。 没有其他信息,特别是没有保留大小。 返回指针时也一样

请注意,数组不是指针:指针可以更改为指向其他内容,而数组总是指向同一个内存; 指针不知道它指向的内存空间有多大,而数组的大小在编译时总是知道的。 混淆源于这样一个事实:在许多情况下,数组衰减到指向其第一个元素的指针,并将它传递给函数/从函数返回它是这些情况中的一些。

那么,为什么你的代码不起作用? 有两个大错误:

  1. 您正在尝试使用指针初始化数组。 我们说int *没有任何关于数组大小的信息。 它只是指向第一个元素的指针。 所以编译器不知道应该做多大来容纳f()返回的东西。

  2. f您将返回指向该函数本地变量的指针。 这是错误的,因为指针实际上并不存储数据,它只指向数据存储的位置,即在你的情况下指向f a本地。 因为该数组是函数的本地数组,所以当函数退出时(即return ),它就不再存在。

    这意味着您返回的指针指向不再存在的东西; 考虑代码:

     int * a = f(); 

    这个初始化工作,你可以尝试在函数中使用a晚,但是a将指向不再存在的f数组; 在最好的情况下,你的程序会崩溃(你会立即注意到你做错了什么),最糟糕的情况似乎会工作一段时间,然后开始给出奇怪的结果。

int *和int []相似但不同。 int *是一个实数指针,同时int []是一个数组引用(一种指向数据开头的“常量指针”),它不能被修改。 因此,int *可以像int []一样被威胁,但不能反之。

您可以互换地使用a[b]*(a+b)因为当ab中的一个是指针而另一个是整数或枚举类型时,这正是a[b]的定义方式。

注意:这也意味着42[a]类的表达式是完全合法的。 人类读者可能会强烈反对,但编译器不会盯着这一点。