为什么浮点指针的取消引用设置为int变量的地址打印为“0”?

时间:2017-10-16 15:15:00

标签: c pointers

我在玩指针时创建了以下代码 -

#include <stdio.h>
int main()
{
    float a=1000;
    int *c=&a;
    float *d=&a;
    printf("\nValue of a is %f",a);
    printf("\nValue of a is %f",*c);
    printf("\nValue of a is %f",*d);
    printf("\nValue of a is %f",*&*c);
    printf("\nValue of a is %f\n",*&*d);

    int b=2000;
    int *e=&b;
    float *f=&b;
    printf("\nValue of b is %d",b);
    printf("\nValue of b is %d",*e);
             printf("\nValue of b is %d",*f);      //Will produce 0 output
             printf("\nValue of b is %d",*&*e);
             printf("\nValue of b is %d\n",*&*f);  //Will produce 0 output

             float g=3000;
             float *h=&g;
             printf("\nValue of g is %f\n",*h);
}

产生了输出 -

aalpanigrahi@aalpanigrahi-HP-Pavilion-g4-Notebook-PC:~/Desktop/C/Daily programs/pointers$ ./pointer004

Value of a is 1000.000000
Value of a is 1000.000000
Value of a is 1000.000000
Value of a is 1000.000000
Value of a is 1000.000000

Value of b is 2000
Value of b is 2000
Value of b is 0
Value of b is 2000
Value of b is 0

Value of g is 3000.000000

对于变量b 已声明为整数 * e和* f 为指针的第二部分,其值为b在 * f和*&amp; * f 的情况下打印为0(如代码所示)但这在上面的情况下有效,其中变量a 已被声明为浮点数。

为什么会这样?

2 个答案:

答案 0 :(得分:1)

此问题是系统所依赖的。 在某些平台中,您将收到0并且在某些平台中为-1。 这是因为您使用floatint打印为%d。 大多数平台中的float为4个字节(使用sizeof(float)进行检查)。 float数字2000的二进制值为01000100111110100000000000000000,并标记为float,因此当您尝试使用%d进行打印时,会遇到未定义的行为

答案 1 :(得分:0)

  

为什么会这样?

-shrugs-当你试图向后飞行飞机时会发生奇怪的事情,眼罩和耳塞进入。因此,你应该始终通过尽可能多地阅读来学习驾驶飞机你跳进驾驶舱。

摘掉眼罩和耳塞。睁开眼睛,开始读书。如果您已经在读书,请换一本新书,因为这本书不适合您。

printf("\nValue of a is %f",*c);是未定义的行为,因为尝试使用格式说明符来打印类型为int*c)的表达式,该格式说明符声称它是{{1} }}。 C11/7.21.6.1p9明确表示:

  

如果任何参数不是相应转换规范的正确类型,则行为未定义。

请注意,我并未暗示任何后果,无论是积极的还是消极的。它是未定义的行为,这意味着我们无法判断它是否能够正常工作。 (无论那意味着什么)或是否&#34;&#34;崩溃&#34;。

因此是UB的本质。你可能没有注意到这个错误,因为它&#34;工作&#34;但是它不需要......继续前进,我们来看你问的例子:

  

printf(&#34; \ n \ b的值是%d&#34;,* f);

类似的情况适用于此; double*f表达式,float告诉%d期望值scanf。行为是未定义的,这恰好意味着在这种情况下,你会看到一个令人困惑的&#34; 0&#34;。

您不能通过声明它不应该打印0来定义未定义。它允许打印0,因为您通过导致未定义的行为允许它。同样地,如果您发现崩溃,它可能会崩溃,因为您通过导致未定义的行为导致崩溃。

同样相关的是C11/6.5p7

  

对象的存储值只能由具有以下类型之一的左值表达式访问: 88)

     
      
  • 与对象的有效类型兼容的类型,   与对象的有效类型兼容的类型的限定版本,
  •   
  • 与对象的有效类型对应的有符号或无符号类型
  •   
  • 与对象的有效类型的限定版本对应的有符号或无符号类型的类型,
  •   
  • 聚合或联合类型,其成员中包含上述类型之一(包括递归地,子聚合或包含联合的成员),或者   一个字符类型。
  •   

因此,通常情况下,如果你正在施展某些你可能犯错的东西......一个常见的错误,例如不读书,所以... <...你正在读哪本书?