reinterpret_cast的C等价物是什么?

yruzcnhs  于 2023-10-16  发布在  其他
关注(0)|答案(8)|浏览(112)

C++中reinterpret_cast的C等价物是什么?

wj8zmpe1

wj8zmpe11#

int *foo;
float *bar;

// c++ style:
foo = reinterpret_cast< int * >(bar);

// c style:
foo = (int *)(bar);
nkoocmlb

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,正如我们所预期的那样。

gev0vcfq

gev0vcfq3#

C风格的强制转换看起来就像括号中的类型名称:

void *p = NULL;
int i = (int)p; // now i is most likely 0

显然,强制转换还有更好的用法,但这是基本语法。

4ioopgfo

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*'将丢弃限定符

pieyvz9o

pieyvz9o5#

C风格的演员阵容是:

int* two = ...;
pointerToOne* one = (pointerToOne*)two;
ghhaqwfi

ghhaqwfi6#

对于c,REINTERPRET运算符是什么:

#define REINTERPRET(new_type, var) ( * ( (new_type *)   & var ) )

我不喜欢说“reinterpret_cast”,因为cast意味着转换(在c中),而reinterpret意味着相反:没有转换。

hyrbngr7

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的扩展:

#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)),但这可能不是主题。
你可以在这里试试我的解决方案。
阿克塞尔

up9lanfz

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;

相关问题