2012-12-06 93 views
8

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

在C,我不得不写类似的东西:

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

它是一个«C动态投»?它与C++的static_cast<int*>(p)相同吗?它要多少钱?

在此先感谢。

+2

...有关“非常”的适当定义... – DevSolar

+0

[C/C++编译器如何处理具有不同值范围的类型之间的类型转换?](https://stackoverflow.com/questions/340413/how-do-cc-compilers-handle-type-casting-between-types-with-different-value-ra) – jww

回答

7

C中的强制转换只在编译时有意义,因为它告诉编译器如何处理一段数据。它不会更改数据的实际值。例如,(int*)p告诉编译器将p视为一个整数的内存地址。然而,这在运行时不需要花费任何代价,处理器只是按照给它的方式处理原始数据。

+8

这对所有演员都不正确。 '(float)0.3'改变IEEE754系统上的值。它不再等于'0.3'。 –

+0

的确如此,谢谢。 – jazzbassrob

8

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

+1

它是从一个指针类型投射到另一个,但在这种情况下,'reinterpret_cast'与static_cast'做同样的事情。比如说,将一个double转换为一个整数可以起到真正的作用,并且不像'reinterpret_cast'。对我来说,与'static_cast'的比较似乎比'dynamic_cast'更合适。 – sepp2k

+0

@ sepp2k我已经更新了我的答案,以包含关于指针类型转换的观点。我不确定我是否同意你关于static指针和reinterpret转换的指针类型相同 - 编译器是否不检查静态转换是否在兼容类型之间? (虽然这可能正好相反,但我确实同意并注意到了你的主要观点) – simonc

+0

你说得对,'static_cast'只与编译时的'reinterpret_cast' **相同​​。 – sepp2k

2

指针是指针 - 铸造指针是一个noop。

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

它基本上是一个声明“让我们假设这是一个指向类型x的指针,用于将来的类型检查”。因为它不会执行额外的编译时间类型检查,例如,你可能会把它称为reinterpret_cast在C++方面,因为它不会执行额外的编译时间类型检查,例如, dynamic_caststatic_cast

我不认为C等于dynamic_cast(“insert runtime type check here”)或static_cast(“在此处执行额外的编译时类型检查”)。

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

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

与其说是一个演员,而是一个明确的类型转换

+0

好吧。所以它比其他任何东西更像是一个_compiler_ **提示**。 – phaazon

+0

对编译器来说不是一个“暗示”:它不会帮助编译器优化任何东西。但它是一个*程序员*的东西。我不让编译器*猜测*这是正确的,但我*明确指出*这应该被强制转换,而不是拼写错误;它只是告诉编译器,这不是一个错误,而是指这种方式。“ –

5

C演员阵容更像是所有C++风格演员阵容除了dynamic_cast组合。所以当你将一个int转换为另一个整数类型时,它是static_cast。当您将指针指向其他指针类型或整型时,或者相反,它是reinterpret_cast。如果你丢弃const,它是const_cast

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