我正在学习C ++。如果我想声明指向数组的指针,我将使用:
int (*p)[10];
但是如果我想声明指针数组,我将使用:
int *(p[10]);
但是如果我使用new运算符,则没有变量名,如p,我必须写成它:
x = new int *[10];
问题是:编译器如何确定此语句分配的内存大小,是指针数组还是指针数组。另外,如何强制编译器根据需要解释int *[10]
的含义?
要声明一个指向int
的指针的数组,不需要括号:
int* p[10];
将会。要声明一个指向10个整数的数组的指针,您确实需要括号:
int (*p)[10];
这只是运算符优先级的问题。 []
与*
中的declarator绑定更牢固。因此,在没有括号的情况下,int *p[10];
将是十个([10]
首先应用)*
之后的指针的数组。 int
中的括号是多余的。另一方面,int *(p[10]);
声明一个指向10数组(int (*p)[10];
其次应用)*
的指针(()
由于[10]
而首先应用)。
A int
表达式没什么不同。唯一的区别是,声明符不包含标识符,因为您没有声明要命名的变量,而只是拼写了一个类型。 new
根据您要求创建的对象的类型来确定需要多少存储空间。
要简单地声明类型为“ new
的十个指针的数组”,您可以编写int
。并声明“指向十个整数数组的指针”的类型,您可以编写int* [10]
。
但是,在int (*)[10]
上下文中存在一个问题。问题在于C ++中数组类型的边界必须是常量表达式(即编译时常量)。动态大小的数组在C ++类型系统中不存在。但是,new
的全部要点是动态创建对象,尤其是动态大小的数组。
要解决此问题,new
必须避免曾经要求将动态大小的数组命名为类型。当前在C ++规范中实现此目的的方式是,对于new-expressions
new
具有完全独立的声明符语法。发生的情况是顶层数组边界被剥离并分别处理。编写[expr.new]/1时,将创建new int[n]
类型的n
对象的数组,其中int
不必为constant-expression。与n
对其他类型进行操作的方式相反,如果您要求new
创建数组类型的对象,则new
不会返回指向给定类型的数组的指针,而是指向该数组的第一个元素的指针它创建的数组。因此,即使您创建的数组的大小不是常量表达式,new-expression结果的类型也永远不会是“动态大小的数组”,但实际上存在于类型系统中…有一个逃生舱口盖的想法。 new表达式的语法为new
可以被赋予new-type-id(这是允许创建动态大小数组的单独语法)或普通的type -id放在括号中。new-expression
:[expr.new]/1opt::
new-placement opt new-type-id new-initializer optnew
opt::
new-placement optnew
type-id(
new-initializer opt如您所见,new-expression
因此,实际上可以通过)
创建指向十个int
的数组的单个指针:
new
以下内容是不正确的,我会很快将其删除(只是希望有一个答案可以对此答案发表评论^^)