C++ Primer 第5章 语句

news2024/11/23 16:35:28

C++ Primer 第5章 语句

  • 5.1 简单语句
    • 一、空语句
    • 二、别漏写分号,也别多写分号
    • 三、复合语句(块)
  • 5.2 语句作用域
  • 5.3 条件语句
    • 5.3.1 if语句
      • 一、使用if else语句
      • 二、嵌套if语句
      • 三、注意使用花括号
      • 四、悬垂else
      • 五、使用花括号控制执行路径
    • 5.3.2 switch语句
      • 一、switch内部的控制流
      • 二、漏写break容易引发缺陷
      • 三、default标签
      • 三、switch内部的变量定义
  • 5.4 迭代语句
    • 5.4.1 while语句
      • 一、使用while循环
    • 5.4.2 传统的for语句
      • 一、传统for循环的执行过程
      • 二、for语句头中的多重定义
      • 三、省略for语句头的某些部分
    • 5.4.3 范围for语句
    • 5.4.4 do while语句
  • 5.5 跳转语句
    • 5.5.1 break语句
    • 5.5.2 continue语句
    • 5.5.3 goto语句
  • 5.6 try语句块和异常处理
    • 5.6.1 throw表达式
    • 5.6.2 try语句块
      • 一、编写处理代码
      • 二、函数在寻找处理代码的过程中退出
    • 5.6.3 标准异常
  • 小结

5.1 简单语句

C++语言中的大多数语句都以分号结束,一个表达式,末尾加上分号就变成了表达式语句。表达式语句的作用是执行表达式并丢弃掉求值结果。

一、空语句

; // 空语句
空语句是最简单的语句,空语句由一个单独的分号构成。如果在程序的某个地方,语法上需要一条语句但是逻辑上不需要,此时应该使用空语句,空语句什么也不做。

二、别漏写分号,也别多写分号

三、复合语句(块)

复合语句是指用花括号括起来的语句和声明的序列,复合语句也被称作块。块不以分号作为结束。

5.2 语句作用域

while (int i = get_num()) // 每次迭代时创建并初始化i
	cout << i << endl;
i = 0; // 错误:在循环外部无法访问i

5.3 条件语句

5.3.1 if语句

if (condition)
	statement

if (condition)
	statement
else 
	statement2

一、使用if else语句

二、嵌套if语句

三、注意使用花括号

四、悬垂else

C++规定else与离它最近的尚未匹配的if匹配。

五、使用花括号控制执行路径

5.3.2 switch语句

unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
char ch;
while (cin >> ch) {
	switch (ch) {
		case 'a':
			++aCnt;
			break;
		case 'e':
			++eCnt;
			break;
		case 'i':
			++iCnt;
			break;
		case 'o':
			++oCnt;
			break;
		case 'u':
			++uCnt;
			break;
	}
}

switch语句首先对括号里的表达式求值,该表达式紧跟在关键字switch的后面,可以是一个初始化的变量声明。表达式的值转换成整数类型,然后与每个case标签的值比较(case标签必须是整型常量表达式,任何两个case标签的值不能相同)。如果表达式和某个case标签的值匹配成功,程序从该标签之后的第一条语句开始执行,直到到达了switch的结尾或者是遇到一条break语句为止。

一、switch内部的控制流

如果某个case标签匹配成功,将从该标签开始往后顺序执行所有case分支,除非程序显式地中断了这一过程,否则直到switch的结尾处才会停下来。

unsigned vowelCnt = 0;
switch (ch) {
	// 出现了a、e、i、o或u中的任意一个都会将vowelCnt的值加1
	case 'a':
	case 'e':
	case 'i':
	case 'o':
	case 'u':
		++vowelCnt;
		break;
}

switch (ch) {
	// 另一种合法的书写形式
	case 'a': case 'e': case 'i': case 'o': case 'u':
		++vowelCnt;
		break;
}

二、漏写break容易引发缺陷

三、default标签

如果没有任何一个case标签匹配上switch表达式的值,程序将执行紧跟在default标签后面的语句。

switch (ch) {
	// 另一种合法的书写形式
	case 'a': case 'e': case 'i': case 'o': case 'u':
		++vowelCnt;
		break;
	default:
		++otherCnt;
		break;
}

三、switch内部的变量定义

如果在某处一个带有初值的变量位于作用域之外,在另一处该变量位于作用域之内,则从前一处跳转到后一处的行为是非法行为。

case true:
	string file_name; // 错误:控制流绕过一个隐式初始化的变量
	int ival = 0; // 错误:控制流绕过一个显式初始化的变量
	int jval; // 正确:因为jval没有初始化
	break;
