【问题标题】:Type conversion with pointers使用指针进行类型转换
【发布时间】:2014-06-12 10:40:05
【问题描述】:

我不知道如何使用指针进行类型转换

double x = 0.7;
int *ptr = (int *)&x;

*(byte )&x 发生了什么? &x 表示变量x的地址。那么类型转换地址是什么意思呢?现在 ptr 也可以引用 x 吗?如果是,那么我们不会丢失数据吗?

还有 ptr 的大小是多少?

【问题讨论】:

  • 将 this 转换为 int 指针没有意义,因为您正在丢失信息。 Double 是 8 字节和 int 4。关于大小,指向任何东西的指针使用 4 或 8 字节,具体取决于架构,32 位或 64 位。
  • 你在 Quake 快速反平方根上吗?如果不是,您可能会觉得这很有趣。 Q_rsqrt。基本上,类型双关仅在内存布局相同的情况下才有效,而对于 int 和 float 则无效,因为它们使用不同的内存布局。
  • 你知道(byte *)&x*(byte )&x 是两个不同的东西吗?您似乎将它们视为相同的。

标签: c pointers casting pointer-conversion


【解决方案1】:

该行获取变量x 的地址并将其值存储到ptr。您必须进行分配,因为不允许将 double* 分配给 int*。

通过在赋值后取消引用ptr,您违反了别名规则并导致您的程序显示未定义的行为。

ptr 的大小等于sizeof( ptr )sizeof( int* ) 表达式的结果。

【讨论】:

  • 我不会称之为未定义的行为。因为如果您将其转换回原始类型,则信息仍然存在。这种类型的双关语其实很常见,一直用在socket编程中。
  • 您不必这样做,但标准可以。转回原始类型与这个问答无关。事实上,正如我所描述的,使用 ptr 是未定义的行为。
【解决方案2】:

让我们稍微重构一下你的代码:

#include <stdio.h>
#include <stdlib.h>


int main (void)
{
    int i;
    double d = 0.7;
    unsigned char* c = (unsigned char*)&d;

    for (i = 0; i < sizeof(d); i++) {
        printf("%x ", c[i]);
    }

    unsigned int* n = (unsigned int*) &d;

    printf("\n%x", *n);

    return 0;
}

上面的程序输出如下内容:

$ ./test.exe
66 66 66 66 66 66 e6 3f
66666666

那么类型转换地址是什么意思呢?现在ptr也可以参考 X?如果是,那么我们不会丢失数据吗?

基本上你所做的就是你把 &d 这是一个 double* 并将其转换为一个 int*。通过这样做,您将 &d 处的内存中的任何内容解释为 int。这不是将 double 类型转换为 int 的简单问题,而是重新解释整个内存布局。这可能在不同的机器上具有不同的输出,具体取决于它们的架构(32/64 位)和字节序。

【讨论】:

  • 如果我将某个东西定义为int i = 42; *((float *) &amp;i) = 3.14; 这意味着什么?
  • 表示你在i变量的地址写入3.14(覆盖其内容)。
  • 我的意思是你能一步一步地看一遍吗?从最里面的 &i 声明开始向外?
  • &i 是 i 的地址(类型为 int*)。您将其转换为 (float*)。然后你取消引用这个 float* 指针,在那里写一些东西。由于您将它用作浮点数,因此它的内部二进制表示将类似于浮点数(如 IEEE 754 浮点数en.wikipedia.org/wiki/IEEE_floating_point
  • @Dubby 不要忘记在你的代码中这样做会导致你的程序表现出未定义的行为,这可能会导致你的程序随机崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 2017-10-06
  • 2021-09-20
  • 1970-01-01
  • 2011-12-10
  • 2017-09-02
相关资源
最近更新 更多