我试图深入理解指针概念。 在以下代码中,
#include <stdio.h>
int main()
{
int i = 10;
int *iptr = &i;
printf("(float)* : %f\n", (float)*iptr);
printf("(float*) : %f\n", (float*)iptr);
printf("*(float*) : %f\n", *(float*)iptr);
return 0;
}
输出:
(float)* : 10.000000
(float*) : 10.000000
*(float*) : 0.000000
我也收到了关于类型转换(float*)
的警告
我发现很难分析差异。如果有人可以帮我分析这三者的确切用法,那将会有所帮助。
答案 0 :(得分:4)
区别在于
您正在取消引用int
并将其投放到<{p>}中的float
printf("(float)* : %f\n", (float)*iptr);
没关系。
您正在将int
指针强制转换为float
指针,并且使用float
说明符打印"%f"
指针是未定义的行为,正确的说明符是打印指针是"%p"
,所以
printf("(float*) : %f\n", (float*)iptr);
错了,应该是
printf("(float*) : %p\n", (void *) iptr);
此处转换为float *
没有意义,因为void *
地址与float *
地址以及int *
地址相同,不同之处在于做指针算法。
您正在将int
指针投射到float
并取消引用生成的float
指针,尽管它将violate strict aliasing rules位于
printf("(float*) : %f\n", *(float*)iptr);
这也是未定义的行为
答案 1 :(得分:3)
第一个是正确的。
i
是int
变量,iptr
是指向int
的指针。
(float)*iptr
:*iptr
取消引用iptr
,返回int
。然后将int
转换为包含相同值的临时float
。 float
使用printf
。
*(float*)iptr
:尝试将指向int
的指针转换为指向float
的指针。这是无效的,应该产生编译器警告或错误。它创建一个具有相同地址的指针,但其类型表示它指向float
值。
然后*
运算符取消引用它,因此int
被读取为float
。因此,结果float
将无效,并且可能导致段错误,因为float
s长于int
s,因此它读取的内存比为{{1}分配的内存更多}}
int
:同样的问题,但它没有取消引用(无效)指针,并将指向(float*)iptr
的指针传递到float
,而不是{ {1}}。但printf
需要float
。一些编译器也应该在这里产生警告/错误,因为格式字符串表示期望的值类型。
如果格式说明符指示printf
,则它需要指针(float
,%p
或任何其他指针。然后它将打印出地址,而不是它指向的值。例如,这在调试中很有用。