case false:
	jval = next_num(); // 正确:给jval赋一个值
	if (file_name.empty()) // 
		// ...
 #include <iostream>

 using namespace std;

 int main()
 {
    bool flag = false;
    switch (flag)
    {
        case true:
            int i = 10; // 报错
            // 解决方式
            // (1)加大括号限制i的使用范围
            // (2)不初始化i,只声明
            // 定义一个变量——编译阶段就会创建
            // 初始化一个变量——真正运行时才会创建
            break;
        case false:
            cout << "Hello World" << endl;
            cout << "&i = " << &i << endl;
    }

    return 0;
 }

如果需要为某个case分支定义并初始化一个变量,我们应该把变量定义在块内,从而确保后面的所有case标签都在变量的作用域之外。

case true:
	{
		// 正确:声明语句位于语句块内部
		string file_name = get_file_name();
	}
	break;
case false:
	if (file_name.empty()) // 错误:file_name不在作用域之内
		// ...

5.4 迭代语句

5.4.1 while语句

while的条件部分可以是一个表达式或者是一个带初始化的变量声明
while (condition)
	statement

一、使用while循环

5.4.2 传统的for语句

for (init-statement; condition; expression)
	statement
init-statement必须是以下三种形式中的一种:声明语句、表达式语句、空语句

一、传统for循环的执行过程

二、for语句头中的多重定义

init-statement只能有一条声明语句,因此,所有变量的基础类型必须相同。

三、省略for语句头的某些部分

for语句头能省略掉init-statement、condition和expression中的任何一个(或者全部)。

5.4.3 范围for语句

expression表示的必须是一个序列,比如用花括号括起来的初始值列表、数组或vector或string等类型的对象,这些类型的共同特点是拥有能够返回迭代器的begin和end成员。
for (declaration : expression)
	statement
vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (auto &r : v) 
	r *= 2;

// 等价于
for (auto begin = v.begin(), end = v.end(); beg != end; ++beg) {
	auto &r = *beg;
	r *= 2;
}

不能通过范围for语句增加vector对象(或者其他容器)的元素了。在范围for语句中,预存了end()的值。一旦在序列中添加(删除)元素,end函数的值就可能变得无效了。

5.4.4 do while语句

do
	statement
while(condition);
condition使用的变量必须定义在循环体之外

5.5 跳转语句

5.5.1 break语句

break语句负责终止离它最近的while、do while、for或switch语句,并从这些语句之后的第一条语句开始继续执行。

5.5.2 continue语句

continue语句终止最近的循环中的当前迭代并立即开始下一次迭代。continue语句只能出现在for、while、do while循环的内部。

5.5.3 goto语句

goto语句的作用是从goto语句无条件跳转到同一函数的另一条语句。

goto label;
label是用于表示一条语句的标识符
带标签语句是一种特殊的语句,在它之前有一个标示符以及一个冒号:
end: return; // 带标签语句,可以作为goto的目标

goto语句也不能将程序的控制权从变量的作用域之外转移到作用域之内。

	goto end;
	int ix = 10; // 错误:goto语句绕过了一个带初始化的变量定义
end:
	// 错误:此处的代码需要使用ix,但是goto语句绕过了它的声明
	ix = 42;

5.6 try语句块和异常处理

异常处理:
(1)throw表达式:异常检测部分使用throw表达式来表示它遇到了无法处理的问题。我们说throw引发了异常
(2)try语句块:异常处理部分使用try语句块处理异常。try语句块以关键字try开始,并以一个或多个catch子句结束。try语句块中代码抛出的异常通常会被某个catch子句处理。因为catch子句“处理”异常,所以它们也被称作异常处理代码
(3)一套异常类,用于在throw表达式和相关的catch子句之间传递异常的具体信息。

5.6.1 throw表达式

程序的异常检测部分使用throw表达式引发一个异常。throw表达式包含关键字throw和紧随其后的一个表达式,其中表达式的类型就是抛出的异常类型。throw表达式后面通常紧跟一个分号,从而构成一条表达式语句。

Sales_item item1, item2;
if (item1.isbn() != item2.isbn()) {
	throw runtime_error("Data must refer to same ISBN");
	// 异常是类型runtime_error的对象。抛出异常将终止当前的函数,并把控制权转移给能处理该异常的代码
	// 类型runtime_error是标准库异常类型的一种,定义在stdexcept头文件中
}

5.6.2 try语句块

try {
	program-statements
} catch (exception-declaration) {
	handler-statements
} catch (exception-declaration) {
	handler-statements
}

catch子句包括三个部分:关键字catch、括号内一个(可能未命名)对象的声明(异常声明)以及一个块

一、编写处理代码

while (cin >> item1 >> item2) {
	try {
		// 执行添加两个Sales_item对象的代码
		// 如果添加失败,代码抛出一个runtime_error异常
	} catch (runtime_error err) {
		cout << err.what() << "\nTry again? Enter y or n" << endl;
		char c;
		cin >> c;
		if (!cin || c == 'n') 
			break;
	}
}

