C++ Primer 第5章 语句

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()) // 每次迭代时创建并初始化icout << i << endl;
i = 0; // 错误:在循环外部无法访问i

5.3 条件语句

5.3.1 if语句

if (condition)statementif (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的值加1case '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语句

dostatement
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.rhkb.cn/news/140212.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle分区的使用详解:创建、修改和删除分区,处理分区已满或不存在的插入数据,以及分区历史数据与近期数据的操作指南

一、前言 什么是表分区: Oracle的分区是一种将表或索引数据分割为更小、更易管理的部分的技术。它可以提高查询性能、简化维护操作,并提供更好的数据组织和管理。 表分区和表空间的区别和联系: 在Oracle数据库中,表空间(Tablespace)是用于存储表、索引和其他数据库对…

Baichuan2 技术报告笔记

文章目录 预训练预训练数据模型架构TokenizerPositional EmbeddingsAcitivations and NormalizationsOptimizations 对齐Supervised Fine-TuningRLHF 安全性预训练阶段对齐阶段 参考资料 对Baichuan2技术报告阅读后的笔记 Baichuan2 与其他大模型的对比如下表 预训练 预训练数…

【Java开发】Redis位图实现统计日活周活月活

最近研究了使用 Redis 的位图功能统计日活周活等数据&#xff0c;特来和大家分享下&#xff0c;Redis 位图还可用于记录用户签到情况、判断某个元素是否存在于集合中等。 1 Redis 位图介绍 Redis 位图是一种特殊的数据结构&#xff0c;它由一系列位组成&#xff0c;每个位只能…

洛谷P8815:逻辑表达式 ← CSP-J 2022 复赛第3题

【题目来源】https://www.luogu.com.cn/problem/P8815https://www.acwing.com/problem/content/4733/【题目描述】 逻辑表达式是计算机科学中的重要概念和工具&#xff0c;包含逻辑值、逻辑运算、逻辑运算优先级等内容。 在一个逻辑表达式中&#xff0c;元素的值只有两种可能&a…

Appilot发布:打造面向DevOps场景的开源AI助手

今日&#xff0c;数澈软件Seal &#xff08;以下简称“Seal”&#xff09;宣布推出面向 DevOps 场景的 AI 助手 Appilot&#xff0c;这款产品将充分利用 AI 大语言模型的能力为用户提供变革性的部署和应用管理体验。Seal 此次发布的 Appilot 项目&#xff0c;可以让用户直接输入…

leetcode 22. 括号生成

2023.9.24 看到组合两个字&#xff0c;想到了回溯。 大致思路是将所有可能的组合列出来&#xff0c;通过中止条件筛选掉无效的括号。 第一个中止条件&#xff1a;如果右括号数量大于左括号&#xff0c;那括号肯定无效。 第二个中止条件&#xff1a;当左右括号数量相等&#x…

古代有没有电子元器件?

手机&#xff0c;电脑&#xff0c;电视等等电子产品&#xff0c;无时无刻充斥在我们的生活中&#xff0c;如果有一天突然没有了这些功能多样的电子产品&#xff0c;估计大部分人都会一时之间难以适应。 这就好比正在上网&#xff0c;结果突然被人断了网&#xff0c;导致无网络连…

Go语言入门篇

目录 一、基础数据类型 1.1 变量的定义方式 1.2 用%T输出变量的类型 二、复合数据类型 2.1 数组 2.1.2、数组的遍历 2.1.3 数组传参 2.2. 切片slice 2.2.1. 初始化切片 2.2.2. append向切片中追加元素 2.2.3. 切片的截取 2.3. map 2.3.1. map初始化 2.3.2. 添加和…

操作系统权限提升(三十)之数据库提权-SQL Server sp_oacreate+sp_oamethod(dba权限)提权

SQL Server sp_oacreate+sp_oamethod(dba权限)提权 sp_oacreate+sp_oamethod介绍 在xp_cmdshell被删除或不能利用是可以考虑利用sp_oacreate,利用前提需要sqlserver sysadmin账户服务器权限为system(sqlserver2019默认被降权为mssql)。sp_oacreate 是一个存储过程,可以…

【无标题】mysql 普通用户连接报错: MySql server has gone away

1、mysql 普通用户连接报错&#xff1a; MySql server has gone away 2、进入mysql错误日志位置查看输出日志显示错误为&#xff1a; [Warning] [MY-013130] [Server] Aborted connection 47 to db: unconnected user: tjcx host: 10.195.11.4 (init_connect command failed; …

基于docker进行Grafana + prometheus实现服务监听

基于docker进行Grafana Prometheus实现服务监听 Grafana安装Prometheus安装Jvm监控配置服务器主机监控(基础cpu&#xff0c;内存&#xff0c;磁盘&#xff0c;网络) Grafana安装 docker pull grafana/grafanamkdir /server/grafanachmod 777 /server/grafanadocker run -d -p…

汽车OTA

汽车OTA&#xff08;Over-The-Air&#xff09;技术是指通过无线网络对汽车进行软件升级、数据传输和远程诊断等功能的技术。随着汽车行业的数字化和智能化发展&#xff0c;OTA技术在汽车领域的应用越来越广泛&#xff0c;对于提高汽车性能、降低维修成本和提升用户体验具有重要…

Linux(ubuntu)系统更新后不能进入图形界面

最近需要跑一个深度学习的程序&#xff0c;把许久没用的ubuntu系统调了出来&#xff0c;手欠的我更新了一下系统&#xff0c;结果再启动&#xff0c;系统就只停留在光标闪动那里&#xff0c;不能看到图形界面了。网上查了一下&#xff0c;说是因为更新后&#xff0c;显卡驱动没…

Scrapy+Selenium自动化获取个人CSDN文章质量分

前言 本文将介绍如何使用Scrapy和Selenium这两个强大的Python工具来自动获取个人CSDN文章的质量分数。我们将详细讨论Scrapy爬虫框架的使用&#xff0c;以及如何结合Selenium浏览器自动化工具来实现这一目标。无需手动浏览每篇文章&#xff0c;我们可以轻松地获取并记录文章的…

MySQL常见join关联查询分析

1、join关联查询七大类型结构图 2、建表语句 CREATE TABLE t_dept (id INT(11) NOT NULL AUTO_INCREMENT,deptName VARCHAR(30) DEFAULT NULL,address VARCHAR(40) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;CREATE TABLE t_emp (id…

Go 并发可视化解释 - sync.Mute

在学习 Go 编程语言时&#xff0c;您可能会遇到这句著名的格言&#xff1a;“不要通过共享内存来进行通信&#xff1b;相反&#xff0c;通过通信来共享内存。” 这句话构成了 Go 强大并发模型的基础&#xff0c;其中通道&#xff08;channels&#xff09;作为协程之间的主要通信…

搭建安信可小安派Windows 开发环境

搭建小安派Windows 开发环境 Ai-Pi-Eyes 系列是安信可开源团队专门为Ai-M61-32S设计的开发板&#xff0c;支持WiFi6、BLE5.3。所搭载的Ai-M61-32S 模组具有丰富的外设接口&#xff0c;具体包括 DVP、MJPEG、Dispaly、AudioCodec、USB2.0、SDU、以太网 (EMAC)、SD/MMC(SDH)、SP…

操作系统真象还原_访问vaddr对应的pte

须知&#xff1a; 只要开启了分页机制&#xff0c;不管物理地址还是虚拟地址在CPU面前都按照分页处理&#xff0c;也就是即便给出物理地址CPU也按虚拟地址对待。 为什么没有出现页目录表结构体&#xff0c;也没有页目录项结构体。页目录表在某一块内存中&#xff0c;页表也在某…

存储管理详解

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

docker openjdk:8-jdk-alpine 修改时区、添加字体

新建Dockerfile文件&#xff0c;制作新镜像 FROM openjdk:8-jdk-alpine 1、解决字体问题 RUN apk add --update ttf-dejavu fontconfig && rm -rf /var/cache/apk/* 2、解决时差问题 # 解决时差8小时问题ENV TZAsia/ShanghaiRUN ln -snf /usr/share/zoneinfo/$TZ /et…