【问题标题】:Const pointer to a non-const variable [duplicate]指向非常量变量的常量指针[重复]
【发布时间】:2020-02-06 08:10:01
【问题描述】:

int i = 1;
const int *p = &i;

为什么我可以更改i 而不能更改*p?或者更确切地说,允许我写i = 5 而不是*p = 5 的幕后发生了什么?

【问题讨论】:

  • 为什么不能通过指针改变呢?因为你说它是一个 const int 的指针,你不能改变常量。
  • @Blaze 我试图了解编译器如何区分指针和值,因为指针只指向非常量值?
  • A const 指针是一个指针,其引用值不能通过该指针更改。没有什么可以阻止该值通过其他方式发生变化。
  • "编译器如何区分指针和值,因为指针只是指向非常量值?" -- 为什么不能要做到这一点?这发生在编译时。它看到*p = 5,它知道p 是一个指向const int 的指针,然后你得到错误。
  • 这能回答你的问题吗? Dereferencing a pointer to constant

标签: c constants


【解决方案1】:

您告诉编译器“我不会尝试分配给*p”(这实际上就是const 的全部内容),但这并没有说明i

#include <stdio.h>
void main(void) {
  int i = 1;
  const int *p = &i;
  printf("i=%d\np*=%d\n", i, p);
  i = 5;
  printf("i=%d\np*=%d\n", i, p);
  *p = 10;
  printf("i=%d\np*=%d\n", i, p);
}

GCC 会抱怨assignment of read-only location '*p',但i=5 很好,因为i 不是const。把*p中的const去掉,或者去掉*p=10的赋值,一切都好了。

如果对i 的引用不知何故消失了,那么从程序员的角度来看,该内存空间实际上将变为只读:编译器不会让我写到*p,这是我唯一的句柄为了那段记忆而离开。

【讨论】:

    【解决方案2】:

    首先不是const pointer,只有pointer to const object

    事实上,你只是向编译器保证你不希望指针引用的对象被这个指针的取消引用改变。编译器将跟踪(但仅编译器)尝试为源代码中的对象分配新值。没有运行时检查,您当然可以(如果对象不在只读内存中)通过在源代码中欺骗编译器来更改它。

    【讨论】:

    • 是的,正确的 - 添加解释
    【解决方案3】:

    通过将p 声明为指向const int 的指针,您承诺编译器不会使用通过p 的取消引用来修改p 指向的对象。如果您通过其他方式更改p 指向的对象来信守或违反承诺,这取决于您。

    【讨论】:

      【解决方案4】:

      场景背后什么都没有。一切都在编译器方面。

      i 表示一个标识符,它引用能够存储int 值的内存块。通过i,您可以读取或写入。

      p 表示指向const int 的指针。这仅意味着通过p,您无法写入指向的int,只能读取。 pint视图,不允许你修改它。就这样。这是在编译时确保的属性。

      现在将定义/声明视为对受访问权限污染的内存的类型化访问。

      【讨论】:

        【解决方案5】:
        const int *p
        

        表示p is a pointer to a constant of type int

         const int * const p
        

        表示p is a constant pointer to a constant of type int

         int * const p
        

        表示p is a constant pointer to an object of type int

         int *p
        

        表示p is a pointer to an object of type int

        【讨论】:

          猜你喜欢
          • 2021-04-19
          • 2014-02-23
          • 1970-01-01
          • 1970-01-01
          • 2020-10-23
          • 2012-04-22
          • 2011-08-27
          • 1970-01-01
          • 2021-06-19
          相关资源
          最近更新 更多