二、函数在寻找处理代码的过程中退出

当异常被抛出时,首先搜索抛出该异常的函数。如果没找到匹配的catch子句,终止该函数,并在调用该函数的函数中继续寻找。如果还是没有找到匹配的catch子句,这个新的函数也被终止,继续搜索调用它的函数。以此类推,沿着程序的执行路径逐层回退,直到找到适当类型的catch子句为止。
如果最终还是没能找到任何匹配的catch子句,程序转到名为terminate的标准库函数。该函数的行为与系统有关,一般情况下,执行该函数将导致程序非正常退出。

5.6.3 标准异常

(1)exception头文件定义了最通用的异常类exception。它只报告异常的发生,不提供任何额外信息
(2)stdexcept头文件定义了几种常用的异常类
在这里插入图片描述
(3)new头文件定义了bad_alloc异常类型
(4)type_info头文件定义了bad_cast异常类型
我们只能以默认初始化的方式初始化exception、bad_alloc和bad_cast对象,不允许为这些对象提供初值。其他异常类型的行为则恰好相反:应该使用string对象或C风格字符串初始化这些类型的对象,但是不允许使用默认初始化的方式。当创建此类对象时,必须提供初始值,该初始值含有错误相关的信息。
异常类型只定义了一个名为what的成员函数,该函数没有任何参数,返回值是一个指向C风格字符串的const char*。该字符串的目的是提供关于异常的一些文本信息。

小结

C++语言提供了有限的语句类型,它们中的大多数会影响程序的控制流程:
(1)while、for和do while语句,执行迭代操作
(2)if和switch语句,提供条件分支结构
(3)continue语句,终止循环的当前一次迭代
(4)break语句,退出循环或者switch语句
(5)goto语句,将控制权转移到一条带标签的语句
(6)try和catch,将一段可能抛出异常的语句序列括在花括号里构成try语句块。catch子句负责处理代码抛出的异常
(7)throw表达式语句,存在于代码块中,将控制权转移到相关的catch子句
(8)return语句,终止函数的执行
除此之外还有表达式语句和声明语句。表达式语句用于求解表达式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1034221.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣-219.存在重复元素||

Idea 使用哈希表来辅助存储&#xff0c;key存储nums数组中的值nums[i]&#xff0c;value存储该值在nums数组的下标 i&#xff0c;然后遍历nums数组&#xff0c;未出现的重复的存储在hashmap中 AC Code class Solution { public:bool containsNearbyDuplicate(vector<int>…

Kuboard突然无法访问提示:Failed to connect to the database

一、背景 没有做任何特殊操作&#xff0c;突然kuboard访问时&#xff0c;提示如下信息&#xff1a; {"message": "Failed to connect to the database.","type": "Internal Server Error" }二、排查过程 此处kuboard为docker部署的…

二刷力扣--二叉树(3)

106.从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 手动构造的步骤&#xff1a; 后序确定根&#xff0c;中序分…

面试必杀技:Jmeter性能测试攻略大全(第一弹)

前言 性能测试是一个全栈工程师/架构师必会的技能之一&#xff0c;只有学会性能测试&#xff0c;才能根据得到的测试报告进行分析&#xff0c;找到系统性能的瓶颈所在&#xff0c;而这也是优化架构设计中重要的依据。 第一章 测试流程&#xff1a; 需求分析→环境搭建→测试…

上位机通过Modbus转Profinet网关与变频器Modbus通讯案例

上位机与变频器Modbus通讯是通过Modbus转Profinet网关来实现的。这个网关可以理解为一个通信翻译器&#xff0c;负责将上位机通过Modbus协议发送的数据转换为Profinet协议&#xff0c;再通过Profinet网络与变频器进行通信。 上位机通过Modbus转Profinet网关与变频器Modbus通讯…

操作系统存储管理

目录 存储管理&#xff08;1&#xff09; 第一节 存储管理概述&#xff08;内存管理&#xff09; 一、存储体系 二、存储管理的任务 三、地址转换 存储管理&#xff08;2&#xff09; 第二节 分区管理方案 一、固定分区 二、可变分区 三、分区管理方案的优缺点 第…

基于Web的足球青训俱乐部管理后台系统的设计与开发

目录 前言 一、技术栈 二、系统功能介绍 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着社会经济的快速发展&#xff0c;人们对足球俱乐部的需求日益增加&#xff0c;加快了足球健身俱乐部的发展&#xff0c;足球俱乐部管理工作日益繁忙&#xff0c;传统…

安果清理大师-不用的时候我真的不给你推荐这种软件

