我来自C#和Java的背景,但似乎无法理解在C++中使用指针进行强制类型转换的含义。
例如:
int x = 1;
char c = *((char*)&x);
它有什么作用?它有什么用处?
在你的两个示例中,你犯了一些错误导致代码无法编译。因此我假设你想要做以下操作:
int x = 1;
char c = *((char*)&x);
根据你的体系结构,c
现在将具有x
的最少或最重要字节的值。在这个例子中,这将是0或1(实际上可以用来检测字节顺序)。
你的第二个示例不会起作用,因为你试图忽略 const
导致非法操作/错误转换(这也称为“const正确性”)。
编辑:关于你的“什么意思?”的评论:
在表达式中:
&somevariable
将返回somevariable
的地址。
*somevariable
假设somevariable
的内容是实际值的地址,然后返回该地址的内容。
在声明中:
datatype
是一个普通的变量/对象。这是按值传递的。
datatype&
是一个引用。这与 Java/C# 中的普通变量完全相同,并通过引用传递。
datatype*
是指针。它只包含实际值所在的地址(参见上文),并且本质上也是通过引用传递的。
实际的强制转换与 Java/C# 非常相似,但指针就是指向实际值的位置。虽然这可能会让你感到困惑,但在 C/C++ 中指针的工作方式与 Java/C# 中使用的标准变量/引用完全相同。
看看这个:
MyClass x; // object of MyClass
MyClass *x; // pointer to an object of MyClass - the actual value is undefined and trying to access it will most likely result in an access violation (due to reading somewhere random).
MyClass *x = 0; // same as above, but now the default value is defined and you're able to detect whether it's been set (accessing it would essentially be a "null reference exception"; but it's actually a null pointer).
MyClass &x = MyClass(); // creating a new reference pointing to an existing object. This would be Java's "MyClass x = new MyClass();"
int x = 1;
char c = (char) x; // Lose precision
int x = 1;
char *c = (char *)x;
告诉编译器 x
的值是一个字符的地址。它等同于
char *c;
c = 1; // Set the address of c to 0x0000000000000001
很少有这种情况需要这样做。
在C++中,有两个根本不同的概念,有时都被称为“转换”:一个是转换,另一个是重新解释。
转换创建一个新对象,其“值”与现有对象相同,但类型不同。以下是一些示例:
示例1:类型提升
// 1a: promote int to double to get the correct type of division
int numerator = rand(), denominator = rand();
double d = double(numerator) / double(denominator);
// 1b: convert int to double to achieve a particular argument deduction
int n;
template <typename T> void do_numeric_stuff(T x) { /* ... */ }
do_numeric_stuff(double(n));
示例2:派生到基类的转换
struct B { }; struct D : B { };
D x;
D * p = &x; // pointer to x
B * q = p; // implicit conversion; may change the value!
std::ofstream file("output.bin"); // output file
char large_buffer[HUGE]; // in-memory buffer
unsigned int n = get_data();
char const * p = reinterpret_cast<char const *>(&n);
file.write(p, p + sizeof n); // write the bytes of `n`
std::copy(p, p + sizeof n, large_buffer); // ditto
std::copy(large_buffer + 17, large_buffer + 17 + sizeof n,
reinterpret_cast<char *>(&n)); // repopulate `n` from buffer
void*
中,然后将其转换回来并使用它是可以的,但不可以将float视为整数等进行操作。唯一可接受的访问一个对象的方式是我所演示的方式,即将类型为T
的对象视为数组char[sizeof(T)]
—— 也就是说,您可以访问每个对象的底层二进制表示。我曾经很久以前使用过这个习语来访问指定地址上的硬件,在自定义IO板上。例如,要写入PIC(可编程中断控制器)以重置某些标志(虚构代码):
#define PIC_LOC 0x1000
#define PIC_ENABLE_PORT *((char*)(PIC_LOC+0x10))
#define BIT_ENABLE (1 << 3)
...
PIC_ENABLE_PORT |= BIT_ENABLE;
...
无论如何,您都应该避免使用c类型转换,例如(char*)。如果您确实需要进行类型转换,请查看dynamic_cast、static_cast和reinterpret_cast。
但正如已经说明的那样,您很少需要进行转换。
在此处查看更多信息: http://www.cplusplus.com/doc/tutorial/typecasting/
http://www.parashift.com/c++-faq/static-typing-and-cpp.html
http://www.parashift.com/c++-faq-lite/print-char-or-ptr-as-number.html
char c = *((char*)x);
。 - CapelliC