我正在学习 C++。 如果我想声明指向数组的指针,我将使用:
int (*p)[10];
但如果我想声明指针数组,我将使用:
int *(p[10]);
但如果我使用 new 运算符,则没有变量名,例如 p,我必须写成:
x = new int *[10];
问题是:编译器如何确定此语句分配的内存大小,它是指针数组还是指向数组的指针。另外,如何强制编译器根据我的需要解释 int *[10]
的含义?
最佳答案
要声明指向int
的指针数组,您不需要括号:
int* p[10];
会做。要声明一个指向包含 10 个整数的数组的指针,您确实需要括号:
int (*p)[10];
这只是运算符优先级的问题。 []
在 declarator 中的绑定(bind)比 *
更强.因此,如果没有括号,int *p[10];
将是一个包含十个([10]
首先适用)指向 (*
适用于第二个)int
。 int *(p[10]);
中的括号是多余的。 int (*p)[10];
另一方面,声明一个指向(*
由于 ()
而首先应用)的指针10 个数组([10]
第二个应用)int
。
new
表达式也不异常(exception)。唯一的区别是您的声明符不包含标识符,因为您没有声明要命名的变量,您只是在拼写一个类型。 new
根据您要求它创建的对象类型计算出它需要多少存储空间。
要简单地声明“指向 int
的十个指针的数组”类型,您可以编写 int* [10]
。要声明“指向十个 int 数组的指针”类型,您需要编写 int (*)[10]
。
但是,new
的上下文中存在一个问题。这个问题是 C++ 中数组类型的边界必须是常量表达式(即编译时常量)。 C++ 类型系统中不存在动态大小的数组。但是,new
的全部意义在于动态创建对象,尤其是动态大小的数组。
要解决这个问题,new
必须避免要求将动态大小的数组命名为类型。目前在 C++ 规范中实现这一点的方法是为 new-expressions 使用完全独立的声明符语法 [expr.new]/1 .那里发生的事情是顶级数组边界被剥离并单独处理。当您编写 new int[n]
时,您创建了一个包含 n
个类型为 int
的对象的数组,其中 n
不必是常量表达式。与 new
对其他类型的操作方式相反,如果您要求 new
创建数组类型的对象,new
不会返回指向给定类型的数组,而是指向它创建的数组的第一个元素的指针。因此,即使您创建了一个大小不是常量表达式的数组,new-expression 的结果类型也永远不会是“动态大小数组”,而是始终类型系统中实际存在的东西......
有一个逃生舱口的想法。 new 表达式的语法是 [expr.new]/1
new-expression:
::
optnew
new-placementopt new-type-id new-initializeropt
::
optnew
new-placementopt(
type-id)
new-initializeropt
如您所见,new-expression 可以被赋予new-type-id(这是允许创建动态大小数组的单独语法) 或括号中的普通 type-id。
因此,实际上可以通过 new
创建一个指向十个 int
数组的指针:
int (**p)[10] = new (int(*)[10]);
关于c++ - 如何强制新运算符(operator)根据我的需要解释语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59130221/