因此,void指针是一个通用指针,可以在以后指向任何字符或整数,对吧?但它是一个指针。但是,这编译时没有任何错误:
void* ptr;
long var;
ptr = (void*)var;
为什么在这里可以将long
强制转换为指针?不应该给出错误吗?请注意,如果var
是int
或char
,这也有效。
此外,如果var
为long
!
cout<<(long)ptr;
但是,如果var
是int
或char
,则此功能无效。我不知道该怎么做。我使用的是64位Linux机器。
答案 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_t
,uintptr_t
整数类型,能够保存从void指针转换的值,然后转换回该类型,其值与原始指针的值相等。
可选:某些库实现中可能未定义这些typedef。*
这些类型是可选的,但在大多数实现中都可用。即使它们不存在,也应该为存储内存地址定义特定于平台的类型。
哦,关于转换的观点并不完全正确 - 每个整数(有符号或无符号)值都可以通过显式转换转换为指针(任何类型,包括void*
)。它也可以反过来。
答案 2 :(得分:0)
由于指针包含地址,地址是(类似整数)数字,因此可以执行此操作,
就像你可以int
到long
或long
到int
。显式转换告诉编译器您意识到潜在的问题,因此它不会给您一个警告。
然而,根本不能保证long可以像指针一样保持相同的值范围
所以不要将long
用于地址。