I thought a[]
and *a
are the same thing because they work like pointers. Yet I encountered something unexpected in the following code:
我认为a和a是一样的因为它们像指针一样工作。然而,我在以下代码中遇到了意想不到的事情:
#include <iostream>
using namespace std;
class F {
public:
bool a[];
F();
};
F::F() {
*a = new bool[5];
a[2] = true;
}
int main() {
F obj;
if(obj.a[2])
cout << '?';
return 0;
}
This code prints ?
, but I don't understand how it works. When:
这个代码是打印出来的,但是我不明白它是怎么工作的。当:
*a = new bool[5];
is changed into:
变成:
a = new bool[5];
compiler reports:
编译器报告:
F:\main.cpp|11|error: incompatible types in assignment of 'bool*' to 'bool [0]'|
I found this behaviour weird, so I was playing around with this code. When I changed the type of a
from bool
to int
compiler always reports an error
我发现这种行为很奇怪,所以我在摆弄这段代码。当我将a的类型从bool更改为int编译器时,总是会报告一个错误
F:\main.cpp|11|error: invalid conversion from 'int*' to 'int' [-fpermissive]|
Why does this work the way it does?
为什么会这样呢?
3 个解决方案
#1
2
I thought
a[]
and*a
are the same thing because they work like pointers.我认为a和a是一样的因为它们像指针一样工作。
Let's talk about this piece of declaration:
让我们谈谈这段宣言:
int a[4] = { 1, 2, 3, 5 };
int *b = NULL;
This is how they land in memory in the executable:
这就是它们在可执行文件中的记忆方式:
+----+----+----+----+
a: | 1 | 2 | 3 | 5 | <-- 4 integers
+----+----+----+----+
+----------+
b: | NULL | <-- 1 pointer that points to nowhere
+----------+
As you can see, they are not the same thing.
正如你所看到的,它们不是一回事。
What happens after b = new int[4];
?
b = new int[4]后会发生什么?
The new memory layout of b
is something like this:
b新的内存布局是这样的:
+----------+
b: | 0xacf3de | <-- 1 pointer that points to a block of 4 integers
+----------+
Somewhere else in memory (at address 0xacf3de)...
+----+----+----+----+
0xacf3de: | ? | ? | ? | ? | <-- 4 integers
+----+----+----+----+
But wait, somebody told me that arrays work like pointers...
但是等等,有人告诉我数组就像指针一样工作。
No, that's not true. The arrays do not work like pointers.
不,那不是真的。数组不像指针那样工作。
An array name (a
, f.e.) can be used as a shortcut for its address in memory (which is, in fact, the address of its first element). The following notations are equivalent:
数组名(a, f.e.)可以用作其在内存中的地址的快捷方式(实际上是第一个元素的地址)。下列表示法是等价的:
a
&a
&a[0]
The value of all of them is the address in memory where the first element of a
(the 1
in the example above) is stored.
它们的值都是内存中的地址,其中存储了a的第一个元素(上面示例中的1)。
a[0]
is an int
, &a[0]
is an int *
. This is the complete form. The other two are shortcuts that the language provides in order to make the code easier to read and understand.
[0]是int,而[0]是int *。这是完整的表格。另外两个是语言提供的快捷方式,以便使代码更容易阅读和理解。
The things are different for pointers.
指针是不同的。
b
is the value stored in the b
variable (NULL
or 0xacf3de
in the example above. It is a value of type int *
-- the address in memory where an int
is stored. &b
is the address in memory where (the value of) b
is stored. Its type is int **
-- a pointer to a pointer to an int
; or "the address in memory where is stored the address of an int
".
b是存储在b变量中的值(NULL或上面示例中的0xacf3de)。它是int *类型的值——存储int类型的内存地址。&b是存储b值的内存地址。它的类型是int **——指向int的指针;或“内存中存储int地址的地址”。
But wait, they can be replaced one for another in some contexts
但是,等等,在某些情况下,它们可以相互替换
Up to some point, yes, a pointer and an array are interchangeable. As you can see above, there is a common data type involved: int *
. It is the type of b
(which stores the address of an int
) and also the type of &a[0]
(which is also the address of an int
).
在某种程度上,指针和数组是可以互换的。正如您在上面看到的,涉及到一个公共数据类型:int *。它是b的类型(存储int的地址)和[0]的类型(也是int的地址)。
This means that where b
can be used, a
(a short of &a[0]
) can be used instead, and vice-versa.
这意味着,在可以使用b的地方,可以使用a(简写为&a[0]),反之亦然。
Also, where *b
can be used, *a
can be used instead. It is the short for *&a[0]
and it means "the value (*
) stored at the address (&
) of a[0]
" and it is, in fact, the same as a[0]
.
此外,如果可以使用*b,则可以使用*a。它是*和[0]的缩写,意思是“在一个[0]的地址(&)中存储的值”,实际上,它与[0]相同。
But, where &b
can be used, &a
cannot be used instead; remember that &a
is the same as &a[0]
and its type is int *
(but the type of &b
is int **
).
但是,在可以使用&b的地方,不能使用& &代替;记住,&a和[0]是一样的,它的类型是int *(但是&b的类型是int **)。
#2
2
The line:
线:
*a = new bool[5];
is equivalent to:
等价于:
a[0] = new bool[5];
You are not initialiazing your array, but allocating an array of bool
which is then implicitly converted into bool
to be assigned to a[0]
: the value should be true
since the pointer returned by new
should be different from 0
. This implicit conversion does not apply with int
s: that is why you are getting an error when changing the type of a
.
您不是在初始化数组,而是分配一个bool数组,然后隐式地将其转换为bool,将其赋值为[0]:该值应该为true,因为new的指针应该与0不同。这种隐式转换不适用于int:这就是为什么在更改a的类型时会出现错误。
Now, considering this line:
现在,考虑这条线:
a = new bool[5];
Here you are trying to assign your dynamically allocated array to a
, in other words assigning a pointer to an array bool*
to a static array bool[0]
: as the compiler says, the types are incompatible. A static array a[]
can be used as a pointer, e.g. in the following code:
这里,您试图将动态分配的数组分配给a,换句话说,将指向数组bool*的指针分配给静态数组bool[0]:正如编译器所说,类型是不兼容的。静态数组A[]可以用作指针,例如在下面的代码中:
int foo(bool* a) { /* ... */ }
bool my_array[5];
foo(my_array);
But pointers can not be converted into static arrays as you are trying to do.
但是指针不能像您正在尝试的那样转换成静态数组。
#3
0
Type of value returned from new Type[x]
is Type *
i.e pointer of that type
新类型[x]返回的值的类型是* i。e是那种类型的指针
examle: So Right syntax is bool a;
正确的语法是bool a;
*a = new bool[x];
* = new bool[x];
so it is wrong to do like is
所以这样做是不对的
a=new bool[x]
wrong syntax as it is invalid to assign pointer to a normal varibale
新的bool[x]语法错误,因为将指针赋给普通变量是无效的
看到更多的细节
#1
2
I thought
a[]
and*a
are the same thing because they work like pointers.我认为a和a是一样的因为它们像指针一样工作。
Let's talk about this piece of declaration:
让我们谈谈这段宣言:
int a[4] = { 1, 2, 3, 5 };
int *b = NULL;
This is how they land in memory in the executable:
这就是它们在可执行文件中的记忆方式:
+----+----+----+----+
a: | 1 | 2 | 3 | 5 | <-- 4 integers
+----+----+----+----+
+----------+
b: | NULL | <-- 1 pointer that points to nowhere
+----------+
As you can see, they are not the same thing.
正如你所看到的,它们不是一回事。
What happens after b = new int[4];
?
b = new int[4]后会发生什么?
The new memory layout of b
is something like this:
b新的内存布局是这样的:
+----------+
b: | 0xacf3de | <-- 1 pointer that points to a block of 4 integers
+----------+
Somewhere else in memory (at address 0xacf3de)...
+----+----+----+----+
0xacf3de: | ? | ? | ? | ? | <-- 4 integers
+----+----+----+----+
But wait, somebody told me that arrays work like pointers...
但是等等,有人告诉我数组就像指针一样工作。
No, that's not true. The arrays do not work like pointers.
不,那不是真的。数组不像指针那样工作。
An array name (a
, f.e.) can be used as a shortcut for its address in memory (which is, in fact, the address of its first element). The following notations are equivalent:
数组名(a, f.e.)可以用作其在内存中的地址的快捷方式(实际上是第一个元素的地址)。下列表示法是等价的:
a
&a
&a[0]
The value of all of them is the address in memory where the first element of a
(the 1
in the example above) is stored.
它们的值都是内存中的地址,其中存储了a的第一个元素(上面示例中的1)。
a[0]
is an int
, &a[0]
is an int *
. This is the complete form. The other two are shortcuts that the language provides in order to make the code easier to read and understand.
[0]是int,而[0]是int *。这是完整的表格。另外两个是语言提供的快捷方式,以便使代码更容易阅读和理解。
The things are different for pointers.
指针是不同的。
b
is the value stored in the b
variable (NULL
or 0xacf3de
in the example above. It is a value of type int *
-- the address in memory where an int
is stored. &b
is the address in memory where (the value of) b
is stored. Its type is int **
-- a pointer to a pointer to an int
; or "the address in memory where is stored the address of an int
".
b是存储在b变量中的值(NULL或上面示例中的0xacf3de)。它是int *类型的值——存储int类型的内存地址。&b是存储b值的内存地址。它的类型是int **——指向int的指针;或“内存中存储int地址的地址”。
But wait, they can be replaced one for another in some contexts
但是,等等,在某些情况下,它们可以相互替换
Up to some point, yes, a pointer and an array are interchangeable. As you can see above, there is a common data type involved: int *
. It is the type of b
(which stores the address of an int
) and also the type of &a[0]
(which is also the address of an int
).
在某种程度上,指针和数组是可以互换的。正如您在上面看到的,涉及到一个公共数据类型:int *。它是b的类型(存储int的地址)和[0]的类型(也是int的地址)。
This means that where b
can be used, a
(a short of &a[0]
) can be used instead, and vice-versa.
这意味着,在可以使用b的地方,可以使用a(简写为&a[0]),反之亦然。
Also, where *b
can be used, *a
can be used instead. It is the short for *&a[0]
and it means "the value (*
) stored at the address (&
) of a[0]
" and it is, in fact, the same as a[0]
.
此外,如果可以使用*b,则可以使用*a。它是*和[0]的缩写,意思是“在一个[0]的地址(&)中存储的值”,实际上,它与[0]相同。
But, where &b
can be used, &a
cannot be used instead; remember that &a
is the same as &a[0]
and its type is int *
(but the type of &b
is int **
).
但是,在可以使用&b的地方,不能使用& &代替;记住,&a和[0]是一样的,它的类型是int *(但是&b的类型是int **)。
#2
2
The line:
线:
*a = new bool[5];
is equivalent to:
等价于:
a[0] = new bool[5];
You are not initialiazing your array, but allocating an array of bool
which is then implicitly converted into bool
to be assigned to a[0]
: the value should be true
since the pointer returned by new
should be different from 0
. This implicit conversion does not apply with int
s: that is why you are getting an error when changing the type of a
.
您不是在初始化数组,而是分配一个bool数组,然后隐式地将其转换为bool,将其赋值为[0]:该值应该为true,因为new的指针应该与0不同。这种隐式转换不适用于int:这就是为什么在更改a的类型时会出现错误。
Now, considering this line:
现在,考虑这条线:
a = new bool[5];
Here you are trying to assign your dynamically allocated array to a
, in other words assigning a pointer to an array bool*
to a static array bool[0]
: as the compiler says, the types are incompatible. A static array a[]
can be used as a pointer, e.g. in the following code:
这里,您试图将动态分配的数组分配给a,换句话说,将指向数组bool*的指针分配给静态数组bool[0]:正如编译器所说,类型是不兼容的。静态数组A[]可以用作指针,例如在下面的代码中:
int foo(bool* a) { /* ... */ }
bool my_array[5];
foo(my_array);
But pointers can not be converted into static arrays as you are trying to do.
但是指针不能像您正在尝试的那样转换成静态数组。
#3
0
Type of value returned from new Type[x]
is Type *
i.e pointer of that type
新类型[x]返回的值的类型是* i。e是那种类型的指针
examle: So Right syntax is bool a;
正确的语法是bool a;
*a = new bool[x];
* = new bool[x];
so it is wrong to do like is
所以这样做是不对的
a=new bool[x]
wrong syntax as it is invalid to assign pointer to a normal varibale
新的bool[x]语法错误,因为将指针赋给普通变量是无效的
看到更多的细节