C++ Primer 第五章:语句详解与实战练习

C++ Primer 第五章:语句详解与实战练习

Cpp-Primer C++ Primer 5 answers Cpp-Primer 项目地址: https://gitcode.com/gh_mirrors/cp/Cpp-Primer

前言

本文基于C++ Primer第五章内容,深入讲解C++中各种语句的使用方法、常见错误及最佳实践。作为C++基础语法的重要组成部分,掌握语句的正确使用对编写健壮、高效的代码至关重要。

空语句与块语句

空语句(Null Statement)

空语句是最简单的语句形式,仅由一个分号组成:

; // 空语句

使用场景

  • 作为占位符,当语法要求必须有语句但逻辑上不需要任何操作时
  • 循环体中不需要执行任何操作的情况

示例

// 读取输入直到遇到特定值或文件结束
while (cin >> s && s != sought)
    ; // 使用空语句作为循环体

块语句(Block)

块语句是由花括号包围的语句序列:

{
    statement1;
    statement2;
    // ...
}

关键特性

  • 可以包含零个或多个语句
  • 形成独立的作用域
  • 常用于需要执行多个语句但语法只允许单个语句的场合

示例

while (val <= 10) {
    sum += val;  // 多个语句需要放在块中
    ++val;
}

逗号运算符与代码可读性

逗号运算符允许在单个表达式位置写多个表达式,按顺序求值并返回最后一个表达式的值。

示例

while (val <= 10)
    sum += val, ++val;  // 使用逗号运算符合并两个表达式

可读性分析: 虽然逗号运算符可以减少代码行数,但会降低可读性。建议在简单逻辑中使用,复杂逻辑还是应该使用块语句。

条件语句常见错误

if语句常见问题

  1. 遗漏分号
if (ival1 != ival2) ival1 = ival2  // 错误:缺少分号
  1. 作用域不明确
if (ival < minval) 
    minval = ival;
    occurs = 1;  // 不在if作用域内
  1. 变量作用域问题
if (int ival = get_value())  // ival只在if作用域内有效
    cout << "ival = " << ival << endl;
if (!ival)  // 错误:ival已不可见
    cout << "ival = 0\n";
  1. 误用赋值运算符
if (ival = 0)  // 应该是ival == 0
    ival = get_value();

switch语句陷阱

  1. 忘记break导致case穿透
switch (ch) {
    case 'a': aCnt++;  // 没有break会继续执行下一个case
    case 'e': eCnt++;  // 无论ch是否为'e'都会执行
    default: iouCnt++;
}
  1. 变量初始化问题
switch (index) {
    case 1:
        int ix = get_value();  // 初始化可能被跳过
        ivec[ix] = index;
        break;
    default:
        ix = ivec.size()-1;  // ix可能未初始化
        ivec[ix] = index;
}
  1. case标签语法错误
switch (digit) {
    case 1, 3, 5, 7, 9:  // 错误:应该用多个case标签
        oddcnt++;
        break;
}
  1. 非常量case标签
unsigned ival=512;  // 必须为常量表达式
switch(swt) {
    case ival:  // 错误:case标签必须是常量
        bufsize = ival * sizeof(int);
        break;
}

循环语句最佳实践

while vs for循环选择

while循环适用场景

  • 不确定循环次数的情况
  • 基于条件的循环(如读取输入直到特定条件)

for循环适用场景

  • 已知循环次数或范围
  • 需要局部循环变量的情况

示例比较

// while风格
int i;
while (cin >> i) {
    // 处理i
}

// 等效for循环
for (int i; cin >> i;) {
    // 处理i
}

专家建议: 优先使用for循环,因为:

  1. 循环变量作用域限于循环内,减少命名冲突
  2. 初始化、条件和迭代操作集中在一处,更易维护
  3. 代码更紧凑

do-while循环注意事项

do-while循环保证循环体至少执行一次,但要注意:

  1. 条件中使用的变量必须在外部声明
  2. 不要将变量声明放在do块内而在while条件中使用

错误示例

do {
    int ival = get_response();  // 错误:ival在while条件中不可见
} while (ival);

跳转语句与异常处理

goto语句替代方案

goto语句容易导致代码结构混乱,应尽量避免。通常可以用循环结构替代:

goto版本

begin:
    int sz = get_size();
    if (sz <= 0) goto begin;

改进为for循环

for (int sz = get_size(); sz <= 0; sz = get_size())
    ; // 空循环体

异常处理基础

基本try-catch结构:

try {
    // 可能抛出异常的代码
    if (denominator == 0)
        throw runtime_error("Division by zero");
    result = numerator / denominator;
} catch (runtime_error err) {
    // 处理异常
    cout << err.what() << endl;
}

实战练习解析

重复单词统计

统计输入中连续重复次数最多的单词及其重复次数:

解决方案要点

  1. 使用两个string变量分别保存当前单词和前一个单词
  2. 维护当前重复计数和最大重复计数
  3. 遇到新单词时重置当前计数
  4. 每次重复时更新最大计数

除法异常处理

安全除法程序需要考虑除零异常:

关键实现

try {
    if (b == 0) throw runtime_error("Divide by zero");
    cout << a / b << endl;
} catch (runtime_error e) {
    cout << e.what() << endl;
}

总结

本章深入讲解了C++中各种语句的使用方法和最佳实践,重点包括:

  1. 空语句和块语句的正确使用场景
  2. 条件语句(if/switch)的常见陷阱和解决方案
  3. 循环语句(while/for/do-while)的选择标准和优化建议
  4. 跳转语句的替代方案和异常处理基础

通过理解这些概念并避免常见错误,可以编写出更健壮、更易维护的C++代码。建议读者结合实际练习巩固这些知识点,为后续更复杂的C++学习打下坚实基础。

Cpp-Primer C++ Primer 5 answers Cpp-Primer 项目地址: https://gitcode.com/gh_mirrors/cp/Cpp-Primer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔嫣忱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值