转型运算符

< c‎ | language

进行显式类型转换。

语法

( type-name ) expression

其中

type-name - void 类型或任何标量类型
expression - 任何标量类型表达式(除非 type-namevoid ,此情况下它可以是任何表达式)

解释

type-namevoid ,则 expression 为其副效应求值,而其返回值被舍弃,与单独将 expression 用作表达式语句时相同。

否则,若 type-name 恰是 expression 的类型,则不做任何事(除非若 expression 拥有浮点类型,且它表示大于其范围和精度的值——见后述)。

否则,转换 expression 的值被到 type-name 所指名的类型,如下:

允许每种如同赋值的隐式转换

另外还允许显示转换,允许下列转换规则:

  • 任何整数能被转型到任何指针类型。除了如同 NULL 的空指针常量(这不需要转型),结果是实现定义的,可能对齐不准确,可能不指向所引用类型的对象,而且可能是一个陷阱表示
  • 任何指针类型可以被转型到任何整数类型。结果是实现定义的,即使是对空指针值(它们不必得到零值)。若结果不能被表示成目标类型,则行为未定义(无符号整数在从指针转型的情况下不实现模算术)。
  • 任何指向对象的指针能被转型成指向任何其他对象类型的指针。若其值未为目标类型正确对齐,则行为未定义。否则,若其值转换回原类型,则它与原值比较相等。若指向对象指针被转型到指向任何字符类型的指针,则结果指向对象的最低字节,且能自增到目标类型的 sizeof (换言之,可用于检验对象表述,或通过 memcpymemmove 复制)。
  • 任何指向函数的指针能被转型成指向任何其他函数类型的指针。若转换结果指针回原类型,则它与原值比较相等。若将转换所得指针用作函数调用,则行为未定义(除非函数类型兼容)。
  • 在指针间转换(指向对象或指向函数的)时,若原值是其类型的空指针值,则结果是目标类型的正确空指针值。

在任何场合(执行隐式转换和同类型转型时)中,若 expressiontype-name 是浮点类型,且 expression 表示大于其类型所指示的范围和精度(见 FLT_EVAL_METHOD ),则剥除范围和精度以匹配目标类型。

转型表达式的值类别始终是非左值。

注意

因为 constvolatilerestrict_Atomic 限定符仅对左值有效,到 cvr 限定或原子类型的转型准确等价于到对应无无限定类型的转型。

转型到 void 在令编译器关于未使用结果的警告沉默时有用。

不允许不列于此的转换。特别是,

  • 没有指针和浮点类型间的转换
  • 没有指向函数指针和指向对象指针(含 void* )间的转换
  • 没有指向函数指针和整数间的转换


示例

#include <stdio.h>
 
int main(void)
{
    // 检验对象表示是转型的合法使用
    double d = 3.14;
    printf("The double %.2f(%a) is: ", d, d);
    for(size_t n = 0; n < sizeof d; ++n)
        printf("0x%02x ", ((unsigned char*)&d)[n]);
 
    // edge cases
    struct S {int x;} s;
//    (struct S)s; // 错误;非标量类型
                   // 尽管转型到相同类型什么都不做
    (void)s; // 转换任何类型到 void 都 OK
}

可能的输出:

The double 3.14(0x1.91eb851eb851fp+1) is: 0x1f 0x85 0xeb 0x51 0xb8 0x1e 0x09 0x40

引用

  • C11 standard (ISO/IEC 9899:2011):
  • 6.5.4 Cast operators (p: 91)
  • C99 standard (ISO/IEC 9899:1999):
  • 6.5.4 Cast operators (p: 81)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 3.3.4 Cast operators

参阅