我遗漏了一些明显的东西,但请考虑以下内容,
int k = 10;
int *p = &k;
int i = (int)p;
以上产生,
warning: cast from pointer to integer of different size
以下,
int k = 10;
int *p = &k;
int i = p;
原因,
warning: initialization makes integer from pointer without a cast
有点谷歌搜索引导我,
Converting a pointer into an integer
使用uintptr_t建议,
int k = 10;
int *p = &k;
int i = (uintptr_t)p;
以上工作没有错误没有警告。所以我的问题是k是一个int而p是一个指向k的int指针为什么我会得到一个错误解引用p?
答案 0 :(得分:9)
int k = 10;
int *p = &k;
int i = *p;
注意最后一行的p之前的*。取消引用指针以获取它指向的int。
编辑:我对uintptr_t并不熟悉,但我运行了代码int i =(uintptr_t)p; 存储到i中的结果是k的内存地址,而不是10。演员告诉编译器你真的想把地址变成一个整数(所以没有警告;因为你坚持编译器你知道自己在做什么,但不会取消引用指针。答案 1 :(得分:3)
您收到错误,因为您实际上没有取消引用p
,您只是从int*
转换(强制更改其类型)。要取消引用,您需要使用*
运算符,如下所示:
int i = *p;
答案 2 :(得分:2)
您没有取消引用指针,因此您将指针的地址指定给int。
int i = *p;
你最想要的是什么。
答案 3 :(得分:1)
你正在使用int来进行指针转换,并且无法保证两者甚至不再使用相同数量的内存。实际上它并没有保证在人们做的时候使用相同尺寸,但对于大多数平台来说,它恰好正好工作了。
由于您在后一个示例中显式转换,编译器认为它不是一个错误(或者您为什么要键入它?)。这就是编译器输出差异的原因。
请注意,如果您不想将k的内存地址存储到i中,那么将K的值输入i的正确方法将是
int i = *p;
答案 4 :(得分:1)
您将i
设置为等于k
的地址(p
持有的地址)。地址值是无符号类型。因此,当从指针进行转换时,它会抱怨,因为您正在将转换和无符号值转换为signed。
同样指针是基于平台的不同大小的类型,因此32位指针小于64.因此,如果指针是8字节无符号,则将其转换为4字节签名。
答案 5 :(得分:0)
它应该是这样看的
int k = 10;
int *p = &k;
int i = *p;
这是我如何看待它
k = 10
p =某个地址
& k =某个地址
* p = 10
答案 6 :(得分:0)
uintptr_t
并不是指对int
进行中间转换的类型,而是使用它。如果它是在系统上定义的(并且你似乎有它),那么它是无符号整数类型,当你用指针值加载它时,你不会丢失信息。因此,如果必须,请完全使用uintprt_t
而不是int
。但这应该是罕见的情况,在大多数情况下我敢打赌,这只是设计糟糕的迹象。
无论如何int
从一开始就是一个坏主意。如果有的话,指针值只是虚拟内存空间中的一个位置,并将其视为有符号值对我来说毫无意义。