【问题标题】:Type casting error in pointer in C [closed]C中指针中的类型转换错误[关闭]
【发布时间】:2016-12-14 13:56:40
【问题描述】:

我无法对指针进行类型转换。我发现了一个垃圾值 Y。 我在我的代码中做错了吗?请帮我找到我想要的输出

#include<stdio.h>

int main(){

    float x= 15;
    int *y;

    y=(int *)&x;

    printf("\tValue of X is : %f \n",x);
    printf("\tValue of y is : %d",*y);

    return 0;
}

输出

【问题讨论】:

  • 我的代码有问题吗? -- 是的,你在对编译器撒谎,float *int * 相同。
  • 未定义的行为。
  • A intfloat 是两种不同的类型。它们甚至不必是相同的大小。把一个地址当作另一个地址肯定会失败。
  • 你能给我正确的代码吗??
  • @ManashKumarMondal 如果您只想将浮点数的值存储在 int 中,那么为什么要使用指针?只需声明一个 int 并存储该值。

标签: c pointers types casting


【解决方案1】:

y=(int *)&amp;x; 如果您执行类似此值的操作,&amp;f 引用将不会转换为 float。你会得到float指针,它指向int

这是正确的方式:

int main()
{
    float x= 15;
    int *y = malloc( sizeof(int) ); // Allocate memory for int
    *y  =  int(x); // Convert to int and set as value which y pointing

    printf("\tValue of X is : %f \n",x);
    printf("\tValue of y is : %d",*y);

    free(y); // Free heap allocated memory
}

您还可以获得一些关于floatint 实现的信息

【讨论】:

  • 为什么还要创建一个指针? int y = (int)x; 就是你所需要的。
  • @NathanOliver 因为问题创建者需要“指针转换”。
  • 他在哪里说的?
  • NEW 和 PRINTF 在一起,为什么?
  • 这不是 C 。而第二句话完全错了。
【解决方案2】:
float x= 15;
int *y;
y=(int *)&x;
...
printf("\tValue of y is : %d",*y);

使用此代码,您是在告诉编译器您希望将float 值15.0 的位模式解释该模式作为int .正如其他人指出的那样,此代码会导致未定义的行为,这意味着任何结果都是可能的。 intfloat 具有不同的表示形式,它们可能(并且在许多平台上确实)具有不同的大小,并且可能具有不同的对齐要求。

不会做的是将浮点值15.0 转换为整数值15

假设大端、IEEE-754 32 位单精度 float15.0 的二进制表示将如下所示:

0 10000010 111000000000000000000
| |      | |                   |
| |      | +---------+---------+
| +--+---+           |
|    |               +----------- binary fraction 1.1112 (normalized)
|    +--------------------------- exponent (3, excess 127 notation)
+-------------------------------- sign bit
这也恰好是 integer1097859072 的位模式。

如果要将浮点数15.0 转换为整数15,只需执行以下操作:

float x = 15.0;
int y = x;    // no pointers involved at all

C会自动将浮点值15.0(表示为01000001011100000000000000000000<sub>2</sub>)转换为整数值15(表示为00000000000000000000000000001111<sub>2</sub>

请注意,在此转换中,小数部分被简单地丢弃;您将有效地向 0 舍入。

【讨论】:

    【解决方案3】:
    float x= 15;
    int *y;
    
    y =(int *)&x;
    

    float 的地址分配给指向int 的指针是未定义的行为,它们不是同一类型且不可互换,唯一允许这样做的类型是char *void * .

    改为:

    float x= 15;
    char *y;
    
    y = (char *)&x;
    
    printf("\tValue of X is : %f \n", x);
    printf("\tValue of y is : %d", (int)*(float *)y);
    

    float x= 15;
    void *y;
    
    y = &x;
    
    printf("\tValue of X is : %f \n", x);
    printf("\tValue of y is : %d", (int)*(float *)y);
    

    【讨论】:

      【解决方案4】:

      您正在尝试将指针类型转换为另一种类型的指针。

      为了了解您的失败,您需要了解计算机的内存是如何工作的。我会尽量用最短和最简单的方式向你解释。

      位序列可以用不同的方式解释:

      x: 01000010
      

      RAM 中的每个单元内存都有一个由变量类型赋予的含义。

      所以,例如:

      • 如果x 是一个整数,则01000010 的值将被解释为整数:66
      • 如果xchar,则该值将被解释为字符B,依此类推。

      你的代码有问题

      你在内存中分配了一个整数,所以:

      x: 15.0f // In decimal base, floating point
      

      如果您使用带有浮点指针的指针访问该内存,就像您的情况:

      float* y = (float*)&x
      

      那么相同位序列将被解释为整数值。

      确实,浮点有一种标准的位形式表示方式:wiki FP standard

      754 标准将值 15 存储为:

      01000001011100000000000000000000
      

      浮点数表示为 15.0,但 1097859072 为整数表示。

      你可以在DecimalConversion上测试它。

      【讨论】:

      • 所有这些都无关紧要,并且可能是错误的,具体取决于实现。 OP 调用 UB,'nuff 说。
      【解决方案5】:

      我刚刚做了一个小程序来测试一个猜测,我发现了你的问题

      #include <iostream>
      
      union test
      {
          float f;
          int i;
      }Test;
      
      int main()
      {
        union test t;
        t.f = 15;
        std::cout << t.i << std::endl;
      }
      

      果然,它打印了1097859072。这是因为整数和浮点数都是 32 位数字,而您所做的是告诉它“将我保存为浮点数的 0 和 1 的模式解释为整数”。当整数和浮点数下降到 0 和 1,甚至

      int x = 10;
      float y = 10;
      

      尽管数字相同,但 0 和 1 的模式将完全不同。您所做的不是有效的类型转换方式。 @Inline's 答案有一个正确的方法,这里是另一个:

        float x = 15;
        int y = (int)x;
      

      编辑: 我应该澄清一下,并非所有的整数都是 32 位的,但我可以通过我的小测试程序中的实验证据来判断你的整数。您可以使用sizeof(int) 获取系统上数据类型的大小(以字节为单位)以进行验证。

      【讨论】:

      • 这是因为整数和浮点数都是 32 位数字 它在哪里说的? int 可以小到 16 位。
      • 我可以看出他的整数是 32 位,因为如果您将联合中的 int i 更改为短整数(在我的系统上是 16 位),它会得到一个完全不同的数字(0 表示我)。他遇到的问题只有在他的 int 是 32 位时才有效。
      • 这是一个 C 问题,因此您应该提供一个 C 答案。
      • Union 是 C 数据类型,唯一的 C++ 部分使用了 cout,它与 printf("%d", t.i); 工作原理相同
      • "但我可以看出你的是通过实验证据" - 哦,你可以访问 OPs 计算机?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 2020-11-17
      • 1970-01-01
      • 2020-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多