(浮动*)和&之间的差异C中的*(float *)

时间:2015-06-04 10:12:48

标签: c pointers casting

我试图深入理解指针概念。 在以下代码中,

#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*)的警告 我发现很难分析差异。如果有人可以帮我分析这三者的确切用法,那将会有所帮助。

2 个答案:

答案 0 :(得分:4)

区别在于

  1. 您正在取消引用int并将其投放到<{p>}中的float

    printf("(float)* : %f\n", (float)*iptr);
    

    没关系。

  2. 您正在将int指针强制转换为float指针,并且使用float说明符打印"%f"指针是未定义的行为,正确的说明符是打印指针是"%p",所以

    printf("(float*) : %f\n", (float*)iptr);
    

    错了,应该是

    printf("(float*) : %p\n", (void *) iptr);
    

    此处转换为float *没有意义,因为void *地址与float *地址以及int *地址相同,不同之处在于做指针算法。

  3. 您正在将int指针投射到float并取消引用生成的float指针,尽管它将violate strict aliasing rules位于

    printf("(float*) : %f\n", *(float*)iptr);
    

    这也是未定义的行为

答案 1 :(得分:3)

第一个是正确的。

iint变量,iptr是指向int的指针。

  1. (float)*iptr*iptr取消引用iptr,返回int。然后将int转换为包含相同值的临时floatfloat使用printf

  2. *(float*)iptr:尝试将指向int的指针转换为指向float的指针。这是无效的,应该产生编译器警告或错误。它创建一个具有相同地址的指针,但其类型表示它指向float值。

    然后*运算符取消引用它,因此int被读取为float。因此,结果float将无效,并且可能导致段错误,因为float s长于int s,因此它读取的内存比为{{1}分配的内存更多}}

  3. int:同样的问题,但它没有取消引用(无效)指针,并将指向(float*)iptr的指针传递到float,而不是{ {1}}。但printf需要float。一些编译器也应该在这里产生警告/错误,因为格式字符串表示期望的值类型。

    如果格式说明符指示printf,则它需要指针(float%p或任何其他指针。然后它将打印出地址,而不是它指向的值。例如,这在调试中很有用。