首页 > 编程语言 >《C++ Primer》导学系列:第 5 章 - 语句

《C++ Primer》导学系列:第 5 章 - 语句

时间:2024-06-18 12:58:20浏览次数:22  
标签:语句 std 示例 int 代码 C++ 导学 作用域 Primer

5.1 简单语句

5.1.1 基本概念

在C++中,简单语句是构成程序的基本单元。每个简单语句以分号(;)结束,可以是表达式、声明或空语句。

5.1.2 表达式语句

表达式语句是由表达式构成的语句,通常用于计算、赋值和函数调用。

示例代码
#include <iostream>

int main() {
    int a = 10;  // 赋值表达式语句
    a = a + 1;  // 计算并赋值
    std::cout << "a: " << a << std::endl;  // 函数调用语句

    return 0;
}

在这个示例中,每行代码都是一个表达式语句,执行赋值、计算和输出操作。

5.1.3 声明语句

声明语句用于声明变量、函数或类型,告诉编译器它们的存在和类型信息。

示例代码
#include <iostream>

int main() {
    int a = 10;  // 声明并初始化变量
    double b = 3.14;  // 声明并初始化变量
    std::cout << "a: " << a << ", b: " << b << std::endl;

    return 0;
}

在这个示例中,int adouble b是声明语句,它们声明并初始化了变量。

5.1.4 空语句

空语句仅由一个分号构成,不执行任何操作。通常用于需要语法上要求一个语句但实际不需要做任何事情的地方。

示例代码
#include <iostream>

int main() {
    int a = 0;
    while (a < 10) {
        ;  // 空语句,循环体不执行任何操作
        ++a;
    }
    std::cout << "a: " << a << std::endl;  // 输出 a 的值

    return 0;
}

在这个示例中,空语句用于while循环体,但没有实际操作。

5.1.5 复合语句(块)

复合语句由一对花括号{}包围的一系列语句组成,通常用于控制语句和函数体中。复合语句可以包含声明和其他语句,是形成控制结构的基础。

示例代码
#include <iostream>

int main() {
    int a = 0;
    {
        int b = 10;  // 复合语句中的声明
        a = a + b;  // 复合语句中的表达式
        std::cout << "Inside block: a: " << a << std::endl;
    }  // 复合语句的结束,b 的作用域结束

    std::cout << "Outside block: a: " << a << std::endl;

    return 0;
}

在这个示例中,复合语句(块)包含声明和表达式,块内的变量在块结束时作用域也结束。

重点与难点分析

重点

  1. 简单语句的种类和用法:理解表达式语句、声明语句和空语句的作用和用法。
  2. 复合语句的结构和作用:掌握复合语句的语法和应用场景,理解其在控制结构中的重要性。

难点

  1. 空语句的正确使用:初学者需要理解空语句的用途,避免在不适当的地方使用空语句。
  2. 复合语句中的作用域管理:掌握复合语句中变量的作用域,避免作用域混淆导致的错误。

练习题解析

  1. 练习5.1:编写一个包含多种简单语句的程序,输出结果。
  • 示例代码
#include <iostream>

int main() {
    int x = 5;  // 声明语句
    x = x + 2;  // 表达式语句
    ;  // 空语句
    std::cout << "x: " << x << std::endl;  // 函数调用语句

    return 0;
}

  1. 练习5.2:编写一个包含复合语句的程序,演示变量的作用域。
  • 示例代码
#include <iostream>

int main() {
    int a = 10;
    {
        int b = 20;
        a = a + b;
        std::cout << "Inside block: a: " << a << ", b: " << b << std::endl;
    }
    // b 的作用域结束,下面的代码会引发错误
    // std::cout << "Outside block: b: " << b << std::endl;  
    std::cout << "Outside block: a: " << a << std::endl;

    return 0;
}

总结与提高

本节总结

  1. 学习了简单语句的种类,包括表达式语句、声明语句和空语句,理解了它们在程序中的作用。
  2. 掌握了复合语句的结构和应用,理解了复合语句中变量的作用域。
  3. 理解了简单语句和复合语句的基本概念和用法,通过示例代码加深了对这些概念的理解。

提高建议

  1. 多练习简单语句的使用:通过编写各种包含不同简单语句的程序,熟悉它们的用法和作用。
  2. 深入理解复合语句中的作用域管理:通过实践掌握复合语句中变量作用域的管理,避免作用域混淆导致的错误。
  3. 优化代码结构:在编写代码时,合理使用复合语句组织代码,提高代码的可读性和维护性。