下载地址&#xff1a;安果移动 视频演示&#xff1a;安果清理大师-不用的时候我真的不给你推荐这种软件_哔哩哔哩_bilibili 全能手机助手&#xff1a;四大功能&#xff0c;全面呵护您的手机&#xff01;☆ 在如今的数字时代&#xff0c;手机已经成为我们生活中不可或缺 的伴侣…

1795_ChibiOS网络书籍阅读_实时系统的一些概念

全部学习汇总&#xff1a; GreyZhang/g_ChibiOS: I found a new RTOS called ChibiOS and it seems interesting! (github.com) 不同的OS在介绍自己的机理的时候都有自己的模型或者抽象概念&#xff0c;ChibiOS也不例外。这里的几个概念需要做一个基本的理解&#xff1a; 1. 进…

如何使用Selenium进行自动化测试

前言 对于很多刚入门的测试新手来说&#xff0c;大家都将自动化测试作为自己职业发展的一个主要阶段。可是&#xff0c;在成为一名合格的自动化测试工程师之前&#xff0c;我们不仅要掌握相应的理论知识&#xff0c;还要进行大量的实践&#xff0c;积累足够的经验&#xff0c;…

RGB格式

Qt视频播放器实现&#xff08;目录&#xff09; RGB的使用场景 目前&#xff0c;数字信号源&#xff08;直播现场的数字相机采集的原始画面&#xff09;和显示设备&#xff08;手机屏幕、笔记本屏幕、个人电脑显示器屏幕&#xff09;使用的基本上都是RGB格式。 三原色 RGB是…

【51单片机】6-静态和动态控制数码管

1.什么是数码管 1.几方面看数码管 1. 外观 2.作用 数码管是显示器件&#xff0c;用来显示数字的 3.分类 单个&#xff08;1位&#xff09;&#xff0c;连排(2位&#xff0c;4位&#xff0c;8位&#xff09; 2.工作原理 1.亮灭原理 其实是内部的照明LED 2.显示数字 原理&…

速码!!BGP最全学习笔记:BGP概述

一、BGP概述 BGP是一种实现自治系统AS之间的路由可达&#xff0c;并选择最佳路由的矢量性协议。早期发布的三个版本分别是BGP-1&#xff08;RFC1105&#xff09;、BGP-2&#xff08;RFC1163&#xff09;和BGP-3&#xff08;RFC1267&#xff09;&#xff0c;1994年开始使用BGP-4…

【一人之下】杀了七个男童,只为修炼邪术!肖哥这一战可以封神!

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析一人之下国漫。 在一人之下中&#xff0c;老肖是临时工里战力数一数二的存在&#xff0c;也是十佬之一解空大师的弟弟&#xff0c;平常看起来像一个热心肠的大哥&#xff0c;但却嗜好杀人&#xff0c;常挂在嘴边的一句话就…

基于微信小程序食谱大全系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言用户微信小程序端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌…

解决typescript报错=》不能将类型“undefined”分配给类型“boolean”

报错如下&#xff1a; 然后看看isSearch的类型定义&#xff1a; isSearch的定义是可选属性&#xff0c;但是TypeScript 中将一个参数标记为可选时&#xff0c;它的默认值将是 undefined。可选参数表示你可以选择性地提供该参数&#xff0c;如果不提供&#xff0c;那么它将默认为…

python随手小练1

题目&#xff1a; 使用python做一个简单的英雄联盟商城登录界面 具体操作&#xff1a; print("英雄联盟商城登录界面") print("~ * "*15 "~") #找其规律 a "1、用户登录" b "2、新用户注册" c "3、退出系统&quo…

实验室仪器应该如何清洗?

梵英超声(fanyingsonic)实验室超声波清洗机 实验室中常见的玻璃器皿如量杯、试管、滴定管、移液管、量瓶等等&#xff0c;是化学实验操作的核心组成部分。但这些玻璃器皿在使用过程中很容易沾上各种污渍&#xff0c;如油渍、血渍、水垢、锈渍等等&#xff0c;如果用完之后没有及…

xx-job凌晨一点清除oss指定文件夹以及指定保留时间的文件

ps&#xff1a;文件下面还有文件夹&#xff0c;这代码不能完全保证是否遍历到所有该文件夹以及子文件夹的文件&#xff0c;因为不可能一点点上到服务器去数&#xff0c;只是代码上做到应该不会出现重复的文件夹以及出现死循环 public static void main(String[] args) {long st…

在Idea中调试本地Docker

报错&#xff1a; Error running myApp: Unable to open debugger port (localhost:5005): java.net.SocketException "Connection reset" 原因&#xff1a; Docker配置里边没有配置环境变量JAVA_TOOL_OPTIONS. 解决&#xff1a; 在Docker下加入运行时的环境变量JAVA…