为什么可以将整数类型转换为指针?

时间:2015-04-21 04:50:17

标签: c++ pointers void void-pointers

因此,void指针是一个通用指针,可以在以后指向任何字符或整数,对吧?但它是一个指针。但是,这编译时没有任何错误:

void* ptr; 
long var;
ptr = (void*)var;

为什么在这里可以将long强制转换为指针?不应该给出错误吗?请注意,如果varintchar,这也有效。

此外,如果varlong

,则以下代码段有效
cout<<(long)ptr;

但是,如果varintchar,则此功能无效。我不知道该怎么做。我使用的是64位Linux机器。

3 个答案:

答案 0 :(得分:2)

因为指针是对内存位置的数字引用,因此可以转换为数值。在许多情况下,它们之间的转换大致相同。例如,如果我有一个像0x3E103A08这样的32位内存位置(指针通常以十六进制形式查看),则该十六进制表示将是等效于1041250824的无符号整数。为了得到更详细的信息,32位指针只有4个字节,因此是32位无符号整数。事实上,在CPU级别,使用CPU寄存器 - 有些像指针,有些用于计算 - 所有这些(在我过去在ASM中开发)更像是整体变量。

答案 1 :(得分:2)

它有效,因为指针实际上是内存地址,而后者又由无符号整数(地址)表示。

注意,long通常为4字节长,因此如果切换到64位平台(指针长度为64位/ 8字节),它将无法保存内存地址。在这种情况下,将指针转换为int / long会截断(从而使其内容无效)。

要存储地址值,请使用uintptr_t(或签名版本intptr_t),如上所述here

  

intptr_tuintptr_t

     

整数类型,能够保存从void指针转换的值,然后转换回该类型,其值与原始指针的值相等。

     

可选:某些库实现中可能未定义这些typedef。*

这些类型是可选的,但在大多数实现中都可用。即使它们不存在,也应该为存储内存地址定义特定于平台的类型。

哦,关于转换的观点并不完全正确 - 每个整数(有符号或无符号)值都可以通过显式转换转换为指针(任何类型,包括void*)。它也可以反过来。

答案 2 :(得分:0)

由于指针包含地址,地址是(类似整数)数字,因此可以执行此操作, 就像你可以intlonglongint。显式转换告诉编译器您意识到潜在的问题,因此它不会给您一个警告。

然而,根本不能保证long可以像指针一样保持相同的值范围 所以不要将long用于地址。