5.2 语句作用域

5.2.1 基本概念

在C++中,作用域(scope)定义了标识符(如变量、函数、类型等)在程序中可见和可访问的区域。理解作用域的概念有助于避免命名冲突和不必要的错误,提高代码的可读性和可维护性。

5.2.2 作用域类型

C++中主要有以下几种作用域:

  1. 全局作用域:在整个程序中都可见和可访问的标识符。
  2. 局部作用域:在函数或复合语句(块)内定义的标识符,仅在定义它们的块内可见。
  3. 类作用域:在类或结构体内定义的标识符,仅在该类或结构体的成员函数内可见。
  4. 命名空间作用域:在命名空间内定义的标识符,仅在该命名空间内可见。

5.2.3 全局作用域

全局作用域中的标识符在整个程序中都可见,通常在文件的最外层定义。

示例代码
#include <iostream>

int global_var = 100;  // 全局作用域变量

void func() {
    std::cout << "Global variable: " << global_var << std::endl;
}

int main() {
    std::cout << "Global variable in main: " << global_var << std::endl;
    func();
    return 0;
}

在这个示例中,global_var是一个全局作用域变量,在main函数和func函数中都可见和可访问。

5.2.4 局部作用域

局部作用域中的标识符在其定义的函数或块内可见,离开该块后不可见。

示例代码
#include <iostream>

void func() {
    int local_var = 10;  // 局部作用域变量
    std::cout << "Local variable in func: " << local_var << std::endl;
}

int main() {
    int local_var = 20;  // 局部作用域变量
    std::cout << "Local variable in main: " << local_var << std::endl;
    func();
    return 0;
}

在这个示例中,local_varmain函数和func函数中分别定义,并且只在各自的函数内可见。

5.2.5 类作用域

类作用域中的标识符在类或结构体的成员函数内可见。

示例代码
#include <iostream>

class MyClass {
public:
    MyClass(int val) : member_var(val) {}
    void display() {
        std::cout << "Member variable: " << member_var << std::endl;
    }
private:
    int member_var;  // 类作用域变量
};

int main() {
    MyClass obj(42);
    obj.display();
    return 0;
}

在这个示例中,member_var是类MyClass的成员变量,仅在类的成员函数display内可见。

5.2.6 命名空间作用域

命名空间作用域中的标识符在定义它们的命名空间内可见,可以避免全局命名冲突。

示例代码
#include <iostream>

namespace MyNamespace {
    int var = 50;  // 命名空间作用域变量
    void display() {
        std::cout << "Namespace variable: " << var << std::endl;
    }
}

int main() {
    MyNamespace::display();
    std::cout << "Namespace variable in main: " << MyNamespace::var << std::endl;
    return 0;
}

在这个示例中,vardisplay函数在命名空间MyNamespace内定义,只在该命名空间内可见。

重点与难点分析

重点:

  1. 作用域的基本概念:理解作用域的定义和作用,掌握不同类型的作用域及其应用场景。
  2. 局部和全局作用域:掌握局部和全局作用域的区别和使用方法,避免命名冲突和作用域混淆。
  3. 类作用域和命名空间作用域:理解类作用域和命名空间作用域的概念及其在实际编程中的应用。

难点

  1. 作用域管理:初学者需要通过实践理解作用域的管理,避免变量作用域混淆导致的错误。
  2. 命名空间的使用:掌握命名空间的定义和使用,特别是在大型项目中的应用,避免命名冲突。

练习题解析

  1. 练习5.3:编写一个包含全局变量和局部变量的程序,输出它们的值。
  • 示例代码
#include <iostream>

int global_var = 100;  // 全局变量

void func() {
    int local_var = 10;  // 局部变量
    std::cout << "Local variable in func: " << local_var << std::endl;
    std::cout << "Global variable in func: " << global_var << std::endl;
}

int main() {
    int local_var = 20;  // 局部变量
    std::cout << "Local variable in main: " << local_var << std::endl;
    std::cout << "Global variable in main: " << global_var << std::endl;
    func();
    return 0;
}

  1. 练习5.4:编写一个包含类作用域变量的程序,并在类的成员函数中输出其值。
  • 示例代码
#include <iostream>

class MyClass {
public:
    MyClass(int val) : member_var(val) {}
    void display() {
        std::cout << "Member variable: " << member_var << std::endl;
    }
private:
    int member_var;  // 类作用域变量
};

