【问题标题】:Can a pointer point to a value and the pointer value point to the address?指针可以指向一个值,而指针值指向地址吗?
【发布时间】:2016-08-11 08:24:35
【问题描述】:

我在书中读到的正常指针用法如下:

int *pointer;
int number = 5;
pointer = &number; 

那么 *pointer 的值为 5。 但这是否反过来起作用?我的意思是:

int *pointer;
int number = 5;
*pointer = &number;

这里是不是指针包含值5而*指针包含数字的地址?

谢谢。

【问题讨论】:

  • 不,它会调用未定义的行为。
  • 你可能需要指针的指针。

标签: c++ c pointers reference dereference


【解决方案1】:

要编写赋值 x = yxy 必须是或可以隐式转换为相同类型(或 x 必须有一个用户定义的赋值运算符,其参数匹配y 的类型,或者......好吧,有几种可能性,但你明白了)。

现在,让我们看看声明

*pointer = &number;

这里,*pointer 的类型为 int& - 您按照指针获取(引用)存储在该位置的整数。让我们暂时忽略您的指针未初始化并跟随它会导致未定义行为这一事实。

右侧&number 是一个指向整数变量的指针,所以类型是int*

因此,仅就类型系统而言,表达式根本没有意义:无法将int* 分配给int&。它不意味着任何东西。

让我们把它与你的问题的英语联系起来

这里是不是指针包含值5而*指针包含数字的地址?

这直接转化为类型系统,因此没有任何意义。同样,我们可以分解它

  • 指针是否包含值 5

    一个指针包含一个位置。唯一有意义的是谈论具有字面值的指针(nullptr 除外)是在有众所周知地址的平台上 - 这种情况很少见,'5' 不太可能是无论如何,格式正确的地址

  • *指针保存地址

    好吧,有一种情况,*pointer 可以保存一个地址——其中*pointer 本身就是一个指针,这意味着变量pointer 是一个指向指针的指针,例如int **。这不是这里的情况:我们知道您的代码中*pointer 的类型,它是int&,而不是int*

【讨论】:

    【解决方案2】:

    当你创建一个指针变量时,最初它会有垃圾值(比如 300 地址位置)。因此,当您取消引用指针(*300)时,它会给出另一个垃圾值(300 地址位置的值)或错误(严格来说,任何事情都可能发生,具体取决于您的计算机)。

    在第三步中,&number:- 这也是另一个数字,您正在尝试为 *pointer 分配一个数字(可能是另一个数字),这是不可能的。 (就像这样:- 5=6)。因此这将是一个错误。

    【讨论】:

      【解决方案3】:

      牵强的类比系的类比:

      您每天都会多次使用指针,甚至没有考虑它。

      指针是一个间接 - 它告诉你在哪里 某物在哪里,或者如何到达它,但不告诉你是什么 .
      (在类型化语言中,您可以知道它是什么种类,但这是另一回事。)

      例如,考虑电话号码。

      这些告诉您如何联系电话号码所属的人。
      随着时间的推移,那个人可能会发生变化——也许有人没有支付账单并且号码被重新分配——但只要号码是有效的,你就可以用它来联系一个人。

      使用这个类比,我们可以定义以下操作:

      • &person 给你一个人的电话号码,并且
      • *number 为您提供号码所属的人。

      一些规则:

      • 这种语言只有两种类型 - 人员和电话号码。
      • 只有人才能拥有电话号码; &number 是一个错误,*person 也是。
      • Acme, Inc. 客户服务部总经理收到一个未指明的电话号码。

      现在,您的第一个示例将转换为

      PhoneNumber n;
      Person Bob;
      n = &Bob;
      

      这是有道理的; n 现在拥有 Bob 的电话号码。

      您的第二个示例将转换为

      PhoneNumber n;
      Person Bob;
      *n = &Bob;
      

      这会说“用 Bob 的电话号码替换 Acme Inc 客户服务部的总经理”,这完全没有意义。

      最后一个问题,

      这里是不是指针包含值5而*指针包含数字的地址?

      会翻译成

      这个电话号码和 Bob 一样吗,如果你拨打它,Bob 的电话号码会接听吗?

      我相信你可以看到这是一个相当奇怪的问题。

      【讨论】:

        【解决方案4】:

        *pointer = &number; 是无效的 C。

        *pointerint 类型,&numberint* 类型。这不是有效的赋值形式,不会在标准 C 编译器上编译。

        您可以将数字存储在指针变量中,但是您必须使用显式强制转换来强制进行类型转换。一些编译器允许它不显式转换,但请注意,这样做是非标准扩展。

        当然,请注意,您尚未将 pointer 设置为指向已分配的内存地址,因此您无法在其指向的位置存储任何内容。

        如果您进行显式转换,例如

        pointer = &something;
        *pointer = (int)&number;
        

        那么它在 C 中是允许的,但是如果您尝试取消引用该指针,则行为是实现定义的。在未对齐等情况下,它也可能是未定义的行为。参见 C11 6.3.2.3:

        整数可以转换为任何指针类型。除了以前 指定,结果是实现定义的,可能不是 正确对齐,可能不指向被引用的实体 类型,并且可能是陷阱表示。

        【讨论】:

        • TL;DR:一开始就不要写这种无意义的代码。
        • 好的,谢谢!我没有完全掌握这个主题,所以当时听起来就在我耳边。
        【解决方案5】:

        您的第二种情况无法编译,因为赋值 *pointer = &number 涉及不兼容的类型(左侧为int,右侧为指向int 的指针),这使得赋值无效。

        如果您以某种方式强制分配进行编译,则 pointer 不会被初始化。访问它的值,更不用说取消引用它(例如评估*pointer 或分配给它,如*pointer = number*pointer = 5)会给出未定义的行为。然后任何事情都可能发生......根据具体情况,未定义行为的常见结果是程序异常终止。

        【讨论】:

          【解决方案6】:

          int *pointer;
          int number = 5;
          *pointer = &number;
          

          您永远不会为 pointer 分配有效地址,因此取消引用该指针(如表达式 *pointer 所做的那样)无效。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-10
            • 1970-01-01
            • 2015-02-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多