diff --git a/faq/basic_concepts/type_conversion.rst b/faq/basic_concepts/type_conversion.rst index 9bae2410..a239bf07 100644 --- a/faq/basic_concepts/type_conversion.rst +++ b/faq/basic_concepts/type_conversion.rst @@ -4,6 +4,15 @@ 类型转换是指从一个类型的值转换得到另一个类型的值, 这个过程是生成了新的对象或引用, **原来的对象或引用保持不变**. +======================================================================================================================== +值保留类型转换和窄化类型转换 +======================================================================================================================== + +我们将 :cpp:`T` 类型的值转换为 :cpp:`U` 类型的值, 再从 :cpp:`U` 类型的值转换回 :cpp:`T` 类型的值. 经历这个过程后, + +- 如果新得到的 :cpp:`T` 类型值和原来的值相等, 则从 :cpp:`T` 到 :cpp:`U` 的转换称为值保留 (value-preserving) 类型转换. +- 如果新得到的 :cpp:`T` 类型值和原来的值不等, 则从 :cpp:`T` 到 :cpp:`U` 的转换称为窄化类型转换. + ======================================================================================================================== 隐式类型转换 ======================================================================================================================== @@ -25,30 +34,42 @@ sizeof(array) == sizeof(int) * 5; sizeof(array + 0) == sizeof(int*); +如果隐式类型转换是值保留的, 则称为提升 (promotion). + ------------------------------------------------------------------------------------------------------------------------ 常考的隐式类型转换 ------------------------------------------------------------------------------------------------------------------------ +以下内容 (很不幸地) 不是 C++ 所允许的全部隐式类型转换. + .. tabs:: .. tab:: 整型 - 整型提升, 以下是常考的点 + 整型提升 (integral promotion): 值保留类型转换 - 同等等级下, 有符号数转为无符号数. - - 窄于 :cpp:`int` 的整型 (:cpp:`char` 也是整型!) 在算术运算 (不含比较运算) 时会转换成 :cpp:`int` 或 :cpp:`unsigned int`, 所以 :cpp:`sizeof(char变量 + 1)` 其实是 :cpp:`sizeof(int)`. + - :cpp:`int` 表示了计算机在进行算术运算时最 "自然" 的大小, 因此 C 语言要求窄于 :cpp:`int` 的整型 (:cpp:`char` 也是整型!) 在算术运算 (不含比较运算) 时会转换成 :cpp:`int` 或 :cpp:`unsigned int`, 所以 :cpp:`sizeof(char变量 + 1)` 其实是 :cpp:`sizeof(int)`. + - :cpp:`bool` -> 其他整型 - -> :cpp:`bool` - - 非 0 -> :cpp:`true`. - - 0 -> :cpp:`false`. + - :cpp:`true` -> 1. + - :cpp:`false` -> 0. - -> 浮点数 - - 只要有可能, 转换为足够精确的数值, 例如整数 :cpp:`1` 转换为浮点数 :cpp:`1`. + 整型转换 (integral conversion): 窄化类型转换 + - 如果目标类型是无符号数 -> 当前的值 % 2^n 所表示的无符号数, 也就是直接截断前面的二进制位. + - 如果目标类型是有符号数, + + - 目标类型能表示当前的值 -> 当前的值. + - 不能 -> 当前的值 % 2^n 所表示的, 也就是直接截断前面的二进制位. + + - 如果目标类型是 :cpp:`bool`, - .. tab:: :cpp:`bool` + - 非 0 -> :cpp:`true`. + - 0 -> :cpp:`false`. - -> 其他整型 - - :cpp:`true` -> 1. - - :cpp:`false` -> 0. + - :cpp:`char` 类型可能采用 :cpp:`signed char` 或 :cpp:`unsigned char` 的表示方式; 但 :cpp:`char` 是独立的类型, 不是 :cpp:`signed char` 类型, 也不是 :cpp:`unsigned char`! + + -> 浮点数 + - 只要有可能, 转换为足够精确的数值, 例如整数 :cpp:`1` 转换为浮点数 :cpp:`1`. .. tab:: 浮点数