指针可以指向一个值,指针值可以指向地址吗?
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.
*pointer
是 int
类型,&number
是 int*
类型。这不是有效的赋值形式,不会在标准 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 = y
,x
和 y
必须是同一类型,或者可以隐式转换为同一类型(或者 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)。因此这将是一个错误。
我在书上读到的指针的正常用法如下:
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.
*pointer
是 int
类型,&number
是 int*
类型。这不是有效的赋值形式,不会在标准 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 = y
,x
和 y
必须是同一类型,或者可以隐式转换为同一类型(或者 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)。因此这将是一个错误。