【问题标题】:Printing out the value from a Pointer in C从 C 中的指针打印出值
【发布时间】:2013-02-16 21:09:19
【问题描述】:

在以下示例中,我将如何打印出 u 中的值?我继续打印地址。

int example (float f) 
{ 
    unsigned int u = *(unsigned int*)&f;
    printf("The value in u is: %u\n", u);
}

编辑

我有这样的事情:

int example (float f) 
{ 
    unsigned int u = *(unsigned int*)&f;

    if((u&u) && u != MASK) {

     printf("The value in u is: %u\n", u);

     printf("The address in u is: %u" , u);
    }
}

int main ()
{
    example(3);
    return(EXIT_SUCCESS);
}

我遇到的问题是当我尝试检查并打印出“u”的值时。 我似乎无法将其打印出来。

【问题讨论】:

  • 您要打印什么?
  • 如果我要在 u 中输入一个值,例如:u = u&mask;如果我想查看 u 中的实际值,我将如何打印而不是获取地址?
  • 你想用unsigned int u = *(unsigned int*)&f; 达到什么目的?将 float 转换为 unsigned int?
  • 您的代码包含大量语法错误...
  • 该代码试图查看 float 中的数据在解释为整数时的样子——构成浮点数的位是什么。

标签: c pointers int printf


【解决方案1】:

这是您的代码的扩展,可以在 Mac OS X 10.7.5 上的 GCC 4.7.1 下编译并正常运行。

#include <stdio.h>
#include <inttypes.h>

static void example(float f) 
{ 
    unsigned int u = *(unsigned int*)&f;
    printf("%13.6e: %10u = 0x%08X (address 0x%08" PRIXPTR ")\n",
           f, u, u, (uintptr_t)&f);
}

int main(void)
{
    example(+3.14159F);
    example(+0.0);
    example(-0.0);
    example(+3.456789e24);
    example( 3.456789e-24);
    example(-3.456789e24);
    example(-3.456789e-24);
    return(0);
}

输出:

 3.141590e+00: 1078530000 = 0x40490FD0 (address 0x7FFF5FD3754C)
 0.000000e+00:          0 = 0x00000000 (address 0x7FFF5FD3754C)
-0.000000e+00: 2147483648 = 0x80000000 (address 0x7FFF5FD3754C)
 3.456789e+24: 1748435002 = 0x6837003A (address 0x7FFF5FD3754C)
 3.456789e-24:  411417185 = 0x1885BA61 (address 0x7FFF5FD3754C)
-3.456789e+24: 3895918650 = 0xE837003A (address 0x7FFF5FD3754C)
-3.456789e-24: 2558900833 = 0x9885BA61 (address 0x7FFF5FD3754C)

如您所见,我使用的是 64 位机器。您可以在十六进制中看到符号位在最高有效字节中;不太明显的是指数在接下来的 8 位,尾数在剩下的 23 位。

您的代码与我所展示的非常接近——一旦错别字被修正。您使用 MASK 的代码很神秘,因为您没有显示 MASK 是什么。但是,它应该打印几乎所有浮点值的信息,除了正零(因为u&amp;u 评估为假)或具有与MASK 匹配的位模式的一个特定浮点值。

对于我的代码,编译器会发出警告:

$ gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
      -Wold-style-definition x.c -o x
x.c: In function ‘example’:
x.c:6:5: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
$

这是另一个扩展,还有更多示例输出:

#include <stdio.h>
#include <inttypes.h>

static void example(float f) 
{ 
    unsigned int u = *(unsigned int*)&f;
    unsigned int s = u >> 31;
    unsigned int e = (u >> 23) & 0xFF;
    unsigned int m = (u >> 16) & 0x7F;
    printf("%13.6e: %10u = 0x%08X (s=%u, e=x%02X, m=0x%02X) (0x%08" PRIXPTR ")\n",
           f, u, u, s, e, m, (uintptr_t)&f);
}

int main(void)
{
    example(+3.14159F);
    example(+0.0);
    example(-0.0);
    example(+1.0);
    example(-1.0);
    example(+2.0);
    example(-2.0);
    example(+3.0);
    example(-3.0);
    example(+4.0);
    example(-4.0);
    example(+5.0);
    example(-5.0);
    example(+3.456789e24);
    example( 3.456789e-24);
    example(-3.456789e24);
    example(-3.456789e-24);
    return(0);
}

输出:

 3.141590e+00: 1078530000 = 0x40490FD0 (s=0, e=x80, m=0x49) (0x7FFF6112754C)
 0.000000e+00:          0 = 0x00000000 (s=0, e=x00, m=0x00) (0x7FFF6112754C)
-0.000000e+00: 2147483648 = 0x80000000 (s=1, e=x00, m=0x00) (0x7FFF6112754C)
 1.000000e+00: 1065353216 = 0x3F800000 (s=0, e=x7F, m=0x00) (0x7FFF6112754C)
-1.000000e+00: 3212836864 = 0xBF800000 (s=1, e=x7F, m=0x00) (0x7FFF6112754C)
 2.000000e+00: 1073741824 = 0x40000000 (s=0, e=x80, m=0x00) (0x7FFF6112754C)
-2.000000e+00: 3221225472 = 0xC0000000 (s=1, e=x80, m=0x00) (0x7FFF6112754C)
 3.000000e+00: 1077936128 = 0x40400000 (s=0, e=x80, m=0x40) (0x7FFF6112754C)
-3.000000e+00: 3225419776 = 0xC0400000 (s=1, e=x80, m=0x40) (0x7FFF6112754C)
 4.000000e+00: 1082130432 = 0x40800000 (s=0, e=x81, m=0x00) (0x7FFF6112754C)
-4.000000e+00: 3229614080 = 0xC0800000 (s=1, e=x81, m=0x00) (0x7FFF6112754C)
 5.000000e+00: 1084227584 = 0x40A00000 (s=0, e=x81, m=0x20) (0x7FFF6112754C)
-5.000000e+00: 3231711232 = 0xC0A00000 (s=1, e=x81, m=0x20) (0x7FFF6112754C)
 3.456789e+24: 1748435002 = 0x6837003A (s=0, e=xD0, m=0x37) (0x7FFF6112754C)
 3.456789e-24:  411417185 = 0x1885BA61 (s=0, e=x31, m=0x05) (0x7FFF6112754C)
-3.456789e+24: 3895918650 = 0xE837003A (s=1, e=xD0, m=0x37) (0x7FFF6112754C)
-3.456789e-24: 2558900833 = 0x9885BA61 (s=1, e=x31, m=0x05) (0x7FFF6112754C)

这就开始详细分析IEEE 754 single-pricision floating point format。引用的 Wikipedia 页面提供了更多信息,说明为什么我用于创建 sem 的值具有相关性(注意我正在使用 Intel 机器,因此这是小端数据)。

除了“逐渐下溢”值、零、无穷大和 NaN,“真实”尾数的第一位始终为 1,因此该格式实际上并未存储该值。您可以从 1、2、4 的值中看到这一点——与 3 和 5 形成对比(尽管 3 和 5 的二进制表示包含两个设置位,但它们中的每一个都在尾数中设置了一个位)。

【讨论】:

    猜你喜欢
    • 2011-01-29
    • 2013-10-29
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    相关资源
    最近更新 更多