我之前看到const
在static
数组的声明中使用了两次,现在我正在创建自己的静态数组我想知道为什么在某些情况下需要两次const。
指针数组是否有所不同?
a. static const TYPE name[5];
b. static const TYPE const name[5];
c. static const TYPE* name[5];
d. static const TYPE* const name[5];
我的理解是b.
无效,但如果使用const两次有效,它的目的是什么?
答案 0 :(得分:13)
const TYPE * x;
表示x指向的东西是const。
TYPE * const x;
表示指针x为const。
结合你得到的2:
const TYPE * const x;
意味着指针和指向的东西都是const。
答案 1 :(得分:1)
您可以将任何cv限定符(const
或volatile
)应用于任何类型,包括cv限定类型 - 但不在同一声明中。但是,就优先级而言,它们比任何运算符绑定更强,并且可以应用于限定类型的两端:
// Let T by any type:
T const tr;
const T tl;
const T const tlr; // only in C
const const const const const T t5; // only in C
typedef const T CT;
CT const tcc; // fine, although CT was already const
声明完全相同,常量T
。如果T
已经具有cv限定符,则不会更改其他限定条件的含义。
现在,优先;你可以说“我想要一个指向常量T
”的指针:
const T (* tp);
通常写为
const T* tp;
因为const
绑定比*
更强。在相同的模式中,您可以定义一个“常量但指向可变T
”的变量:
T (* const tp) = 0; // must be initialised, because tp is immutable
通常写为
T* const tp = 0;
同样,应用了下标运算符[]
- 具有与表达式相同的优先级。
答案 2 :(得分:0)
在第一个代码块中,第二行中有一个冗余重复const
,这没有任何效果。 (事实上,好的编译器会警告你这个。)你正在声明一个5 const TYPE
的数组,就是这样。
第二个代码块有两种不同的场景:第一行创建一个包含五个可变指针到const TYPE
s的数组,而后者生成一个包含五个常量<的数组< / em>指向const TYPE
的指针。
请注意,您必须初始化一个常量数组:由于您以后无法更改这些值,因此将它们定义为未初始化是没有意义的。
答案 3 :(得分:0)
在类型上使用const
两次在C ++ 2003中是非法的,但在C ++ 2011中是合法的(参见7.1.6.1 [decl.type.cv]第1段:“忽略冗余cv资格。”)。当你使用
static const TYPE const name[5];
你使TYPE
两次不变。但请注意,此声明在C ++ 2011中也是非法的,因为在声明它时需要初始化const
对象。
const TYPE
和
TYPE const
绝对等效:在这两种情况下,都会使TYPE
对象保持不变。为了保持一致性,我总是将const
放在右边,因为除了顶级类型之外,const
必须放在右侧(好吧,除非某些编码指南要求不同,但我'打击愚蠢的编码指南)。
使用指针时,认为变得与众不同。涉及两种类型:类型指向类型和指针。其中的每一个都可以单独制作const
:
TYPE const* ptr1(0); // non-const pointer to const TYPE
TYPE* const ptr2(0); // const pointer to non-const TYPE
TYPE const* const ptr3(0); // const pointer to const TYPE
确定const
内容的最佳方法是从右到左阅读类型声明。当然,这假设const
限定符被放入正确的位置。您可以在上面的讨论中将const
替换为volatile
或const volatile
,同样的推理也适用。