int main() {
    MyClass obj(42);
    obj.display();
    return 0;
}

  1. 练习5.5:编写一个使用命名空间的程序,定义命名空间变量并在命名空间内的函数中输出其值。
  • 示例代码
#include <iostream>

namespace MyNamespace {
    int var = 50;  // 命名空间变量
    void display() {
        std::cout << "Namespace variable: " << var << std::endl;
    }
}

int main() {
    MyNamespace::display();
    std::cout << "Namespace variable in main: " << MyNamespace::var << std::endl;
    return 0;
}

总结与提高

本节总结

  1. 学习了作用域的基本概念,理解了作用域在程序中的作用。
  2. 掌握了全局作用域、局部作用域、类作用域和命名空间作用域的定义和使用方法。
  3. 理解了不同作用域的应用场景,通过示例代码加深了对这些概念的理解。

提高建议

  1. 多练习不同作用域的使用:通过编写各种包含不同作用域的程序,熟悉它们的用法和作用。
  2. 深入理解作用域管理:通过实践掌握作用域的管理,避免变量作用域混淆导致的错误。
  3. 优化代码结构:在编写代码时,合理使用作用域管理变量和函数,提高代码的可读性和维护性,特别是在大型项目中使用命名空间避免命名冲突。

5.3 条件语句

5.3.1 基本概念

条件语句用于根据表达式的值来控制程序的执行流程。C++中的条件语句主要包括if语句和switch语句。

5.3.2 if语句

if语句根据一个条件表达式的布尔值决定是否执行一个代码块。if语句可以有一个可选的else分支和多个else if分支。

基本语法
if (condition) {
    // 当 condition 为 true 时执行的代码
} else if (another_condition) {
    // 当 another_condition 为 true 时执行的代码
} else {
    // 当所有条件都不满足时执行的代码
}

示例代码
#include <iostream>

int main() {
    int a = 10;

    if (a > 0) {
        std::cout << "a is positive" << std::endl;
    } else if (a == 0) {
        std::cout << "a is zero" << std::endl;
    } else {
        std::cout << "a is negative" << std::endl;
    }

    return 0;
}

在这个示例中,if语句检查a的值,并根据不同的条件执行不同的代码块。

5.3.3 switch语句

switch语句根据一个整数表达式的值选择要执行的代码块。每个代码块由一个或多个case标签标识,switch语句还可以包含一个可选的default标签。

基本语法
switch (expression) {
    case constant1:
        // 当 expression 等于 constant1 时执行的代码
        break;
    case constant2:
        // 当 expression 等于 constant2 时执行的代码
        break;
    default:
        // 当所有 case 都不匹配时执行的代码
}

示例代码
#include <iostream>

int main() {
    int a = 2;

    switch (a) {
        case 1:
            std::cout << "a is 1" << std::endl;
            break;
        case 2:
            std::cout << "a is 2" << std::endl;
            break;
        case 3:
            std::cout << "a is 3" << std::endl;
            break;
        default:
            std::cout << "a is not 1, 2, or 3" << std::endl;
    }

    return 0;
}

在这个示例中,switch语句检查a的值,并根据匹配的case标签执行相应的代码块。

5.3.4 嵌套条件语句

条件语句可以嵌套使用,即在一个条件语句的代码块中包含另一个条件语句。这种嵌套结构可以处理更复杂的条件判断。

示例代码
#include <iostream>

int main() {
    int a = 10;
    int b = 20;

    if (a > 0) {
        if (b > 0) {
            std::cout << "a and b are positive" << std::endl;
        } else {
            std::cout << "a is positive but b is not" << std::endl;
        }
    } else {
        std::cout << "a is not positive" << std::endl;
    }

    return 0;
}

在这个示例中,if语句嵌套在另一个if语句中,用于同时检查两个变量的值。

重点与难点分析

重点

  1. if语句的基本用法:掌握if语句的语法和用法,包括else ifelse分支的使用。
  2. switch语句的基本用法:理解switch语句的语法和用法,掌握case标签和default标签的使用。
  3. 嵌套条件语句:理解条件语句的嵌套用法,能够编写多层次的条件判断结构。

难点

  1. 条件语句的逻辑设计:初学者需要通过实践掌握条件语句的逻辑设计,确保条件判断的完整性和正确性。
  2. 避免代码重复和冗余:在使用条件语句时,应避免代码的重复和冗余,提高代码的可读性和维护性。

