C 整数转换规则

以下内容参考C语言参考手册第五版

    标量类型(算数类型和指针)可以转换为整数类型
    布尔转换 在C99中,涉及_Bool类型的转换与涉及其他整数类型的转换稍有不同。把算数类型转换为_Bool类型时,如果原值为0,转换后的值为0。否则,转换后的值就是1。把指针类型转换为_Bool,null指针转换为0,其他所有指针值被转换为1。把_Bool类型转换为算数类型时,其结果是转换到目标类型的0或1。在本节的剩余部分,除非另有所述,否则我们所提到的整数类型不包括_Bool类型。
       整数类型转换为整数类型 除了_Bool类型之外,从一种整数类型转换为另一种整数类型的基本规则是转换结果的数学值应该尽可能等于原先的数学值。例如,如果一个无符号整数值为15,把这个值转换为一种有符号整数类型时,所产生的值也应该是15。
       如果无法用新类型表示一个对象的原值,则存在两种情况。如果结果类型是有符号类型,则转换结果被认为是溢出,结果值从技术上来说是未定义的。如果结果类型是无符号类型,则转换结果必须是结果类型的一个独一无二的值,并且等于同余模数2^n减去原值,其中n是表示结果类型所使用的位数。如果有符号类型是用补码记法表示的,则相同长度的有符号类型和无符号类型转换时,不需要表示形式的改变。但是,如果有符号类型是用其他记法表示的,例如反码或符号绝对值表示形式,则需要更改表示形式。
       当一个无符号整数转换为一个相同长度的有符号整数时,如果原值太大,无法用有符号表示形式来表示,转换结果就被认为是溢出(即无符号数的高端位位1)。但是,许多程序员以及C程序依赖于静悄悄地执行这种转换,在不改变表示形式的情况下参数负数。
      如果目标类型的长度大于原类型,则结果类型无法表示原值的唯一情况就是当负的有符号值转换为一种更长的无符号类型的时候。在这种情况下,转换行为必须就像首先把原值转换为于目标类型相同长度的有符号类型,然后再转换为目标类型一样。
   ((unsigned long) -1) == ((unsigned)(((long) -1)))
       如果目标类型的长度小于原类型,并且原类型和目标类型都是无符号类型,则转换结果就是简单的截去原值的高位。结果表示形式的位模式将等于原表示形式的n歌低位,其中n是目标类型的位数。把采用补码表示形式的有符号整数转换为更短的无符号类型时,所使用的的丢弃规则与前面相同。这个丢弃规则也是把有符号或无符号整数转换为更短的有符号整数(采用补码表示)可以接受的价格方案之一。注意这个规则在发生溢出时,并不会保留符号位。不过溢出后的行为在任何情况下都没有定义。当有符号整数并不是采用补码表示时,转换就更为复杂。尽管C语言并没有强制要求用补码表示有符号整数,但它显然最适合使用找这种表示形式。
       当目标类型是_Bool时,所有非零的原值都被映射为1,只有原值0被转换为0。
       浮点数转换为整数类型,浮点数到整数类型的转换应该产生一个尽可能与原对象相等的值。如果浮点数有非0的小数部分,小数部分就丢弃。也就是说,这种转换一般设计浮点数的截断。如果浮点数甚至无法近似地用新类型来表示,转换的行为就是未定义的。例如,浮点数的主值太大或者把负的浮点数,转换为一种无符号整数类型。上溢和下溢的处理常常由编译器实现者决定。
       指针类型转为整数类型 当原值是个指针并且目标类型不是_Bool时,这个指针就被当做一种无符号整数类型,它的长度与这个指针的长度相同。然后,这个无符号整数使用前面所列出的规则转换为目标类型。如果null指针不用0表示,
当null指针转换为整数时必须显式地把转换为0。
         过去,C程序员假设指针可以转换为long类型并转换回来,而不丢失信息。尽管这几乎重视正确的,但它不是语言定义所要求的。在C99中,如果stint.h头文件定义了intptr_t和uintptr_t类型,它们分别表示可以保存指针值的有符号和无符号整数类型。问题是,有些计算机所使用的的执政类型的长度可能大于最长的整数类型。

你可能感兴趣的:(C语言参考手册)