类型转换和类型转化有什么区别吗?

7
在C++中,类型转换和类型转换之间有什么区别吗?
4个回答

13

通常情况下,casting 指的是显式转换,无论是使用 C 风格 cast (T(v) 或者 (T)v) 还是 C++ 风格 cast (static_cast, const_cast, dynamic_cast, 或者 reinterpret_cast)。Conversion 是一个更加通用的术语,用于描述任何变量被转换为另一个变量的情况:

std::string s = "foo"; // Conversion from char[] to char* to std::string
int i = 4.3; // Conversion from float to int
float *f = reinterpret_cast<float*>(&i); // (illegal) conversion from int* to float*

区别在于强制转换是明确的。C++的关键字可以被grep'ed。无论是C还是C++的转换,都表明了该转换是有意并经过程序员的同意。隐式转换可能是有意的,也可能是错误的。 - DevSolar

2

类型转换意味着您可以采取一串比特并以不同的方式解释它们。类型转换意味着您将一串比特从一个上下文中有用的配置转换为另一个上下文中有用的配置。

例如,假设我写了以下内容:

int x=65;
char c=(char) x;
char* s=(char*) x;

现在c将包含字符'A',因为如果我将十进制数65重新解释为字符,则会得到字母'A'。s现在将是一个指向存储在内存位置65处的字符字符串的指针。这几乎肯定是无用的事情,因为我不知道该内存位置上是什么。

itoa(x, s, 10);

这是一种类型转换,应该会给我字符串"65"。

也就是说,使用强制转换时,我们仍然查看相同的内存位置。我们只是以不同的方式解释那里的数据。而使用转换时,我们正在生成新数据,该数据源自旧数据,但它不同于旧数据。


那么你的意思是,reinterpret_cast 执行强制转换,但 static_cast(尽管它的名称)执行转换?我觉得这很令人困惑。 - jogojapan

1

类型转换可能会进行最少量的转换:

signed char Schar; // 1 byte (8 bits) to hold 256 values: -128 to 127
unsigned char Uchar; // 1 byte (8 bits) to hold 256 values: 0 to 255
...
if ( Schar < -10  ) ... // compiler uses SIGNED comparision
Uchar = Schar; // implicit conversion only copies the 8 bits
Uchar = (char) Schar; // explicit conversion may be required by compiler
if ( Uchar > 200 ) ... // compiler uses UNSIGNED comparision
...OR...
if ( (unsigned char) Schar > 200 ) ... // explicit conversion for UNSIGNED comparision

short Sshort; // 2 bytes (16 bits) to hold 65536 values: -32768 to 32767
unsigned short Ushort; // 2 bytes (16 bits) to hold 65536 values: 0 to 65536
...
// when moving 8 bits into 16 bit variables, what to do with other 8 bits ?
Sshort = (signed short) Uchar; // move 8 bits over and use 0s for other 8 bits
Sshort = (signed short) Schar; // same, but use 1s if negative to make Sshort negative

但这可能被视为类型转换:

float dbl; // 4 bytes to store floating number in IEEE format
long lng;  // 4 bytes to store 32 bit integer value in 2's complement format
...
dbl = lng; // convert from 2's comp to IEEE format - all bits change !
dbl = (float) lng; // explicit form

注意:int通常与编译器/CPU相关的shortlong相同。 注意:signed通常是可选的,因为这通常是默认值。

当您指定所有变量占用相同的内存空间时,不会进行任何转换:

typedef union MYUNION // all members occupy same space (memory bytes)
{
  signed char Schar; // usual default for char
  unsigned char Uchar;
  signed short Sshort; // usual default for short
  unsigned short Ushort;
  signed long Slong; // usual default for long
  unsigned long Ulong;
  float flt;
  double dbl;
};

MYUNION myunion;

myunion.Schar = ... // set variable (memory byte) to value

if ( (unsigned char) myunion.Schar > 200 ) ... // unsigned compare works ok
... is same as (also without moving any data around) ...
if ( myunion.Uchar > 200 ) ... // unsigned compare works ok

... myunion.Sshort ... // other 8 bits are UNASSIGNED GARBAGE !

myunion.Sshort = myunion.Schar; // provide all 16 bits from Schar
... myunion.Sshort ... // Sshort of valid now

myunion.dbl = 12345.0;
... myunion.Ulong ... // has weird value from odd IEEE bit format

myunion.Ulong = (unsigned long) myunion.dbl; // do explicit conversion
... myunion.Ulong ... // has CONVERTED 12345 value

注意:*(unsigned long*)&dbl也会产生奇怪的值。它做了以下几件事情: a)获取double dbl的地址(位和字节的位置) b)将该地址视为无符号长整型的地址 c)从该位置获取无符号长整型
当然,这种技术有一些真正的应用。例如:解析复杂的外部二进制文件或在只有512字节内存的CPU上等。

1

当你处理字符串时,会出现一个主要的区别。你不能说(int)"234"并获得整数234。类型转换通常只适用于原始数字数据类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接