指针可以指向一个值,指针值可以指向地址吗?

Can a pointer point to a value and the pointer value point to the address?

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

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

那么*pointer的值为5。 但这反过来有效吗?我的意思是:

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

这里指针是否包含值5并且*指针包含数字的地址?

谢谢。

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

您从未将有效地址分配给 pointer,因此取消引用该指针(如表达式 *pointer 所做的那样)是无效的。

你的第二个案例将无法编译,因为赋值 *pointer = &number 涉及不兼容的类型(左侧的 int,右侧指向 int 的指针)这使得赋值无效.

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

*pointer = &number; 无效 C.

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

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

当然,请注意您还没有将 pointer 设置为指向已分配的内存地址,因此您不能在它指向的位置存储任何内容。

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

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

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

An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.

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

现在,让我们看一下声明

*pointer = &number;

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

右手边,&number,正在接受一个指向整型变量的指针,所以类型是int*

所以,表达式根本没有意义,就类型系统而言:无法将 int* 分配给 int&。它没有任何意思。

让我们将其与您问题的英语联系起来

Here does pointer contain the value 5 and *pointer holds the address of number?

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

  • does pointer contain the value 5

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

  • *pointer holds the address

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

类比牵强系系:

你每天都想很多次使用指针。

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

例如,考虑电话phone 号码。

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

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

  • &person 给你一个人的 phone 号码,
  • *number 给你号码所属的人。

一些规则:

  • 这种语言只有两种类型 - 人和 phone 数字。
  • 只有个人可以拥有 phone 个号码; &number 是错误,*person.
  • 也是错误
  • 一个未指定的 phone 号码到达了 Acme, Inc. 的客户服务总经理

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

PhoneNumber n;
Person Bob;
n = &Bob;

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

您的第二个示例将转换为

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

这会说 "replace the General Manager of Acme Inc's Customer Services with Bob's phone number",这完全没有意义。

最后一个问题,

Here does pointer contain the value 5 and *pointer holds the address of number?

将转换为

Is this phone number the same thing as Bob, and if you call it, will Bob's phone number answer?

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

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

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