【问题标题】:What does a C cast really do?C 演员的真正作用是什么?
【发布时间】:2018-03-08 22:48:58
【问题描述】:

我编写了越来越多的 C 应用程序,现在我想知道关于强制转换的一些事情。在 C++ 中,动态转换是一项非常昂贵的操作(例如向下转换),但我什至不知道静态转换。

在 C 中,我不得不写这样的东西:

assert ( p ); /* p is void* */
int v = *(int*)p;

它是“C 动态转换”吗?是不是和C++的static_cast<int*>(p)一模一样?多少钱?

提前致谢。

【问题讨论】:

标签: c types casting


【解决方案1】:

C 中的强制转换仅在编译时才有意义,因为它告诉编译器您想如何操作一段数据。它不会改变数据的实际值。例如,(int*)p 告诉编译器将p 视为整数的内存地址。然而,这在运行时没有任何成本,处理器只是按照给它的方式处理原始数字。

【讨论】:

  • 这并不适用于所有演员表。 (float)0.3 更改 IEEE754 系统上的值。它不再等于0.3
【解决方案2】:

指针的 C 类型转换更像是 C++ reinterpret_cast。它指示编译器将变量视为不同类型,并且在运行时不花费任何成本。

【讨论】:

  • 这是从一种指针类型转换为另一种指针类型时,但在这种情况下,reinterpret_caststatic_cast 执行相同的操作。例如,将 double 转换为整数确实有效,与 reinterpret_cast 完全不同。对我来说,与static_cast 的比较似乎比dynamic_cast 更合适。
  • @sepp2k 我已经更新了我的答案,以包括您关于指针类型转换的观点。我不确定我是否同意您关于指针类型的静态和重新解释强制转换是相同的 - 编译器不检查静态强制转换是否在兼容类型之间? (虽然这可能是切线......我同意并注意到你的主要观点)
  • 你是对的,static_cast 仅与 reinterpret_cast 相同如果它编译。
  • @sepp2k 这也不正确。在 C++11 中,指向指针类型的 0reinterpret_cast 不一定会创建空指针。
【解决方案3】:

C 转换更像是所有 C++ 风格转换除了 dynamic_cast 的组合。因此,当您将 int 转换为另一个整数类型时,它是 static_cast。当您将指针转换为其他指针类型或整数类型或反之亦然时,它是reinterpret_cast。如果你扔掉一个const,它就是const_cast

C 没有类似于dynamic_cast 的东西,因为它具有对象类型的概念,并且也不会像 C++ 那样对它们有用(没有虚函数......)。关于解释对象位的类型只有在与 C 中引用对象的表达式结合时才变得重要。对象本身没有类型。

【讨论】:

    【解决方案4】:

    指针是指针 - 转换指针是一个 noop。

    之前是内存地址,之后是内存地址。

    它本质上是一个声明“让我们假设这是一个指向类型 x 以供将来类型检查的指针”。

    因此,您可以在 C++ 中将其称为 reinterpret_cast,因为它不会执行额外的 编译时间 类型检查,例如dynamic_caststatic_cast 可以。

    我认为 C 没有 dynamic_cast(“在此处插入运行时类型检查”)或 static_cast(“在此处执行额外的编译时类型检查”)等价物。

    请注意,对于 非指针,事情的表现会略有不同。

    int b = 1;
    double a = (double) b;
    

    与其说是强制类型转换,不如说是一种显式类型转换

    【讨论】:

    • 请注意,该标准确实明确保留了指向具有不同宽度的不同类型的指针的权利......虽然这是当今 8 位双补 IEEE 浮点架构世界中的一个奇特案例,语言律师可能会因为“noop”言论而追捕你。 ;-)
    • 好的,知道了。所以它更像是一个编译器 hint而不是别的什么?
    • 对编译器来说并不是真正的“提示”: - 它无助于编译器优化任何东西。但这是程序员的事情。我不让编译器猜测这是正确的,但我明确声明应该强制转换,而不是拼写错误;它只是告诉编译器这“不是错误,而是这种方式”。
    • C++ 在这里更进一步:dynamic_cast 告诉编译器执行额外的类型检查(在运行时),static_cast 告诉编译器检查强制转换,如果无法检查则失败(由编译器)。
    猜你喜欢
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    • 2011-08-19
    相关资源
    最近更新 更多