练习题解析

  1. 练习5.6:编写一个包含if-else语句的程序,根据用户输入的分数判断并输出相应的等级。
  • 示例代码
#include <iostream>

int main() {
    int score;
    std::cout << "Enter your score: ";
    std::cin >> score;

    if (score >= 90) {
        std::cout << "Grade: A" << std::endl;
    } else if (score >= 80) {
        std::cout << "Grade: B" << std::endl;
    } else if (score >= 70) {
        std::cout << "Grade: C" << std::endl;
    } else if (score >= 60) {
        std::cout << "Grade: D" << std::endl;
    } else {
        std::cout << "Grade: F" << std::endl;
    }

    return 0;
}

  1. 练习5.7:编写一个包含switch语句的程序,根据用户输入的月份输出相应的季节。
  • 示例代码
#include <iostream>

int main() {
    int month;
    std::cout << "Enter the month (1-12): ";
    std::cin >> month;

    switch (month) {
        case 12:
        case 1:
        case 2:
            std::cout << "Winter" << std::endl;
            break;
        case 3:
        case 4:
        case 5:
            std::cout << "Spring" << std::endl;
            break;
        case 6:
        case 7:
        case 8:
            std::cout << "Summer" << std::endl;
            break;
        case 9:
        case 10:
        case 11:
            std::cout << "Fall" << std::endl;
            break;
        default:
            std::cout << "Invalid month" << std::endl;
    }

    return 0;
}

  1. 练习5.8:编写一个嵌套if语句的程序,根据用户输入的年龄判断并输出相应的票价。
  • 示例代码
#include <iostream>

int main() {
    int age;
    std::cout << "Enter your age: ";
    std::cin >> age;

    if (age < 12) {
        std::cout << "Ticket price: $5" << std::endl;
    } else {
        if (age < 60) {
            std::cout << "Ticket price: $10" << std::endl;
        } else {
            std::cout << "Ticket price: $7" << std::endl;
        }
    }

    return 0;
}

总结与提高

本节总结

  1. 学习了条件语句的基本概念,掌握了if语句和switch语句的语法和用法。
  2. 理解了嵌套条件语句的结构和应用,能够编写多层次的条件判断结构。
  3. 通过示例代码和练习题,加深了对条件语句的理解和应用。

提高建议

  1. 多练习条件语句的使用:通过编写各种包含条件语句的程序,熟悉if语句和switch语句的用法。
  2. 深入理解条件语句的逻辑设计:通过实践掌握条件语句的逻辑设计,确保条件判断的完整性和正确性。
  3. 优化条件语句的结构:在编写条件语句时,避免代码的重复和冗余,提高代码的可读性和维护性。

5.4 迭代语句

5.4.1 基本概念

迭代语句,也称为循环语句,用于反复执行某段代码,直到满足特定条件为止。C++提供了三种主要的迭代语句:while循环、do while循环和for循环。

5.4.2 while循环

while循环在每次迭代之前测试条件表达式,如果条件为真,则执行循环体;如果条件为假,则退出循环。

基本语法
while (condition) {
    // 循环体
}

示例代码
#include <iostream>

int main() {
    int i = 0;

    while (i < 5) {
        std::cout << "i: " << i << std::endl;
        ++i;
    }

    return 0;
}

在这个示例中,while循环打印变量i的值,直到i不再小于5。

5.4.3 do while循环

do while循环与while循环类似,但不同的是,do while循环在每次迭代之后测试条件表达式。这意味着do while循环至少执行一次。

基本语法
do {
    // 循环体
} while (condition);

示例代码
#include <iostream>

int main() {
    int i = 0;

    do {
        std::cout << "i: " << i << std::endl;
        ++i;
    } while (i < 5);

    return 0;
}

在这个示例中,do while循环确保循环体至少执行一次,即使初始条件为假。

5.4.4 for循环

for循环通常用于需要明确控制循环变量的迭代次数的情况。for循环包含初始化语句、条件表达式和迭代语句。

基本语法
for (initialization; condition; iteration) {
    // 循环体
}

示例代码
#include <iostream>

int main() {
    for (int i = 0; i < 5; ++i) {
        std::cout << "i: " << i << std::endl;
    }

    return 0;
}

在这个示例中,for循环打印变量i的值,从0到4。

5.4.5 范围for语句

C++11引入了范围for语句(range-based for loop),用于遍历数组或其他容器。范围for语句使代码更加简洁和可读。

