C++中reinterpret_cast的C等价物是什么?
reinterpret_cast
wj8zmpe11#
int *foo; float *bar; // c++ style: foo = reinterpret_cast< int * >(bar); // c style: foo = (int *)(bar);
nkoocmlb2#
如果你可以获取值的地址,一种方法是将指向它的指针转换为指向不同类型的指针,然后解引用该指针。例如,float-to-int转换:
int main() { float f = 1.0f; printf ("f is %f\n", f); printf ("(int) f is %d\n", (int)f); printf ("f as an unsigned int:%x\n", *(unsigned int *)&f); }
输出量:
f is 1.000000 (int) f is 1 f as an unsigned int:3f800000
请注意,C标准可能无法保证这一点。无论如何,您不能使用reinterpret_cast将float转换为int,但对于支持的类型(例如,在不同的指针类型之间),这是类似的。不管怎样,让我们确认上面的输出是有意义的。http://en.wikipedia.org/wiki/Single_precision_floating-point_format#IEEE_754_single-precision_binary_floating-point_format:_binary32最后一个二进制答案:0011 1111 1000 0000 0000 0000 0000 0000这是IEEE-754浮点格式:符号位0,后面是8位指数(011 1111 1),后面是23位尾数(全为零)。要解释指数,减去127:0111111b = 127,127 - 127 = 0。指数为0。要解释尾数,请在1后面加上小数点:1.0000000000000000000000000(23个零)。这是十进制的1。因此,十六进制3f 800000表示的值是1 * 2^0 = 1,正如我们所预期的那样。
gev0vcfq3#
C风格的强制转换看起来就像括号中的类型名称:
void *p = NULL; int i = (int)p; // now i is most likely 0
显然,强制转换还有更好的用法,但这是基本语法。
4ioopgfo4#
它不存在,因为reinterpret_cast不能改变[constance][3]。比如说,
int main() { const unsigned int d = 5; int *g=reinterpret_cast< int* >( &d ); (void)g; }
将产生错误:dk.cpp:在函数'int main('中:dk.cpp:5:41:错误:reinterpret_cast从类型'const unsigned int*'到类型'int*'将丢弃限定符
pieyvz9o5#
C风格的演员阵容是:
int* two = ...; pointerToOne* one = (pointerToOne*)two;
ghhaqwfi6#
对于c,REINTERPRET运算符是什么:
REINTERPRET
#define REINTERPRET(new_type, var) ( * ( (new_type *) & var ) )
我不喜欢说“reinterpret_cast”,因为cast意味着转换(在c中),而reinterpret意味着相反:没有转换。
hyrbngr77#
我知道这个问题很老了,但不要忘记做这样的事情:
int a = 420; int* b = &a; printf("%f\n", *(double*)b);
是(不幸的是)大多数时候未定义的行为(即使它可能工作,在很多情况下可能是好的)。在某些情况下,它不是未定义的行为,例如,当您转换为char*或从void*转换时。请参阅cppreference和GCC的手册(甚至memmove页面)以获取更多信息。为了回答这个问题,除非类型是兼容的(根据C标准,这是唯一有效的情况下,你可以做前面提到的转换),一个可移植的方式来实现一个reinterpret_cast可以简单地memcpy(或memmove)从TYPE_1到TYPE_2(或与union +类型双关语)。例如GCC的扩展:
char*
void*
memmove
memcpy
union
#define reinterpret_cast(TO, VAR) \ ({ \ union \ { \ __typeof__((VAR)) source; \ TO dest; \ } u = { .source = (VAR) }; \ (TO)u.dest; \ })
我们甚至可以使用军用级的预处理器库(如chaos-pp及其预处理器fixdas)来实现更好的语法(如reinterpret_cast(uint32_t)(my_variable)),但这可能不是主题。你可以在这里试试我的解决方案。阿克塞尔
reinterpret_cast(uint32_t)(my_variable)
up9lanfz8#
在C中,你可以像对待任何其他类型一样自由地转换指针类型。待完成:
void *foo; some_custom_t *bar; other_custom_t *baz; /* Initialization... */ foo = (void *)bar; bar = (some_custom_t *)baz; baz = (other_custom_t *)foo;
8条答案
按热度按时间wj8zmpe11#
nkoocmlb2#
如果你可以获取值的地址,一种方法是将指向它的指针转换为指向不同类型的指针,然后解引用该指针。
例如,float-to-int转换:
输出量:
请注意,C标准可能无法保证这一点。无论如何,您不能使用reinterpret_cast将float转换为int,但对于支持的类型(例如,在不同的指针类型之间),这是类似的。
不管怎样,让我们确认上面的输出是有意义的。
http://en.wikipedia.org/wiki/Single_precision_floating-point_format#IEEE_754_single-precision_binary_floating-point_format:_binary32
最后一个二进制答案:
0011 1111 1000 0000 0000 0000 0000 0000
这是IEEE-754浮点格式:符号位0,后面是8位指数(011 1111 1),后面是23位尾数(全为零)。
要解释指数,减去127:0111111b = 127,127 - 127 = 0。指数为0。
要解释尾数,请在1后面加上小数点:1.0000000000000000000000000(23个零)。这是十进制的1。
因此,十六进制3f 800000表示的值是1 * 2^0 = 1,正如我们所预期的那样。
gev0vcfq3#
C风格的强制转换看起来就像括号中的类型名称:
显然,强制转换还有更好的用法,但这是基本语法。
4ioopgfo4#
它不存在,因为
reinterpret_cast
不能改变[constance][3]。比如说,将产生错误:
dk.cpp:在函数'int main('中:
dk.cpp:5:41:错误:reinterpret_cast从类型'const unsigned int*'到类型'int*'将丢弃限定符
pieyvz9o5#
C风格的演员阵容是:
ghhaqwfi6#
对于c,
REINTERPRET
运算符是什么:我不喜欢说“reinterpret_cast”,因为cast意味着转换(在c中),而reinterpret意味着相反:没有转换。
hyrbngr77#
我知道这个问题很老了,但不要忘记做这样的事情:
是(不幸的是)大多数时候未定义的行为(即使它可能工作,在很多情况下可能是好的)。在某些情况下,它不是未定义的行为,例如,当您转换为
char*
或从void*
转换时。请参阅cppreference和GCC的手册(甚至memmove
页面)以获取更多信息。为了回答这个问题,除非类型是兼容的(根据C标准,这是唯一有效的情况下,你可以做前面提到的转换),一个可移植的方式来实现一个
reinterpret_cast
可以简单地memcpy
(或memmove
)从TYPE_1到TYPE_2(或与union
+类型双关语)。例如GCC的扩展:
我们甚至可以使用军用级的预处理器库(如chaos-pp及其预处理器fixdas)来实现更好的语法(如
reinterpret_cast(uint32_t)(my_variable)
),但这可能不是主题。你可以在这里试试我的解决方案。
阿克塞尔
up9lanfz8#
在C中,你可以像对待任何其他类型一样自由地转换指针类型。
待完成: