【问题标题】:Casting two pointers (float* to int*)铸造两个指针(float* 到 int*)
【发布时间】:2015-01-08 14:09:22
【问题描述】:

我是一名 IT 学生,今天我参加了 C 编程考试。 其中一个问题有点令人困惑:是否可以将 float* 转换为 int* ? 我说没有,你怎么看?

【问题讨论】:

  • 你可以,你不能:看看 static_cast 和 reinterpret_cast
  • @BeyelerStudios 那是 C++,不是吗?
  • “你的意见是什么?” ——没有意见。可以将float* 转换为int*。它可能无法达到您的预期,但这并不意味着它无效或不可能;)
  • 是的,但它可能不安全,因为它破坏了strict-aliasing rule。除此之外,C 语言标准不强制sizeof(int)sizeof(float) 相等。所以在给定的平台上,如果它们不相等,那么即使不违反严格别名规则也是不安全的(使用指针来访问内存会产生未定义的行为)。
  • 看看here在实际生产代码中的使用情况。

标签: c pointers casting


【解决方案1】:

可以投射,但你不会神奇地得到浮点数的整数版本。

发生的情况是您在内存中的某处有一个浮点数,然后有一个整数指向同一位置。但两者的表示方式不同(例如,two's complementIEEE 754),因此您将得到一个截然不同的整数。

例如:

#include <stdio.h>

int main() {
  printf("sizeof(int) = %zu\n", sizeof(int));
  printf("sizeof(float) = %zu\n", sizeof(float));

  float m = 456.78f;
  int *p = (int*)&m;

  printf("Float:   %f\n", m);
  printf("Integer: %d\n", *p);

  return 0;
}

在我的系统上,这个输出:

sizeof(int) = 4
sizeof(float) = 4
Float:   456.779999
Integer: 1139041239

我也打印了它们的尺寸,以强调它们也可能不同。 例如,如果整数恰好更大,那么您将触摸浮点之外的内存。

虽然这可能不是您想要的,但它有一些用途。例如,如果您想查看特定浮点数的位表示,您可以将其转换为 uint8_t 之类的内容,然后检查到 sizeof(float)

【讨论】:

  • 我认为printf("sizeof(int) = %lu\n", sizeof(int)) 本身可能不安全。我不确定标准对size_t 的规定是什么,但如果在您的平台上long 是8 个字节而size_t 是4 个字节,那么对printf 的调用会带来麻烦。可能有一种更安全(更便携)的编写方式。根据this answer,你应该使用"%z")。
  • 谢谢,你是对的。我按照stackoverflow.com/questions/3168275/… 中的建议将其从%lu 更改为%zu(我知道PRIu 但实际上不知道%z,谢谢您的提示!)
  • 不客气。我自己刚刚了解到这一点,谷歌搜索“print size_t in c”:)
【解决方案2】:

为什么不试试看呢?

$ cat foo.c
#include <stdio.h>
int main(){
  float f = 0.15625;
  float *p = &f;
  printf("%f\n", *p);
  printf("%i\n", *((int *)p));
}
$ gcc foo.c
$ ./a.out
0.156250
1042284544

float 是 32 位的,您可以阅读其表示方式:http://en.wikipedia.org/wiki/Single-precision_floating-point_format

float 指针转换为int 指针只是告诉C“我指向的数据是int”。

float 0.156250 用二进制0111110001000000000000000000000 表示,它表示整数1042284544

编辑:@csl 击败了我 :)

【讨论】:

  • 是的,答案几乎相同。 :-)
  • 那是因为只有一个答案!只是想确保您获得第一名的荣誉。
猜你喜欢
  • 1970-01-01
  • 2011-04-03
  • 2010-12-27
  • 2023-02-05
  • 1970-01-01
  • 2011-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多