指向非常量数据的const指针

5

考虑以下情况 1:

const int n = 5;
int* p = &n; 

这是无效的,因为&n的类型是cont int*p的类型是int *(类型不匹配错误)。

现在,考虑第二种情况:

int k = 4;
int *const p = &k; 

这个案例编译成功,没有任何错误。显然,p 的类型是 int * const,而 &k 的类型是 int *。在这种情况下,存在类型不匹配,但是它是有效的。

问题:为什么尽管存在类型不匹配,第二种情况仍然是有效的?


你可以将一个非常量赋值给一个常量,但反过来不行。 - wcochran
1
将访问权限转换为“const”始终是合法的,但反过来则不行。如果您具有读/写访问权限,则可以不使用写入部分并保持只读状态。但是,如果您只有读取权限,则不能声明具有写入访问权限。 - dxiv
这是两个不同的常量。一个是低级别的常量,另一个是顶级常量。 - MahanGM
1
  1. 指向const的指针(或引用)仅是不通过该指针/引用修改对象的承诺。这并不意味着对象是不可修改的。
  2. int *const是一个常量指针(指针不能重新分配指向其他东西),而不是指向const的指针。
- jamesdlin
那么你会认为const int n = 5; int *const p = &n;是合法的吗?不是的。const 的位置很重要。这是一个指向整数的常量指针。当然,你可以使用一个值来初始化一个常量。 - Swift - Friday Pie
2个回答

4

在这种情况下,存在类型不匹配问题。

不是的,这种情况下不存在类型不匹配问题。它是一个指向非const的指针,您用一个指向非const的指针初始化它。

或者,如果您坚持认为存在“不匹配”,那么它类似于以下“不匹配”:

const int b = 42;

为什么第二种情况是有效的?
简单来说:初始化器的const性质与它是否初始化const对象无关。此外,初始化器是非类类型的prvalue,因此const资格根本不适用于它。

1
我在另一个答案中提到过这个问题,但是关闭这个问题并将其标记为重复问题不是更好吗?请问您是否同意? - cigien
7
如果你发现了重复的内容,可以随意投票关闭。 - eerorika
1
抱歉,让我澄清一下。考虑到您在c++标签下SO上的知识,我相信您可以在写答案的时间内找到一个重复的问题,并且使用您的c++技能自己关闭这个问题。这样做不是比有很多相同的问题更好吗? - cigien
@cigien,是什么阻止了你去做呢? - Nicolas Dusart
@NicolasDusart 没有任何阻止我这样做。我甚至可以将其关闭为由eeorika回答的目标的重复,因为他们已经多次回答了本质上相同的问题。找到目标确实比简单回答一个简单的问题更难,但我的希望是我能说服高声望用户花费精力去寻找目标,而不是反复回答这种基本问题。尽管如此,如果一些用户的优先事项不同,也没有规则阻止他们以这种方式行事。 - cigien

1
首先,int *const 表示一个指向非 const int 的常量指针。因此,在指针和被指对象类型之间绝对没有类型不匹配。
其次,你总是可以将非 const 变量的地址赋给指向 const 的指针。因此,以下代码也是有效的:
int n = 5;
const int * p = &n;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接