C++ 无法从“int *”转换为“int []”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6493185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cannot convert from 'int *' to 'int []'?
提问by ipkiss
I know this might be a common question but I have tried to search but still cannot find a clear answer.
我知道这可能是一个常见问题,但我已经尝试搜索,但仍然找不到明确的答案。
I have the following code:
我有以下代码:
int* f() {
int a[] = {1,2,3};
return a;
}
int main() {
int a[] = f(); // Error here
getch();
return 0;
}
This code produces the error message: "Cannot convert from 'int *' to 'int []'
"
此代码产生错误消息:“ Cannot convert from 'int *' to 'int []'
”
I found this quite strange because I have read that pointer and array are similar. For example, we can use a[i] instead of *(a + i). Can anyone give me a clear explanation, please?
我发现这很奇怪,因为我读过指针和数组是相似的。例如,我们可以使用 a[i] 而不是 *(a + i)。谁能给我一个清楚的解释,好吗?
回答by Alexander Gessler
There are actually two errors in this code.
这段代码实际上有两个错误。
Firstly, you are returning the address of a temporary (the int array within f
), so its contents are undefined after the function returns. Any attempt to access the memory pointed to by the returned pointer will cause undefined behaviour.
首先,您要返回临时地址( 中的 int 数组f
),因此在函数返回后其内容未定义。任何试图访问由返回的指针指向的内存都会导致未定义的行为。
Secondly, there is no implicit conversion from pointers to array types in C++. They are similar, but not identical. Arrays can decay to pointers, but it doesn't work the other way round as information is lost on the way - a pointer just represents a memory address, while an array represents the address of a continuous region, typically with a particular size. Also you can't assign to arrays.
其次,在 C++ 中没有从指针到数组类型的隐式转换。它们相似,但不完全相同。数组可以衰减为指针,但它不会反过来工作,因为信息在途中丢失 - 指针仅表示内存地址,而数组表示连续区域的地址,通常具有特定大小。你也不能分配给数组。
For example, we can use a[i] instead of *(a + i)
例如,我们可以使用 a[i] 而不是 *(a + i)
This, however, has little to do with the differences between arrays and pointers, it's just a syntactic rule for pointer types. As arrays decay to pointers, it works for arrays as well.
然而,这与数组和指针之间的区别关系不大,它只是指针类型的语法规则。随着数组衰减为指针,它也适用于数组。
回答by Matteo Italia
The type int[]
doesn't actually exist.
该类型int[]
实际上不存在。
When you define and initialize an array like
当你定义和初始化一个数组时
int a[] = {1,2,3};
the compiler counts the elements in the initializer and creates an array of the right size; in that case, it magically becomes:
编译器计算初始化器中的元素并创建一个大小合适的数组;在这种情况下,它神奇地变成:
int a[3] = {1,2,3};
int[]
used as a parameter to a function, instead, it's just plain int *
, i.e. a pointer to the first element of the array. No other information is carried with it, in particular nothing about the size is preserved. The same holds when you return a pointer
int[]
用作函数的参数,相反,它只是普通的int *
,即指向数组第一个元素的指针。它没有携带其他信息,特别是没有保留任何有关大小的信息。返回指针时也是如此
Notice that an array is nota pointer: a pointer can be changed to point to other stuff, while an array refers always to the same memory; a pointer does not know anything about how big is the space of memory it points to, while the size of an array is always known at compile time. The confusion arises from the fact that an array decaysto a pointer to its first element in many circumstances, and passing it to a function/returning it from a function are some of these circumstances.
请注意,数组不是指针:指针可以更改为指向其他内容,而数组始终指向相同的内存;指针不知道它指向的内存空间有多大,而数组的大小在编译时总是已知的。混淆源于这样一个事实,即在许多情况下,数组衰减为指向其第一个元素的指针,并将其传递给函数/从函数返回它是其中一些情况。
So, why doesn't your code work? There are two big errors:
那么,为什么您的代码不起作用?有两个大错误:
You are trying to initialize an array with a pointer. We said that an
int *
doesn't carry any information about the sizeof the array. It's just a pointer to the first element. So the compiler cannot know how biga
should be made to accomodate the stuff returned byf()
.In
f
you are returning a pointer to a variable that is local to that function. This is wrong, because a pointer does not actually store the data, it only pointsto where the data is stored, i.e. in your case to thea
local tof
. Because that array is localto the function, it ceases to exist when the function exits (i.e. at thereturn
).This means that the pointer you are returning points to stuff that does not exist anymore; consider the code:
int * a = f();
This initialization works, and you can try to use
a
later in the function, buta
will be pointing to the no-longer existent array off
; in the best case your program will crash (and you'll notice immediately that you've done something wrong), in the worst it will seem to work for some time, and then start giving strange results.
您正在尝试使用指针初始化数组。我们说过 an
int *
不携带有关数组大小的任何信息。它只是一个指向第一个元素的指针。所以编译器不知道a
应该做多大来容纳f()
.在
f
您返回一个指向该函数局部变量的指针。这是错误的,因为指针实际上并不存储数据,它仅指向存储数据的位置,即在您的情况下指向a
本地 tof
。因为该数组是函数的局部数组,所以当函数退出时(即在 处return
)它就不再存在了。这意味着您返回的指针指向不再存在的东西;考虑代码:
int * a = f();
此初始化工作,您可以尝试
a
在函数稍后使用,但a
将指向不再存在的f
;数组。在最好的情况下你的程序会崩溃(你会立即注意到你做错了什么),在最坏的情况下它似乎会工作一段时间,然后开始给出奇怪的结果。
回答by Heisenbug
int * and int [] are similar but different. int * is a real pointer, meanwhile int[] is an array reference ( a sort of "constant pointer" to the begin of the data) wich cannot be modified. So, a int * can be threated like a int [] but not viceversa.
int * 和 int [] 相似但不同。int * 是一个真正的指针,同时 int[] 是一个无法修改的数组引用(一种指向数据开头的“常量指针”)。因此, int * 可以像 int [] 一样受到威胁,但反之则不然。
回答by David Hammen
You can use a[b]
and*(a+b)
interchangeably because that is exactly how a[b]
is defined when one of a
or b
is a pointer and the other is of integer or enumeration type.
您可以使用a[b]
and*(a+b)
互换,因为a[b]
当a
或b
中的一个是指针而另一个是整数或枚举类型时,这正是定义的方式。
Note: This also means that expressions like 42[a]
are perfectly legal. Human readers might object strongly, but the compiler won't bat an eye at this.
注意:这也意味着表达 like42[a]
是完全合法的。人类读者可能会强烈反对,但编译器不会对此置之不理。