将int转换为int *然后再转换为int

时间:2011-02-11 21:20:14

标签: c gcc

我遗漏了一些明显的东西,但请考虑以下内容,

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?

7 个答案:

答案 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从一开始就是一个坏主意。如果有的话,指针值只是虚拟内存空间中的一个位置,并将其视为有符号值对我来说毫无意义。

相关问题