C++ 您如何理解错误:无法从';int[]和#x27;至';int[]和#x27;

C++ 您如何理解错误:无法从';int[]和#x27;至';int[]和#x27;,c++,arrays,visual-studio-2005,pointers,error-code,C++,Arrays,Visual Studio 2005,Pointers,Error Code,编译以下代码时: void DoSomething(int Numbers[]) { int SomeArray[] = Numbers; } VS2005编译器出现错误C2440:“正在初始化”:无法从“int[]”转换为“int[]” 我理解它实际上是试图将指针投射到一个无法工作的数组。但如何解释对C++学习者的错误? 也许你的答案是“因为编译器不知道数组有多大。” 如果存在显式数组大小(为了清楚起见,可能使用typedef),那么您的示例可能会起作用,然后您可以在引入可变大小分配

编译以下代码时:

void DoSomething(int Numbers[])
{
    int SomeArray[] = Numbers;
}
VS2005编译器出现错误C2440:“正在初始化”:无法从“int[]”转换为“int[]”


我理解它实际上是试图将指针投射到一个无法工作的数组。但如何解释对C++学习者的错误?

也许你的答案是“因为编译器不知道数组有多大。”
如果存在显式数组大小(为了清楚起见,可能使用typedef),那么您的示例可能会起作用,然后您可以在引入可变大小分配时解释指针。

假设存在类型和不完整类型:

struct A;
是名为a.While的结构的不完整类型

struct A { };
是称为a的结构的完整类型。第一个结构的大小未知,而第二个结构的大小已知

存在类似于上述结构的不完整类类型。但也有不完整的数组类型:

typedef int A[];
这是一个称为A的不完整数组类型。其大小尚不清楚。不能用它创建数组,因为编译器不知道数组有多大。但您可以使用它来创建数组,前提是您要立即初始化它:

A SomeArray = { 1, 2, 3 };

现在,编译器知道数组是一个包含3个元素的int数组。如果您试图用指针初始化数组,编译器将不会比以前更聪明,并且会拒绝,因为这不会给出要创建的数组的大小

当我试图解释某件事时,我总是试图降低到最低层次,然后从那里开始构建。这就是我喜欢学习东西的方式,我发现如果你从他们知道的基本知识开始,并从中积累,人们会更舒服

在这种情况下,我可能会从以下内容开始:

编译器正在尝试执行以下操作: 作业,因为你写了一个 分配操作。在C++中,你 无法直接分配给数组, 因为它没有内置的赋值 操作员(仅限任何类型) 支持初始值设定项和索引 对于阵列)。因为C++支持 类型的重载运算符 然后,编译器查找重载的 的赋值运算符 “分配给”类型,该类型采用 “assigned from”类型作为其参数。 因为也没有过载 接受int[]的int[]运算符 作为参数,编译器在 这条线和错误告诉了你 为什么编译器不能处理该行


是的,这可能是过分的,而不是仅仅说一些关于大小的知识,不完整的类型,等等。我意识到这也不完整(例如:没有讨论初始化赋值和正常赋值,等等)。然而,我的目标通常是让人们自己找到下一个答案,为此,你通常想制定得出答案的思维过程。

为了让错误信息更有帮助,编译器实际上是在混淆问题。即使
Numbers
参数被声明为数组,C/C++也不会(不能)实际传递数组-
Numbers
参数实际上是一个指针

因此错误应该是
“无法从'int*'转换为'int[]”“

但接下来会出现混乱——“嘿,表达式中没有
int*
”,有人可能会说


出于这个原因,最好避免使用数组参数——将它们声明为指针,因为这才是您真正得到的。对学习C/C++的人的解释应该让他们认识到数组参数是虚构的——它们实际上是指针。

有三件事需要向你试图帮助的人解释:

< > > >强>数组不能通过值传递给C++中的函数。< /强>要做你想做的事情,你需要把数组开始的地址传递到<代码> DOMMETHONSE()/CUT>,以及数组中的大小,在单独的<代码> int <代码>(好,<代码> SiZeSt<<代码>,但我不介意说这个)。您可以使用表达式
&(myArray[0])
获取某个数组
myArray
的起始地址。因为这是一个非常常见的事情,C++允许你只使用数组的名称——例如,代码> MyReals——以获取它的第一个元素的地址。(这可能会有帮助或混淆,取决于你看它的方式)。C++使你可以将一个数组类型(例如,代码> int数字[]/COD>)指定为函数的一个参数,但是它会把这个参数当作一个指针来声明(在这个例子中是代码< int >数字< /代码>)。--您甚至可以在
DoSomething()内执行
Numbers+=5
操作,使其指向从第六个位置开始的数组

> P> <强>当C++中声明数组变量,如 SOMARELY 时,必须提供显式大小或“初始化列表”>,这是括号内的逗号分隔值列表。编译器不可能根据您试图初始化它的另一个数组推断数组的大小,因为

<> L> > P> <强> >不能将一个数组复制到另一个,或者在C++中初始化另一个数组。< /强>因此,即使参数<代码>数字< /C> >实际上是数组(比如1000号)而不是指针,并且指定“代码> SoMuriel< /Cube >的大小(同样如1000),行<代码> int SoMurLay[1000 ] =数字;<代码>将是非法的


要在
DoSomething()
中完成您想做的事情,请先问问自己:

  • 是否需要更改
    数字中的任何值
  • 如果是,我是否希望阻止调用方看到这些更改
  • 如果两个问题的答案都是“否”,那么实际上你不需要复印