← 练习册目录

第 2 章 变量、类型与流程控制

red wenzi · 2026-09-15 · 编程语言 · C++ · 练习册 · 19 题
📝 本章练习:19 题(A 识别 / B 理解 / C 改错 / D 写程序)。先自己做完再看答案——A、B 档不翻书做,C、D 档必须真的编译运行。

2.1 变量与初始化

A1识别判断题:int a; 不初始化就读取它的值,是未定义行为。

答:______________

✅ 查看答案与解析

答案 对

解析:C++ 不强制初始化局部变量,但不初始化就读是未定义行为。最省事的保证有值写法:int x{};(得到 0)。

A2识别判断题:int n{3.14}; 会编译报错。

答:______________

✅ 查看答案与解析

答案 对

解析:花括号初始化禁止窄化转换,3.14 塞进 int 会丢小数,编译器直接拦住。而 int n = 3.14; 只是警告,静默变成 3。

B1理解选择题:std::vector<int> v{5}; 创建的是什么?

5 个 0

1 个元素,值是 5

5 个 5

编译错误

答:______________

✅ 查看答案与解析

答案 B

解析:v{5} 是列表初始化:一个元素 5。而 v(5) 是构造函数:5 个 0。这是 vector 的经典误会,记住 {} 和 () 不一样。

C1应用改错题:下面代码静默丢掉小数部分,要求改成“要么编译报错、要么明确告诉编译器我要转换”。
double d = 3.9;
int i = d;      // 静默截断成 3,编译器可能只给警告
✅ 查看答案与解析

答案 int i = static_cast<int>(d); // 显式转换,语义清楚

解析:C++ 里推荐用四种命名转换(static_cast 等),别用 C 风格 (int)d,它把四种转换混在一起,出问题难查。

// 或者如果希望编译器拦住:int i{d};(窄化报错)
D1创造写程序:声明一个 int、一个 double、一个 std::string,分别初始化后输出它们的值。

提示:用花括号初始化;string 要 #include <string>。

✅ 查看答案与解析

答案 参考答案:

解析:输出:7 3.5 hi。

#include <iostream>
#include <string>
int main() {
    int n{7};
    double d{3.5};
    std::string s{"hi"};
    std::cout << n << ' ' << d << ' ' << s << '\n';
    return 0;
}

2.2 基本类型与溢出

A1识别判断题:C++ 里有符号整数溢出是未定义行为,编译器优化后结果可能完全无法预测。

答:______________

✅ 查看答案与解析

答案 对

解析:Java 里 int 溢出是回绕成确定的数;C++ 里溢出是未定义行为,必须主动避免。

A2识别判断题:Windows 64 位下,long 是 4 字节;Linux 64 位下是 8 字节。

答:______________

✅ 查看答案与解析

答案 对

解析:C++ 只保证 long 不小于 int。要精确宽度用 <cstdint> 的 int32_t / int64_t。

B1理解选择题:累加、乘法、下标计算一旦可能超过约 21 亿(2^31-1),应该用什么类型?

int

long long

short

bool

答:______________

✅ 查看答案与解析

答案 B

解析:int 最大约 21 亿;long long 至少 64 位,是算法题里的默认选择。

C1应用改错题:下面位运算在 int 上溢出,要求改成安全的写法。
int mask = 1 << 31;   // 对 int 是溢出(未定义行为)
✅ 查看答案与解析

答案 long long mask = 1LL << 31; // 先把 1 提升成 long long 再移位

解析:1 << 31 已经越过 int 的最高位。加 LL 后缀让字面量成为 long long,移位结果安全。

D1创造写程序:读入两个整数(可能很大),输出它们的乘积。

提示:读入用 long long 类型。

✅ 查看答案与解析

答案 参考答案:

解析:两数相乘可能超过 int 范围,用 long long 保险。

#include <iostream>
int main() {
    long long a, b;
    std::cin >> a >> b;
    std::cout << a * b << '\n';
    return 0;
}

2.3 运算符与流程控制

A1识别判断题:C++ 里 5 / 2 的结果是 2。

答:______________

✅ 查看答案与解析

答案 对

解析:整数除法向零取整,和 Java 相同。要小数结果必须让一边是浮点:5.0 / 2。

A2识别判断题:0.1 + 0.2 == 0.3 在 C++ 里结果为 true。

答:______________

✅ 查看答案与解析

答案 错

解析:浮点数二进制不精确,0.1+0.2 不等于 0.3。判等要用 fabs(a-b) < 1e-9 这类容差写法。

B1理解选择题:if (x = 5) 会怎么样?

编译错误

等价于 if (x == 5)

永远为真

永远为假

答:______________

✅ 查看答案与解析

答案 C

解析:= 是赋值,把 5 赋给 x,非零即真,所以永远为真。想比较要用 ==。编译器通常只给个警告。

C1应用改错题:下面的 switch 输入 '+' 时结果不对,找出原因。
switch (op) {
    case '+': result += v;
    case '-': result -= v;
    default: break;
}
✅ 查看答案与解析

答案 case '+' 和 case '-' 都缺 break,会“贯穿”执行。给每个 case 补 break。

解析:不加 break 会贯穿到下一个 case,这是 C 系语言的传统,也是经典 bug。

D1创造写程序:读入一个整数 n,输出它是奇数还是偶数。

提示:用 n % 2 判断。

✅ 查看答案与解析

答案 参考答案:

解析:条件必须是能转成 bool 的表达式。

#include <iostream>
int main() {
    int n;
    std::cin >> n;
    if (n % 2 == 0) { std::cout << "even\n"; }
    else { std::cout << "odd\n"; }
    return 0;
}

2.4 const 与 constexpr

A1识别判断题:constexpr 函数可以在编译期就算出结果。

答:______________

✅ 查看答案与解析

答案 对

解析:constexpr int square(int x) { return x*x; } 用编译期常量调用时,编译器直接算出结果,还能配 static_assert 做编译期断言。

B1理解选择题:定义常量时,优先级正确的顺序是?

宏 > constexpr > const

constexpr > const > 宏

const > constexpr > 宏

三者一样

答:______________

✅ 查看答案与解析

答案 B

解析:宏是纯文本替换,没有类型和作用域,能不用就不用;constexpr 能做编译期计算,优先于 const。

C1应用改错题:下面用宏定义常量和函数,要求改成现代 C++ 写法。
#define PI 3.14159
#define MAXN 100005
#define SQUARE(x) ((x) * (x))
✅ 查看答案与解析

答案 constexpr double PI = 3.14159;

解析:宏不参与类型检查、没有作用域;constexpr 编译期计算且类型安全。

constexpr int MAXN = 100005;
constexpr int square(int x) { return x * x; }
D1创造写程序:用 constexpr 定义数组长度,并写一个 constexpr 平方函数,用 static_assert 验证 5 的平方等于 25。

提示:static_assert(square(5) == 25); 写在 main 外面。

✅ 查看答案与解析

答案 参考答案:

解析:static_assert 在编译期检查,不满足直接编译失败。

#include <iostream>
constexpr int square(int x) { return x * x; }
static_assert(square(5) == 25);
int main() {
    constexpr int N = 100;
    int a[N]{};   // 编译期常量可以当数组长度
    std::cout << square(3) << '\n';   // 9
    return 0;
}
📚 相关概念:编译与链接 · STL · map / set · 迭代器