基本语法
for (declaration : expression) {
    // 循环体
}
  • declaration是用于引用容器元素的变量声明。
  • expression是一个可迭代的容器或范围。

示例代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    for (int value : vec) {
        std::cout << "value: " << value << std::endl;
    }

    return 0;
}

在这个示例中,范围for循环遍历vec中的每个元素,并输出其值。

重点与难点分析

重点

  1. while循环和do while循环:掌握while循环和do while循环的基本语法和用法,理解它们的区别。
  2. for循环:理解for循环的基本语法,掌握初始化语句、条件表达式和迭代语句的作用。
  3. 范围for语句:掌握范围for语句的用法,理解其在遍历容器中的优势。

难点

  1. 循环控制:初学者需要通过实践掌握循环控制,包括循环的初始化、条件判断和迭代更新。
  2. 范围for语句的应用:熟悉范围for语句的语法和应用场景,特别是在处理标准库容器时的应用。

练习题解析

  1. 练习5.9:编写一个while循环,计算并输出1到10的和。
  • 示例代码
#include <iostream>

int main() {
    int sum = 0;
    int i = 1;

    while (i <= 10) {
        sum += i;
        ++i;
    }

    std::cout << "Sum: " << sum << std::endl;
    return 0;
}

  1. 练习5.10:编写一个do while循环,反复读取用户输入,直到输入0为止。
  • 示例代码
#include <iostream>

int main() {
    int number;

    do {
        std::cout << "Enter a number (0 to exit): ";
        std::cin >> number;
    } while (number != 0);

    std::cout << "Goodbye!" << std::endl;
    return 0;
}

  1. 练习5.11:编写一个for循环,输出1到10的平方。
  • 示例代码
#include <iostream>

int main() {
    for (int i = 1; i <= 10; ++i) {
        std::cout << "Square of " << i << " is " << i * i << std::endl;
    }

    return 0;
}

  1. 练习5.12:编写一个使用范围for语句的程序,输出数组中的每个元素。
  • 示例代码
#include <iostream>

int main() {
    int arr[] = {1, 2, 3, 4, 5};

    for (int value : arr) {
        std::cout << "value: " << value << std::endl;
    }

    return 0;
}

总结与提高

本节总结

  1. 学习了迭代语句的基本概念,掌握了while循环、do while循环和for循环的语法和用法。
  2. 理解了范围for语句的结构和应用,能够使用范围for语句遍历数组和标准库容器。
  3. 通过示例代码和练习题,加深了对迭代语句的理解和应用。

提高建议

  1. 多练习迭代语句的使用:通过编写各种包含迭代语句的程序,熟悉while循环、do while循环、for循环和范围for语句的用法。
  2. 深入理解循环控制:通过实践掌握循环的初始化、条件判断和迭代更新,确保循环的正确执行。
  3. 优化循环的效率:在编写循环时,注意循环的效率和性能,避免不必要的计算和重复操作,提高代码的执行效率。

5.5 跳转语句

5.5.1 基本概念

跳转语句用于在程序中改变控制流,直接跳转到程序的另一个部分。C++中的主要跳转语句包括breakcontinuegotoreturn和异常处理相关的throw

5.5.2 break语句

break语句用于立即终止所在的循环或switch语句,并跳转到紧接着循环或switch语句后的语句。

示例代码
#include <iostream>

int main() {
    for (int i = 0; i < 10; ++i) {
        if (i == 5) {
            break;  // 当 i 等于 5 时,跳出循环
        }
        std::cout << "i: " << i << std::endl;
    }

    std::cout << "Loop ended." << std::endl;
    return 0;
}

在这个示例中,当i等于5时,break语句终止for循环。

5.5.3 continue语句

continue语句用于跳过当前循环迭代的剩余部分,并继续执行下一次循环迭代。

示例代码
#include <iostream>

int main() {
    for (int i = 0; i < 10; ++i) {
        if (i % 2 == 0) {
            continue;  // 跳过偶数
        }
        std::cout << "i: " << i << std::endl;
    }

    return 0;
}

在这个示例中,continue语句跳过偶数的输出,只输出奇数。

5.5.4 goto语句

goto语句用于无条件跳转到程序中的指定标签。尽管goto语句很强大,但滥用会导致代码难以阅读和维护,因此通常应避免使用。

示例代码
#include <iostream>

int main() {
    int i = 0;

start:
    std::cout << "i: " << i << std::endl;
    ++i;
    if (i < 5) {
        goto start;  // 跳转到标签 start
    }

    return 0;
}

