我正在查看"Pointers in C: when to use the ampersand and the asterisk"的答案,并对示例int *p2 = &i;
感到困惑(来自Dan Olson的答案)
i
的地址不是int,它类似于0x02304,对吧?那么我们怎样才能将它放入p2
?如果字节存储器地址不是int?
谢谢!
P.S。对于那些在这一点上感到困惑的人,我觉得有用的另一个主题(虽然它没有为我回答这个问题)是"What exactly is a C pointer if not a memory address"祝你好运。
答案 0 :(得分:1)
i的地址不是int,就像0x02304说的那样,对吧?
指针是保存内存地址的变量。地址就像你家的地址一样,是一个分配给一个字节内存位置的整数。
int类型的C指针如何保存内存地址
在您的示例中,p2
是 pointer-to-int 类型的变量。它是一个指针 - 一个内存地址 - 您可以在其中声明指向存储int
变量的内存点。
答案 1 :(得分:1)
p2
不是int
,而是指向int
的指针。因此,它可以保存int
变量的地址。
语法int *p2;
定义了指向int
的指针。
使用p2
初始化&i
会将变量i
的地址存储到p2
。修改p2
指向的值将修改i
。
以下替代语法都是等效的:
int *p2 = &i;
int * p2 = & i;
int * p2 =& i;
int*p2=&i;
int* p2 = &i;
首选语法为int *p2 = &i;
,因为它避免了在同一行上定义多个变量时常见的误解:
int *p1, *p2; // defines 2 pointers to int
int *p1, p2; // p1 is a pointer-to-int, whereas p2 is an int
将*
粘贴到该类型会使后一个定义非常混乱:
int* p1, p2; // p1 is a pointer-to-int, whereas p2 is an int
因此,强烈建议不要在同一行上定义具有不同间接级别的变量。
答案 2 :(得分:0)
指针是内存地址的抽象,带有一些相关的类型语义。
p2
的类型为int *
,或“指向int
的指针”。它存储整数对象的位置(在本例中为对象i
的位置)。 表达式 *p2
的类型为int
:
p2 == &i; // both expressions have type int * and evaluate to an address value
*p2 == i; // both expressions have type int and evaluate to an integer value
指针与存储地址值所需的大小一样大,但是该地址值是针对给定平台表示的(无论是单个整数值,还是表示页码和偏移量的一对值,或者某些其他格式)。请注意,不同的指针类型可能大小不同,但在现代桌面架构中,它们的大小相同(32位或64位)。
指针的类型对指针算术很重要。给定指针p
,表达式p + 1
产生指向类型的下一个对象的地址。如果指向的类型是1字节宽(例如char
)并且其当前地址是0x8000,则p + 1
产生下一字节的地址,或0x8001。如果类型为4字节宽(例如long
)且其当前地址为0x8000,则p + 1
将生成第四个下一个字节的地址,即0x8004。
答案 3 :(得分:0)
我认为int *p2 = &i;
令人困惑的原因是同时声明和实例化以及间距的综合影响。我会解释一下。
通常,对于指向整数p2
和整数i
的指针,写入“*p2
”取消引用p2
并让int
生活在地址&i
。
因此代码“int *p2 = &i;
”使int
看起来像是一个内存地址。
确实,代码
int i = 1;
int *p2;
*p2 = &i
是错误的,因为在最后一行中,*p2
是int
,因为p2
已取消引用,&i
是指针。
为什么 int *p2 = &i;
与上面有缺陷的代码的最后一行没有做同样的事情:
代码int *p2 = &i;
与上面的3行代码不同,因为它是一个声明。当您声明一个指针变量时,您可以设置类型(例如int
,long
,char
等),以及变量的名称(正常情况下) - 您还可以在这两个部分之间添加了一个星号*
(请参阅上面关于许多间距选项的@chqrlie答案 - 最好的做法是将*
加到变量名称上。在声明中,*
不取消引用指针。相反,它告诉编译器变量myPointer
将是一个指向存储器的指针,该存储器保存声明类型的数据(int
,long
,char
等。之前)。因此,在代码“int *p2 = &i;
”中,同时声明和实例化指针,*
不会在左侧呈现int
。对于声明,虽然将*
放在变量名旁边是更安全的(如@chqrlie所指出的),但即使指针在声明中被实例化,也不会解开指针。对于声明,请将*
视为附加到类型(而不是变量名称,其中可能有很好的理由)。我喜欢在指针名称旁边用*
声明指针,但是只要明白在声明中实例化指针时,新学员想象这条线的方式可能更明确int* p2 = &1
:
int*
(类型pionter-to-int)p2
(指针名称)= &i
(等于给出整数i
地址的指针){{1 }}
感谢所有回答和评论的人,祝所有可能来到这里试图弄清楚指针的人们好运。
答案 4 :(得分:0)
指针是它自己的类型。 如果它使用不同的语法,可以这样写:
Pointer x = new Pointer(int, address);