C 参考手册
- C 语言
- C 的历史
- 基本概念
- 表达式
- 声明
- 初始化
- 函数
- 语句
- 静态断言
- 字符常量
- 函数声明
- 函数定义
- 转义序列
- 翻译阶段
- 标识符
- 作用域
- 生存期
- 查找与命名空间
- ASCII 码表
- 类型
- 遵从性
- 算术类型
- restrict 类型限定符
- 类型
- 对象与对齐
- 主函数
- 未定义行为
- 内存模型
- if 语句
- switch 语句
- for 循环
- while 循环
- do-while 循环
- continue语句
- break 语句
- goto语句
- return 语句
- 值类别
- 求值顺序
- 整数常量
- 浮点常量
- 字符串字面量
- 复合字面量
- 常量表达式
- 隐式转换
- 成员访问运算符
- 逻辑运算符
- 比较运算符
- 算术运算符
- 赋值运算符
- 自增/自减运算符
- 其他运算符
- sizeof 运算符
- _Alignof 运算符
- 转型运算符
- C 运算符优先级
- 泛型选择
- 标量初始化
- 数组初始化
- 结构体与联合体初始化
- 指针声明
- 数组声明
- 枚举
- 存储类指定符
- const 类型限定符
- volatile 类型限定符
- 结构体声明
- 联合体声明
- 位域
- _Alignas
- typedef 声明
- 原子类型
- 外部及试探性定义
- inline 函数指定符
- _Noreturn 函数指定符
- 变长参数
- 内联汇编
- 可分析性
- 替用运算符及记号
- C 关键词
- 预处理器
- C 标准库头文件
- 类型支持
- 程序支持工具
- 变参数函数
- 错误处理
- 动态内存管理
- 日期和时间工具
- 字符串库
- 算法
- 数值
- 文件输入/输出
- 本地化支持
- 原子操作库
- 线程支持库
- 实验性 C 标准库
- 有用的资源
- 符号索引
- 注释
转型运算符
进行显式类型转换。
语法
( type-name ) expression
|
|||||||||
其中
type-name | - | void 类型或任何标量类型 |
expression | - | 任何标量类型表达式(除非 type-name是 void ,此情况下它可以是任何表达式) |
解释
若 type-name 是 void ,则 expression 为其副效应求值,而其返回值被舍弃,与单独将 expression 用作表达式语句时相同。
否则,若 type-name 恰是 expression 的类型,则不做任何事(除非若 expression 拥有浮点类型,且它表示大于其范围和精度的值——见后述)。
否则,转换 expression 的值被到 type-name 所指名的类型,如下:
允许每种如同赋值的隐式转换。
另外还允许显示转换,允许下列转换规则:
- 任何整数能被转型到任何指针类型。除了如同 NULL 的空指针常量(这不需要转型),结果是实现定义的,可能对齐不准确,可能不指向所引用类型的对象,而且可能是一个陷阱表示。
- 任何指针类型可以被转型到任何整数类型。结果是实现定义的,即使是对空指针值(它们不必得到零值)。若结果不能被表示成目标类型,则行为未定义(无符号整数在从指针转型的情况下不实现模算术)。
- 任何指向对象的指针能被转型成指向任何其他对象类型的指针。若其值未为目标类型正确对齐,则行为未定义。否则,若其值转换回原类型,则它与原值比较相等。若指向对象指针被转型到指向任何字符类型的指针,则结果指向对象的最低字节,且能自增到目标类型的 sizeof (换言之,可用于检验对象表述,或通过 memcpy 或 memmove 复制)。
- 任何指向函数的指针能被转型成指向任何其他函数类型的指针。若转换结果指针回原类型,则它与原值比较相等。若将转换所得指针用作函数调用,则行为未定义(除非函数类型兼容)。
- 在指针间转换(指向对象或指向函数的)时,若原值是其类型的空指针值,则结果是目标类型的正确空指针值。
在任何场合(执行隐式转换和同类型转型时)中,若 expression 与 type-name 是浮点类型,且 expression 表示大于其类型所指示的范围和精度(见 FLT_EVAL_METHOD ),则剥除范围和精度以匹配目标类型。
转型表达式的值类别始终是非左值。
注意
因为 const 、 volatile 、 restrict 及 _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