为什么a[]和*a的行为不同
Why do a[] and *a behave differently?
我认为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;
}
这段代码打印?
,但我不明白它是如何工作的。何时:
*a = new bool[5];
改为:
a = new bool[5];
编译器报告:
F:main.cpp|11|error: incompatible types in assignment of 'bool*' to 'bool [0]'|
我觉得这种行为很奇怪,所以我一直在玩这个代码。当我将a
的类型从bool
更改为int
时,编译器总是报告错误
F:main.cpp|11|error: invalid conversion from 'int*' to 'int' [-fpermissive]|
为什么这样工作
我认为
a[]
和*a
是一样的,因为它们的工作方式类似于指针。
让我们谈谈这段声明:
int a[4] = { 1, 2, 3, 5 };
int *b = NULL;
这就是它们在可执行文件中进入内存的方式:
+----+----+----+----+
a: | 1 | 2 | 3 | 5 | <-- 4 integers
+----+----+----+----+
+----------+
b: | NULL | <-- 1 pointer that points to nowhere
+----------+
正如您所看到的,它们不是一回事。
b = new int[4];
之后会发生什么
b
的新内存布局是这样的:
+----------+
b: | 0xacf3de | <-- 1 pointer that points to a block of 4 integers
+----------+
Somewhere else in memory (at address 0xacf3de)...
+----+----+----+----+
0xacf3de: | ? | ? | ? | ? | <-- 4 integers
+----+----+----+----+
但是等等,有人告诉我数组的工作原理就像指针
不,那不是真的。数组不像指针那样工作。
数组名称(a
,f.e.)可以用作其在内存中的地址(实际上是其第一个元素的地址)的快捷方式。以下符号是等效的:
a
&a
&a[0]
所有这些的值都是存储器中存储a
的第一个元素(上面例子中的1
)的地址。
a[0]
是int
,&a[0]
是int *
。这是完整的表格。另外两个是语言提供的快捷方式,目的是使代码更容易阅读和理解。
指针的情况不同
b
是存储在b
变量中的值(在上面的例子中是NULL
或0xacf3de
。它是类型为int *
的值——存储int
的存储器中的地址。&b
是存储b
的存储器中(的值)的地址。其类型为int **
——指向指向int
的指针的指针;或"存储器中存储int
地址的地址"。
但是等等,在某些情况下它们可以被替换
在某种程度上,指针和数组是可以互换的。正如您在上面看到的,有一种常见的数据类型:int *
。它是b
的类型(存储int
的地址),也是&a[0]
的类型(也是int
的地址)。
这意味着,在可以使用b
的情况下,可以改用a
(&a[0]
的缩写),反之亦然。
此外,在可以使用*b
的情况下,可以替代地使用*a
。它是*&a[0]
的缩写,意思是"存储在a[0]
地址(&
)的值(*
)",事实上,它与a[0]
相同。
但是,在可以使用&b
的情况下,不能使用&a
;请记住,&a
与&a[0]
相同,其类型为int *
(但&b
的类型为int **
)。
行:
*a = new bool[5];
相当于:
a[0] = new bool[5];
您不是在初始化您的数组,而是分配一个bool
数组,然后将其隐式转换为bool
,以分配给a[0]
:值应该是true
,因为new
返回的指针应该与0
不同。这种隐式转换不适用于int
s:这就是为什么在更改a
的类型时会出现错误。
现在,考虑这一行:
a = new bool[5];
在这里,您试图将动态分配的数组分配给a
,换句话说,将指向数组bool*
的指针分配给静态数组bool[0]
:正如编译器所说,类型是不兼容的。静态数组a[]
可以用作指针,例如在以下代码中:
int foo(bool* a) { /* ... */ }
bool my_array[5];
foo(my_array);
但是指针不能像你尝试的那样转换成静态数组
从new Type[x]
返回的值的类型是Type *
,即类型的指针
examle:所以正确的语法是bool a;
*a = new bool[x];
所以像那样做是错误的
a=new bool[x]
语法错误,因为将指针分配给正常可变无效
有关更多详细信息,请参阅
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 为什么会发生堆损坏
- 为什么使用 "this" 指针调用派生成员函数?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么比较运算符如此快速
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 为什么不;名字在地图上是按顺序排列的吗
- 我的字符计数代码计算错误.为什么
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 为什么 std::unique 不调用 std::sort?
- 既然存在危险,为什么项目要使用-I include开关
- 为什么在运行时没有向我们提供有关分段错误的更多信息?