在这个示例中,goto语句跳转到标签start,实现了一个简单的循环。

5.5.5 return语句

return语句用于终止函数的执行,并将控制权返回给调用函数。return语句可以带有一个返回值,该值将作为函数调用的结果。

示例代码
#include <iostream>

int add(int a, int b) {
    return a + b;  // 返回两个整数的和
}

int main() {
    int result = add(5, 3);
    std::cout << "Result: " << result << std::endl;
    return 0;
}

在这个示例中,return语句将add函数的结果返回给调用者。

5.5.6 throw语句

throw语句用于抛出一个异常,使程序跳转到最近的异常处理器。异常处理在第18章详细讨论,这里只作简单介绍。

示例代码
#include <iostream>
#include <stdexcept>

int main() {
    try {
        throw std::runtime_error("An error occurred");  // 抛出异常
    } catch (const std::runtime_error& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }

    return 0;
}

在这个示例中,throw语句抛出一个std::runtime_error异常,并在catch块中捕获和处理。

重点与难点分析

重点

  1. break和continue语句:掌握breakcontinue语句的基本用法,理解它们在循环中的作用。
  2. goto语句:了解goto语句的用法和潜在问题,避免滥用。
  3. return语句:理解return语句的基本用法,掌握其在函数中的作用。
  4. throw语句:初步了解throw语句的用法,理解其在异常处理中的作用。

难点

  1. 跳转控制:初学者需要通过实践掌握不同跳转语句的控制流,理解它们在程序中的具体应用场景。
  2. 异常处理:虽然throw语句在本章只是简单介绍,但理解其在异常处理中的作用是一个难点,需要在后续章节中深入学习。

练习题解析

  1. 练习5.13:编写一个程序,使用break语句终止循环。
  • 示例代码
#include <iostream>

int main() {
    for (int i = 0; i < 10; ++i) {
        if (i == 7) {
            break;  // 当 i 等于 7 时,跳出循环
        }
        std::cout << "i: " << i << std::endl;
    }

    std::cout << "Loop ended." << std::endl;
    return 0;
}

  1. 练习5.14:编写一个程序,使用continue语句跳过循环中的某些迭代。
  • 示例代码
#include <iostream>

int main() {
    for (int i = 0; i < 10; ++i) {
        if (i % 3 == 0) {
            continue;  // 跳过能被 3 整除的数字
        }
        std::cout << "i: " << i << std::endl;
    }

    return 0;
}

  1. 练习5.15:编写一个程序,使用goto语句实现循环,并注意避免滥用。
  • 示例代码
#include <iostream>

int main() {
    int i = 0;

start:
    std::cout << "i: " << i << std::endl;
    ++i;
    if (i < 5) {
        goto start;  // 跳转到标签 start
    }

    return 0;
}

  1. 练习5.16:编写一个包含return语句的函数,并调用该函数输出其返回值。
  • 示例代码
#include <iostream>

int multiply(int a, int b) {
    return a * b;  // 返回两个整数的乘积
}

int main() {
    int result = multiply(4, 5);
    std::cout << "Result: " << result << std::endl;
    return 0;
}

  1. 练习5.17:编写一个程序,使用throw语句抛出一个异常,并在catch块中处理该异常。
  • 示例代码
#include <iostream>
#include <stdexcept>

int main() {
    try {
        throw std::runtime_error("An error occurred");  // 抛出异常
    } catch (const std::runtime_error& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }

    return 0;
}

总结与提高

本节总结

  1. 学习了跳转语句的基本概念,掌握了breakcontinuegotoreturnthrow语句的用法。
  2. 理解了跳转语句在控制程序流中的作用,并通过示例代码加深了对这些概念的理解。
  3. 初步了解了异常处理中的throw语句,理解其在异常处理中的作用。

提高建议

  1. 多练习跳转语句的使用:通过编写各种包含跳转语句的程序,熟悉breakcontinuegotoreturnthrow语句的用法。
  2. 深入理解跳转控制:通过实践掌握跳转语句的控制流,理解它们在程序中的具体应用场景。
  3. 避免滥用goto语句:在编写代码时,应尽量避免使用goto语句,以提高代码的可读性和维护性。
  4. 学习异常处理:后续章节中将深入学习异常处理,掌握throw语句及其相关的异常处理机制。

5.6 try语句块和异常处理

5.6.1 基本概念

