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

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

本文关键字:指针 地址 一个      更新时间:2023-10-16

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

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

则 *指针的值为 5。但这反过来行得通吗?我的意思是:

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

这里的指针包含值 5 和 *pointer 保存数字的地址吗?

谢谢。

in

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

你永远不会给pointer分配一个有效的地址,所以取消引用该指针(如表达式*pointer所做的那样(是无效的。

来自牵强类比部门的类比:

您每天都会多次使用指针,甚至不假思索。

指针是一种间接寻址 - 它告诉你某物在哪里,或者如何到达它,但不是那个东西是什么。
(在键入的语言中,您可以知道它是什么样的东西,但那是另一回事。

例如,考虑电话号码。

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

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

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

一些规则:

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

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

PhoneNumber n;
Person Bob;
n = &Bob;

这是有道理的; n现在持有鲍勃的电话号码。

您的第二个示例将转换为

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

它会说"用鲍勃的电话号码替换Acme Inc客户服务的总经理",这根本没有意义。

你的最后一个问题,

这里的指针包含值 5 和 *pointer 保存数字的地址吗?

将转换为

这个电话号码和鲍勃

是一回事吗,如果你拨打它,鲍勃的电话号码会接听吗?

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

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

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

*pointer = &number; 不是有效的 C。

*pointer 属于 int 类型,&number 属于 int* 类型。这不是有效的赋值形式,不会在标准 C 编译器上编译。

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

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

如果执行显式强制转换,例如

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

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

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

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

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

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

现在,让我们看一下声明

*pointer = &number;

在这里,*pointer具有类型 int& - 您按照指针获取(引用(存储在该位置的整数。现在,让我们忽略这样一个事实,即您的指针未初始化并遵循它会导致未定义的行为。

右侧 &number 是指向整数变量的指针,因此类型为 int*

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

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

这里的指针包含值 5 和 *pointer 保存数字的地址吗?

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

  • 指针是否包含值 5

    指针包含一个位置。唯一有意义的时间是谈论具有文字值的指针(除了nullptr(是在有已知地址的平台上 - 这是罕见的,并且"5"不太可能是一个格式良好的地址

  • 无论如何
  • *指针保存地址

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