C 指针';s地址和从指针转换的int值
我认为ptr的地址和a的地址是一样的。我还认为ptr的地址和指针转换的int值是一样的 但安慰的结果否定了我,原因是什么?我怎么能理解结果呢C 指针';s地址和从指针转换的int值,c,C,我认为ptr的地址和a的地址是一样的。我还认为ptr的地址和指针转换的int值是一样的 但安慰的结果否定了我,原因是什么?我怎么能理解结果呢 #包括 int main(){ inta[5]={1,2,3,4,5}; int*ptr=(int*)((int)a); printf(“a的地址:%p\n”,a); printf(“ptr的地址:%p\n”,ptr); printf(“ptr的int值:%x”,(int)ptr); 返回0; } 控制台的结果是 a's address: 0x7ffee
#包括
int main(){
inta[5]={1,2,3,4,5};
int*ptr=(int*)((int)a);
printf(“a的地址:%p\n”,a);
printf(“ptr的地址:%p\n”,ptr);
printf(“ptr的int值:%x”,(int)ptr);
返回0;
}
控制台的结果是
a's address: 0x7ffee8d30600
ptr's address: 0xffffffffe8d30600
ptr's int value: e8d30600
ps
我已经编辑了标题,最初模棱两可的标题是“指针的地址和指针的int值之间有什么区别”我已经理解了。机器基于64位地址。将地址转换为int值将丢失地址的上限值。所以这里a的地址不同于ptr的地址
如果在C++中使用指针,我们可以使用<代码> ItpTrpT><代码>或最好是<代码> uTunpTrtt><代码>
不是你真正想要达到的目的。int仅包含32位值。因此,(int)ptr将只返回ptr地址的32位值,这是您得到的较低的4个字节。C有一个用于存储指针值的:void *p = …;
uintptr_t u = (uintptr_t)p;
void *q = (void *)q;
// here q is equivalent to p
在许多平台上,u
存储p
指向的对象的地址,就像p
一样,u
和p
在内存中具有相同的表示形式。这不是义务:C实现可以使用不同的表示。但使用相同的表示法是满足C标准要求的最明显的方法
请注意,如果uintptr\u t
值是从仍然有效的指针获得的,则从uintptpr\u t
到指针类型的转换仅提供可用指针。这可能很微妙。即使在表示形式相同的处理器体系结构上(几乎所有的处理器体系结构都是如此),编译器也可以假定您不会做太疯狂的事情,并相应地进行优化。有关一些示例,请参见
在本例中,您没有尝试将指针值存储在uintpttr\t
中,而是尝试将其存储在int
中。此操作失败,因为在您的平台上,int
太小,无法存储指针值。显然,在您的平台上,指针是64位值,int
是32位值。这是一种非常普遍的安排
是数组的地址。(它是指向数组第一个元素的指针,在您的平台上,指针仅由地址表示。)。在这个特定的运行中,它是0x7ffee8d30600。没什么了不起的a
将(int)a
的地址转换为a
值。这是实现定义的。您的实现执行常规操作:因为int
太小,所以它会截断该值。将上述地址截断为无符号32位值将产生int
。要获得有符号值,最高有效位成为符号位,因此0xe8d30600
恰好为负:a
为a
-388823552
是p
。这种转换再次由实现定义,并且您的实现再次执行与大多数实现相同的操作。它接受32位有符号的(int*)((int)a)
值int
,将其扩展到所需的宽度,并将其移动到无符号范围,得到264-388823552=0xFFFFFFFF8D30600-388823552
应用与上述(int)p
相同的截断过程,并再次生成(int)a
。但是您正在使用-388823552
说明符将其打印出来,因此此值将转换为%x
无符号的
(平台上的32位类型),这将给出值232-388823552=0xe8d30600
&ptr
)。指针还包含一个地址(例如:表达式ptr
)。最后,您可以得到它所指向的内容(例如:表达式*ptr
)。每一个都有一个特定的类型,int**
、int*
和int
。也就是说,谁告诉过你“ptr的地址与其int值相同”是天真的。和int*ptr=(int*)((int)a)
完全是胡说八道。尤其是在x86-64平台上,指针的大小为64位并将其强制转换为int将删除信息。您不是在打印指针的地址,而是在打印指针的值。@WhozCraig谢谢您的回答。我编辑了标题和一些内容,这可能会导致歧义。指针只是一个普通变量,它的值包含其他对象的地址。换句话说,指针指向可以找到其他内容的地址。例如,inta=5
将立即值5
存储为其值int*b
创建指向int
和b=&a
存储a
的地址(当前存储5
的内存地址)作为其值。如果需要存储在指针持有的内存地址处的值,可以使用一元'*'
运算符取消对指针的引用,例如int c=*b代码>将初始化c=5
)。