异常处理是C++中用于应对程序运行过程中出现的错误情况的一种机制。通过异常处理,可以将错误与正常的代码逻辑分开,使程序更加健壮和易于维护。异常处理的核心机制包括try语句块、throw语句和catch语句。

5.6.2 try语句块

try语句块用于包围可能引发异常的代码。当try语句块中的代码抛出异常时,程序控制流将转移到相应的catch块中。

基本语法
try {
    // 可能引发异常的代码
} catch (exceptionType1 e1) {
    // 处理 exceptionType1 类型的异常
} catch (exceptionType2 e2) {
    // 处理 exceptionType2 类型的异常
}

5.6.3 throw语句

throw语句用于抛出一个异常,使程序跳转到最近的匹配catch块。throw语句可以抛出任意类型的对象,但通常抛出派生自std::exception的异常对象。

基本语法
throw exceptionObject;

示例代码
#include <iostream>
#include <stdexcept>

int divide(int a, int b) {
    if (b == 0) {
        throw std::runtime_error("Division by zero");  // 抛出异常
    }
    return a / b;
}

int main() {
    try {
        int result = divide(10, 0);
        std::cout << "Result: " << result << std::endl;
    } catch (const std::runtime_error& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }

    return 0;
}

在这个示例中,divide函数在除数为零时抛出std::runtime_error异常,并在main函数中捕获和处理该异常。

5.6.4 catch语句

catch语句用于捕获由try块抛出的异常,并执行处理代码。一个try块可以有多个catch块,每个catch块处理不同类型的异常。

基本语法
catch (exceptionType e) {
    // 处理异常的代码
}

示例代码
#include <iostream>
#include <stdexcept>

int main() {
    try {
        throw std::runtime_error("An error occurred");
    } catch (const std::runtime_error& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    } catch (const std::exception& e) {
        std::cout << "Caught general exception: " << e.what() << std::endl;
    }

    return 0;
}

在这个示例中,catch块捕获并处理std::runtime_error异常和其他std::exception类型的异常。

5.6.5 标准异常类

C++标准库提供了一些常用的异常类,这些类派生自std::exception。常见的标准异常类包括:

  • std::runtime_error
  • std::logic_error
  • std::out_of_range
  • std::invalid_argument
  • std::bad_alloc

示例代码
#include <iostream>
#include <stdexcept>

void checkIndex(int index, int size) {
    if (index < 0 || index >= size) {
        throw std::out_of_range("Index out of range");
    }
}

int main() {
    try {
        checkIndex(10, 5);
    } catch (const std::out_of_range& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }

    return 0;
}

在这个示例中,checkIndex函数在索引超出范围时抛出std::out_of_range异常,并在main函数中捕获和处理该异常。

重点与难点分析

重点

  1. 异常处理的基本概念:理解trythrowcatch语句的基本概念和用法。
  2. 标准异常类的使用:掌握常见的标准异常类及其应用场景。

难点

  1. 异常的传播和捕获:初学者需要通过实践理解异常的传播机制及如何正确捕获和处理异常。
  2. 自定义异常类:在复杂项目中,自定义异常类可以提高代码的可读性和可维护性,需要掌握自定义异常类的方法。

练习题解析

  1. 练习5.18:编写一个函数,抛出一个标准异常,并在main函数中捕获并处理该异常。
  • 示例代码
#include <iostream>
#include <stdexcept>

void func() {
    throw std::runtime_error("An error occurred in func");
}

int main() {
    try {
        func();
    } catch (const std::runtime_error& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }

    return 0;
}

  1. 练习5.19:编写一个包含多个catch块的程序,捕获不同类型的异常。
  • 示例代码
#include <iostream>
#include <stdexcept>

int main() {
    try {
        throw std::out_of_range("Out of range error");
    } catch (const std::out_of_range& e) {
        std::cout << "Caught out_of_range exception: " << e.what() << std::endl;
    } catch (const std::exception& e) {
        std::cout << "Caught general exception: " << e.what() << std::endl;
    }

    return 0;
}

  1. 练习5.20:编写一个函数,使用throw语句抛出一个自定义异常类,并在main函数中捕获并处理该异常。
  • 示例代码
#include <iostream>
#include <stdexcept>

class MyException : public std::exception {
public:
    const char* what() const noexcept override {
        return "My custom exception";
    }
};

void func() {
    throw MyException();
}

