C++ 类型转换与推导总结测验

C++ 类型转换与推导总结测验

  1. 类型转换:把某值由一种数据类型变为另一种数据类型的过程称为“类型转换”。
  2. 隐式类型转换(implicit type conversion,又称自动转换或 coercion):当代码要求某类型却提供了另一类型时,若编译器知道如何转换,则自动完成;否则编译报错。
  3. 标准转换:C++ 内置的一系列转换规则,涵盖基本类型及部分高级类型,包括数值提升、数值转换与算术转换。
  4. 数值提升(numeric promotion):把某些较小数值类型转换为较大数值类型(通常为 intdouble),使 CPU 能以自然字长高效运算。含整型提升与浮点提升,保值无精度损失;并非所有加宽转换都是提升。
  5. 数值转换(numeric conversion):除数值提升外的基本类型间转换。
  6. 窄化转换(narrowing conversion):可能导致值或精度损失的数值转换。
  7. 算术转换(usual arithmetic conversions):某些二元运算符要求操作数同类型,编译器按规则隐式转换。
  8. 显式类型转换:程序员用 强制转换(cast)显式要求转换。C++ 提供 5 种 cast:C 风格 cast、static_castconst_castdynamic_castreinterpret_cast。一般应避免前三种;static_cast 最常用。
  9. typedef 与类型别名:为类型创建别名,并非新类型,与原类型完全等价,无额外类型安全。
  10. auto
    • 用于变量,可根据初始化式 类型推导(type deduction)。推导结果会丢弃顶层 const 和引用,需要时应手动添加。
    • 用于函数返回类型,可让编译器根据 return 语句推导;但普通函数建议显式返回类型。亦可用于 尾随返回类型语法

小测

问题 1

下列语句各发生何种转换?可选答案:无需转换、数值提升、数值转换、因窄化转换无法编译。假设 intlong 均为 4 字节。

int main()
{
    int  a { 5 };                      // 1a
    int  b { 'a' };                    // 1b
    int  c { 5.4 };                    // 1c
    int  d { true };                   // 1d
    int  e { static_cast<int>(5.4) };  // 1e

    double f { 5.0f };                 // 1f
    double g { 5 };                    // 1g

    // 附加题
    long  h { 5 };                     // 1h
    float i { f };                     // 1i(使用前述变量 f)
    float j { 5.0 };                   // 1j
}

答案 1a. 无需转换 1b. 数值提升(charint) 1c. 因窄化转换无法编译 1d. 数值提升(boolint) 1e. 数值转换(doubleint) 1f. 数值提升(floatdouble) 1g. 数值转换(intdouble) 1h. 数值转换(intlong) 1i. 数值转换(doublefloat,且因窄化无法编译) 1j. 数值转换(doublefloat,且因窄化无法编译)

问题 2

2a) 改写下列程序,使用类型别名表示“度”与“弧度”:

#include <iostream>

namespace constants
{
    constexpr double pi { 3.14159 };
}

double convertToRadians(double degrees)
{
    return degrees * constants::pi / 180;
}

int main()
{
    std::cout << "Enter a number of degrees: ";
    double degrees{};
    std::cin >> degrees;

    double radians { convertToRadians(degrees) };
    std::cout << degrees << " degrees is " << radians << " radians.\n";

    return 0;
}

参考答案

#include <iostream>

namespace constants
{
    constexpr double pi { 3.14159 };
}

using Degrees = double;
using Radians = double;

Radians convertToRadians(Degrees deg)
{
    return deg * constants::pi / 180;
}

int main()
{
    std::cout << "Enter a number of degrees: ";
    Degrees degrees{};
    std::cin >> degrees;

    Radians radians { convertToRadians(degrees) };
    std::cout << degrees << " degrees is " << radians << " radians.\n";

    return 0;
}

2b) 根据上题别名定义,解释为何下列语句能否通过编译:

radians = degrees;

解释: RadiansDegrees 均为 double 的别名,本质相同,因此赋值语法正确,编译通过。但语义上把“度”直接赋给“弧度”可能不符合逻辑,需由程序员自行确保正确性。

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"