目录
类型转换规则
转换成整数(Conversions to Integer Types)
能转换成整数的类型包括算术类型(arithmetic)和指针类型(pointer)。
布尔型(_Bool)
C99引入了布尔类型_Bool,任何非零的算术类型和指针类型变量转换成布尔型时,值都是1;零值(如0,0.0,NULL指针)则转换成0。
反过来,当布尔型变量转换成算术类型时,值为1或0。
整型(Integer)
在将一种整型变量转换成另一种整型变量时,基本原则是保持其数学上的值不变(在可能的情况下)。比如,一个无符号数15,转换成一个有符号数,值也要是15。
当没法保持数学上的值不变时,根据目标类型的不同存在两种情况:
1. 目标类型是有符号数,则发生溢出(overflow),结果在技术上应该是未定义的。之所以说“应该“,是因为有些实现会悄然的将同尺寸的无符号数不做任何内部形式的改变,直接当做一个负数使用。
例如:
unsigned char a = 255; signed char b = a;
如果采用二进制补码,此时b的值为-1。
2. 目标类型是无符号数,则进行模2n运算(n是目标类型的bit数)。当目标类型的size大于原类型时(即将一个小尺寸的负数转换成一个大尺寸的无符号数),原类型要先提升为与目标类型相同大小的有符号数,再转换成目标类型。
例如:
signed char a = -1; unsigned short b = a;
如果采用二进制补码,当sizeof(unsigned short)=2时,b的值为65535,而不是255。
浮点型(Floating-point)
将浮点数转换成整数时,丢弃浮点数的小数部分,只保留整数部分。
如果浮点数的整数部分没法放在目标整数类型时,则结果是未定义的(undefined)。
指针类型(Pointer)
转换成浮点数(Conversions to Floating-Point Types)
只有算术类型(arithmetic)能转换成浮点型。
浮点型(Floating-point)
当从低精度的浮点数转换成高精度的浮点数时,如float到double,数值应该保持不变。
反过来,从高精度浮点数到低精度浮点数时,如果原值在目标类型的范围内,则结果是与原值最相近的两个值之一,是舍是入则由实现决定(implementation-dependant);当原值不在目标类型范围内,则发生溢出,结果未定义(undefined)。
整型(Integer)
如果整数能在浮点类型范围内精确表示,则结果等于该整数的浮点表示;如果不能精确表示,但仍在浮点类型范围内,则结果是与原值最相近的两个值之一;如果超出了浮点范围,则结果是未定义的。
复数类型(Complex)
C99增加了复数类型(Complex floating-point type),当在复数类型之间进行转换时,实部(real)和虚部(imaginary)分别按照浮点实数的转换规则进行。
转换成struct/union类型(Conversions to Struct and Union Types)
不同类型的struct/union不允许转换。
转换成枚举类型(Conversions to Enumeration Types)
与整数的转换规则一致。
转换成指针类型(Conversions to Pointer Types)
指针类型(Pointer)
一种类型的空指针(NULL)转换成另一种类型的指针时,结果依旧是空指针。
不同类型的指针可互相转换,但要分外小心,详情可参见:对齐限制(Alignment)。
整型(Integer)
整数0转换成指针,结果一定是空指针(NULL)。
其他整数转换时,目标指针被当做同尺寸的无符号整数类型,然后按之前的整数规则进行转换,不过这种转换是不可移植的(nonportable)。
数组(Array)
一个T类型的数组名能转换成一个指向T类型的指针,指针的值为该数组第一个元素的地址。
函数(Function)
一个返回值类型为T的函数,能转换成一个指向该函数的指针,指针类型为指向返回值类型为T的函数。
转换成数组/函数类型(Conversions to Array and Function Types)
不同类型的数组/函数不允许转换。
转换成void类型(Conversions to Void Types)
所有类型的值都能转换成void,一般只发生在要丢弃该值的场合。有关void的更多信息可参见:void的用法。