int main() {
    try {
        func();
    } catch (const MyException& e) {
        std::cout << "Caught MyException: " << e.what() << std::endl;
    } catch (const std::exception& e) {
        std::cout << "Caught general exception: " << e.what() << std::endl;
    }

    return 0;
}

总结与提高

本节总结

  1. 学习了异常处理的基本概念,掌握了trythrowcatch语句的用法。
  2. 理解了标准异常类的应用场景,并通过示例代码加深了对这些概念的理解。
  3. 掌握了异常的传播机制及其在程序中的具体应用。

提高建议

  1. 多练习异常处理的使用:通过编写各种包含异常处理的程序,熟悉trythrowcatch语句的用法。
  2. 深入理解异常的传播和捕获:通过实践掌握异常的传播机制及其在程序中的具体应用,确保异常能够被正确捕获和处理。
  3. 自定义异常类:在复杂项目中,自定义异常类可以提高代码的可读性和可维护性,掌握自定义异常类的方法。

本主页会定期更新,为了能够及时获得更新,敬请关注我:点击左下角的关注。也可以关注公众号:请在微信上搜索公众号“iShare爱分享”并关注,或者扫描以下公众号二维码关注,以便在内容更新时直接向您推送。 

标签:语句,std,示例,int,代码,C++,导学,作用域,Primer
From: https://blog.csdn.net/iShare_Carlos/article/details/139769415

相关文章

  • c++期末题库三(读程序写结果)
    1.#include<iostream>usingnamespacestd;classBC{public:BC(intn=100){val=n;cout<<"defaultcon."<<endl;}BC(BC&t){val=t.val;cout<<"Copycon."<<endl;}BC&operator=(BC&t){val=t.val;c......
  • VC++ gen uuid and time
    //ConsoleApplication2.cpp:Thisfilecontainsthe'main'function.Programexecutionbeginsandendsthere.//#define_CRT_SECURE_NO_WARNINGS#pragmacomment(lib,"rpcrt4.lib")#include<windows.h>#include<rpcdce.h>#......
  • C/C++ main 函数注意事项
    main 函数是C/C++程序的入口点,当运行程序时,操作系统会调用 main 函数来启动程序。下面为 main 函数的注意事项:函数签名:在C/C++中,main 函数的标准签名通常有两种形式:intmain(){//...}intmain(intargc,char*argv[]){//...}其中,argc 是命......
  • C++ 20新特性之原子引用
    ......
  • 【C/C++】实现高性能日志轮转功能,已实测
    基本实现在C语言中实现日志文件轮转功能,你需要手动编写代码来处理文件的重命名、压缩和删除。下面是一个简单的C语言程序示例,它演示了如何实现基本的日志文件轮转功能。这个程序会检查日志文件的大小,如果超过预设的大小限制,则将当前日志文件重命名,并创建一个新的日志文件。......
  • LeetCode 算法: 环形链表 c++
    原题链接......
  • C++的动态内存管理
    C++的new和delete一、C与C++的内存管理以及分配二、C++中的new和delete1、new/new[]和delete/delete[]的用法2、new和delete对于内置类型和自定义类型的区别三、new和delete的底层原理1、全局的operatornew和全局的operatordelete2、对于内置类型和自定义类型两个全局......
  • [C++][数据结构][红黑树]详细讲解
    目录1.红黑树的概念2.红黑树的性质3.红黑树节点的定义4.红黑树的结构5.红黑树的插入操作1.cur为红,p为红,g为黑,u存在且为红2.cur为红,p为红,g为黑,u不存在/u存在且为黑--单旋+变色3.cur为红,p为红,g为黑,u不存在/u存在且为黑--双旋+变色6.红黑树的迭代器1.begin()与end()2.o......
  • c# 调用 c++代码
    摘要需要三个项目c++代码CPPProjectc++包装器CPPWrapc#包装器CSharpWrapCPPWrap创建c++动态链接库项目配置属性-高级-C+/CLI属性,依次设置公共语言运行时支持、.NET目标框架(设置为需要的.net环境对应的版本即可)调整公共语言运行时调整项目属性-C/C++-语......
  • 埃氏筛+欧拉筛 (c++)
    求出从2到n的素数埃氏筛方法:筛2的倍数,3的倍数,4的倍数......时间复杂度:O(n·loglogn)缺点:一个数筛了多次,比如6会被2筛,被3筛,被6筛,浪费时间下面的代码中,f是是否是素数的标记数组,N是要筛的个数f[1]=1;for(inti=2;i*i<=N;i++)if(f[i]==0){for(intj=i+i;......