转换应该是什么意思?


18

当使用CI之类的低级语言进行编码时,发现强制转换有时意味着“重新解释这些字节,就像它一直是其他类型一样”,而在其他时候则是“将值智能地转换为其他类型”。

这个词的原始含义是什么,什么时候期望进行转换以及什么时候期望进行原始重新解释?


您不了解维基百科文章中的哪些内容?“ 类型转换类型转换强制转换是将一种数据类型的实体隐式或显式更改为另一种数据类型的不同方法。每种编程语言都有关于如何转换类型的规则...”
gnat

“强制转换”的原始含义与编程没有任何共同之处,请参见merriam-webster.com/dictionary/cast
Doc Brown

1
Eric Lippert的博客中很多类型(主要是从托管语言的角度来看)的转换运算符类别
AakashM 2014年

1
@gnat:我不确定这是一个严重的问题还是只是拖钓。但是我想知道如何知道编译器将执行什么操作:转换,强制转换还是强制转换?经验法则是什么?
2014年

1
@DocBrown我认为从cast计算意义上讲,该术语与从冶金意义上讲的铸造更相似,即浇铸到模具中时熔融金属的形状得以重整:britannica.com/EBchecked/topic/377665/metallurgy/81884/Casting
KChaloux 2014年

Answers:


10

用C进行转换是唯一的,与其他语言完全不同。它也永远不会聪明。

使用精心定义的规则,C语言中的转换将值从一种类型转换为另一种类型。如果您真的需要知道,请阅读标准。否则,主要要点是:

  1. 如果可能,整数类型之间的转换将保留该值。如果目标有更多位,这将扩大范围并且通常是安全的,但可能涉及符号扩展。如果更窄,位将丢失。
  2. 指针类型之间的转换保留了指针值,但是结果通常是不确定的,通常是不可移植的,并且通常对高级方案有用。
  3. 如果整数足够大,并且可以保留位模式(无论可能是什么意思),则整数类型和指针之间的转换就可以了。如果整数太小,则结果不确定,但无用。通常,“ long”对于“ void *”足够宽,但不能保证!以各种有趣的方式,以这种方式创建的指针可能无效。
  4. 浮点数和整数类型之间的转换是由适当的库例程定义的算术转换(使用截断而不是舍入)。
  5. 您可以将函数的返回值强制转换为void。我从来没有。它什么也没做。

有些强制转换是隐式应用的,在某些强制转换中,编译器将发出警告。最好注意警告!

最好忽略cast的字典定义,因为它是无用的。通过转换或强制术语可以更好地描述许多演员,因此也值得一读。

C ++更加复杂,但是您没有这样问,对吗?


我对经验法则感兴趣,而不是对细节的关注,但我对C语言以外的其他语言感兴趣,如果这有助于清理问题。
2014年

2
我在这里给出的是合理的通用性。要编写真实的,低级的专业C / C ++代码,微妙的细节至关重要。大多数语言在类型转换中都没有这种问题。很抱歉,如果不能解决您的问题。
david.pfx 2014年

除了往返T*之间的转换void*始终是明确定义的。
Miles Rout 2014年

@Miles:实际上,需要将T *转换为任何U *并返回,以保留原始指针值。在我的回答中,我只是说了“经常不确定”,以使其简短,“因为某些细节非常混乱。
david.pfx 2014年

1
@supercat:请参阅n1570 S6.3.2.3。在T *,U *和void *之间进行转换/往返总是保留指针值,只有一个例外。如果任何T *没有正确对齐,则为不确定的行为。我接受你的观点,但仅限于此。
david.pfx 2014年

2

Webster词典的这一部分给出了正确的定义:

a:通过将液体或塑料形式倒入模具中并使其在无压力的情况下硬化而使(某种物质)成形
b:通过该方法成型

因此,在投射之前,您的“对象”(实际上不是OOP对象)处于给定的形状(类型)。当您重新铸造时,即在其周围“浇筑混凝土”以使其变为新的形状,这就是铸造的工作方式。您有一个数字,是一个六边形的整数,转换后,您将得到一个矩形的字符串。


2
另外:“为(演员)分配特定角色”。
凯利·托马斯

对。我确定这是最好的。+1。
david.pfx 2014年

2

将C强制转换分为两组可能会很有用:

  1. 数值转换-将一个表示形式之间的数字转换为另一种表示形式,尝试保留该值。例如- (int)3.1将是3。有确切的规则定义当无法保留确切值时会发生什么。

  2. 指针强制转换-保留内存地址,但更改其取消引用的方式。例如,对于float x=3.5*(int *)&x将给出1080033280-此整数由表示float的相同位模式表示3.5


Keep the memory address, but change the way it's dereferenced.未定义取消引用类型标记的指针。该标准仅保证从A *to到B *back的转换将产生相同的结果A *,这在第一位置可能无效,或者如果B *为a char *,则可以将其用于读取任何类型的对象表示。对于所有其他类型,取消引用B *指针是类型操作,UB和&违反了严格的别名。无论如何,即使编译器由于这个原因而没有丢弃上面的示例2,您仍在对位模式进行不可移植的假设
underscore_d

1
cast (v): to receive form in a mold

在C ++中,可以使各种类型的转换更加明确,其reinterpret_cast含义是“将这些字节当作已经处理过的其他东西一样处理”。在C语言中,您可以通过使用绝对明确,使用运算符进行union强制转换(type)将尝试使结果在数值上相等,直到精度下降为止。


2
在C语言中,指针转换总是被重新解释,而值转换总是尽可能地保持价值。在C ++中,有多种方法可以进行指针转换,这就是为什么存在更明确的转换类型的原因。
Jan Hudec

C指针广播的语义不一定“重新解释”。对于使用字寻址但想与基于字节的代码很好地交互的处理器来说,具有int*一个字和一个两个字的处理器(char*第二个字节选择一个字的高字节或低字节)是合理的。转换为(int*)to (char*)将需要添加一个额外的单词,该单词的值应等于指定。的第一个字节的值int
超级猫2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.