C++ Primer 迭代语句

欢迎阅读我的 【C++Primer】专栏

专栏简介:本专栏主要面向C++初学者,解释C++的一些基本概念和基础语言特性,涉及C++标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级程序设计技术。希望对读者有帮助!

在这里插入图片描述
在这里插入图片描述

目录

  • 5.4迭代语句
    • 5.4.1 while语句
    • 传统的for语句
    • 传统for循环的执行流程
    • for语句头中的多重定义
    • 范围for语句
    • do while语句

5.4迭代语句

迭代语句通常称为循环,它重复执行操作直到满足某个条件才停下来。while和for语句在执行循环体之前检查条件,do while语句先执行循环体,然后再检查条件。

5.4.1 while语句

只要条件为真,while语句(while statement)就重复地执行循环体,它的语法形式是

while(condition)
    statement

在while结构中,只要condition的求值结果为真就一直执行statement(常常是一个块)。condition不能为空,如果condition第一次求值就得false,statement一次都不执行。

while的条件部分可以是一个表达式或者是一个带初始化的变量声明。通常来说,应该由条件本身或者是循环体设法改变表达式的值,否则循环可能无法终止。

使用while循环

当不确定到底要迭代多少次时,使用while循环比较合适,比如读取输入的内容就是如此。还有一种情况也应该使用while循环,这就是我们想在循环结束后访问循环控制变量。例如:

vector<int> v;
int i;
//重复读入数据,直至到达文件末尾或者遇到其他输入问题
while(cin>>i)
v.push_back(i);
//寻找第一个负值元素
auto beg=v.begin();
while(beg!=v.end()&&*beg>=0)
++beg;
if(beg==v.end())
//此时我们知道v中的所有元素都大于等于0

第一个循环从标准输入中读取数据,我们一开始不清楚循环要执行多少次,当cin读取到无效数据、遇到其他一些输入错误或是到达文件末尾时循环条件失效。第二个循环重复执行直到遇到一个负值为止,循环终止后,beg或者等于v.end(),或者指向v中一个小于0的元素。可以在while循环外继续使用beg的状态以进行其他处理。

传统的for语句

for语句的语法形式是

for (init-statement ;condition; expression){
    statement
}

关键字for及括号里的部分称作for语句头。init-statement必须是以下三种形式中的一种:声明语句、表达式语句或者空语句,因为这些语句都以分号作为结束,所以for语句的语法形式也可以看做

for (initializer:condition; expression)
    statement

一般情况下,init-statement负责初始化一个值,这个值将随着循环的进行而改变。condition作为循环控制的条件只耍condition为真,就执行一次statement 如果condition 第一次的求值结果就是false,则stalement一次也不会执行。expression负责修改 init-statement初始化的变量,这个变量正好就是condition检查的对象,修改发生在每次循环逄代之后。statement可以是一条单独的语句也可以是一条复合语句。

传统for循环的执行流程

//重复处理s中的字符直至我们处理完全部字符或者逼到了一个表示空白的字符
for(decltype(s.size())index=0;
    index!=s.size()&&!isspace(s[index]);++index)
        s[index]=toupper(s[index]);//将当前字符改成大写形式

求值的顺序如下所示:

  1. 循环开始时,首先执行一次init-statement。此例中,定义index并初始化为0。
  2. 接下来判断condition,如果index 不等于s.size,而且在s[index]位置的字符不是空白,则执行for循环体的内容。否则,循环终止。如果第一次迭代时条件为假,for循环体一次也不会执行。
  3. 如果条件为真,执行循环体。此例中,for循环体将s[index]位置的字符改写成大写形式。
  4. 最后执行expression。此例中,将index的值加1。

这4步说明了for循环第一次迭代的过程。其中第1步只在循环开始时执行一次,第2、3、4步重复执行直到条件为假时终止,也就是在s中遇到一个空白字符或者index大于s.size()时终止。

牢记for语句头中定义的对象只在for循环体内可见.因止在上面的例子中,for循环结束后index就不可用了。

for语句头中的多重定义

和其他的声明一样,init-statement也可以定义多个对象。但是init-statetment只能有一条声明语句,因此,所有变量的基础类型必须相同。举个例子,我们用下面的循环把vector的元素拷贝一份添加到原来的元素后面:

//记录下的大小,当到达原来的最后一个元素后结束循环
for(decltype(v.size()) i=0,sz=v.size();i!=sz;++i)
    v.push_back(v[i]);

在这个循环中,我们在init-statement里同时定义了索引i和循环控制变量sz。省略for语句头的某些部分何for语句头能省略掉init-statement,condition和expression中的任何一个(或者全部)。

如果无须初始化,则我们可以使用一条空语句作为init-statement。例如,对于在vector对象中寻找第一个负数的程序,完全能用for循环改写:

auto beg=v.begin();
for(/*空语句*/;beg!=v.end()&&*beg>=0;++beg)
;//什么也不做

注意,分号必须保留以表明我们省略掉了init-statement。说得更准确一点,分号表示的是-个空的init-stafement。在这个循环中,因为所有要做的工作都在for语句头的条件和表达式部分完成了,所以for循环体也是空的。其中,条件部分决定何时停止查找,表达式部分递增迭代器。

省略condition的效果等价于在条件部分写了一个true。因为条件的值永远是true,所以在循环体内必须有语句负责退出循环,否则循环就会无休止地执行下去:

for(int i = 0;/*条件为空*/;++i){
//对i进行处理,循环内部的代码必须负责终止选代过程!
}

我们也能省略掉for语句头中的expression,但是在这样的循环中就要求条件部分或者循环体必须改变迭代变量的值。举个例子,之前有一个将整数读入vector的while循环,我们使用for语句改写它:

vector<int> v;
for(int i;cin>>i;/*表达式为空*/)
v.push_back(i);

因为条件部分能改变i的值,所以这个循环无须表达式部分。其中,条件部分不断检查输入流的内容,只要读取完所有的输入或者遇到一个输入错误就终止循环。

范围for语句

C++11新标引入了一种更简单的for语句,这种语句可以遍历容器或其他序列的所有元素。范围for语句(range for statement)的语法形式是:

for(declaration:expression)
    statement

expression表示的必须是一个序列,比如用花括号括起来的初始值列表、数组或者vector或string等类型的对象,这些类型的共同特点是拥有能返回迭代器的begin和end成员。

declaration定义一个变量,序列中的每个元素都得能转换成该变量的类型。确保类型相容最简单的办法是使用auto类型说明符,这个关键字可以令编译器帮助我们指定合适的类型。如果需要对序列中的元素执行写操作,循环变量必须声明成引用类型。

每次迭代都会重新定义循环控制变量,并将其初始化成序列中的下一个值,之后才会执行statement。像往常一样,statement可以是一条单独的语句也可以是一个块。所有元素都处理完毕后循环终止。

之前我们已经接触过几个这样的循环。接下来的例子将把vector对象中的每个元素都翻倍,它涵盖了范围for语句的几乎所有语法特征:

vector<int> v={0,1,2,3,4,5,6,7,8,9};
//范围变量必须是引用类型,这样才能对元素执行写操作
for(auto&r:v)// 对v中的每一元素
r*2;//将v中每个元素的值翻倍

for语句头声明了循环控制变量r,并把它和v关联在一起,我们使用关键字auto后编译器为r指定正确的类型。由于准备修改v的元素的值,因此将z声明成引用类型。此时,在循环体内给r赋值,即改变了z所绑定的元素的值。

范围for语句的定义来源于与之等价的传统for语句:

for(auto beg=v.begin(),end=v.end();beg!=end;++beg){
    auto&r=*beg;//r必须是引用类型,这样才能对元素执行写操作
    r*=2;//将中每个元素的值翻倍
}

在范围for语句中,预存了end()的值。一旦在序列中添加(删除)元素,end函数的值就可能变得无效了。

do while语句

do while 吾句(do while statement)和while语句非常唯一的区别是,do while语句先执行循环体后检查条件。不管条件的值如何,我们都至少执行一次循环。do while 语句的语法形式如下所示:

do
statement
while(condition);

do while语句应该在括号包围起来的条件后面用一个分号表示语句结束

在do语句中求condilion的值之前首先执行次statement,condition 不能为空。如果condition的值为假,循环终止;否则,重复循环过程。condition使用的变量必须定义在循环体之外。

我们可以使用do while循环(不断地)执行加法运算:

//不断提示用户输入一对数,然后求其和
string rsp;//作为循环的条件,不能定义在do的内部
do{
    cout<<"please enter two values:";
    int val1=0,val2=0;
    cin>>val1>>val2;
    cout<<"the sumo f"<<val1<<" and "<<val2 <<" = " << val1+val2 <<"\n\n" << " more entery yes or no:";
    cin >> rsp;
    while( rsp.empty()&&rsp[0]!='\n');
}

循环首先提示用户输入两个数字,然后输出它们的和并询问用户是否继续。条件部分检查用户做出的回答,如果用户没有回答,或者用户的回答以字母n开始,循环都将终止否则循环继续执行。

因为对于do while来说先执行语句或者块,后判断条件,所以不允许在条件部分定义变量:

do{
    //...
    mumble(foo);
}while(int foo=get_foo());//错误:将变量声明放在了do的条件部分

如果允许在条件部分定义变量,则变量的使用出现在定义之前,这显然是不合常理的!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

你需要提供管理员权限才能删除此文件夹解决方法

立即高级启动 windows10 搜索“设置”&#xff0c;然后“更新和安全””->“恢复”->“立即重新启动” windows11 搜索“设置”&#xff0c;然后“Windows更新”->“更新历史记录”->“恢复”->“立即重新启动” 疑难解答 点击“疑难解答” 高级选项 启…

408-数据结构

数据结构在学什么&#xff1f; 1.用代码把问题信息化 2.用计算机处理信息 ch1 数据&#xff1a;数据是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。 ch2 //假设线性表…

神经网络常见激活函数 9-CELU函数

文章目录 CELU函数导函数函数和导函数图像优缺点pytorch中的CELU函数tensorflow 中的CELU函数 CELU 连续可微指数线性单元&#xff1a;CELU&#xff08;Continuously Differentiable Exponential Linear Unit&#xff09;,是一种连续可导的激活函数&#xff0c;结合了 ELU 和 …

Ceph集群搭建2025(squid版)

squid版本维护年限 apt install -y cephadmecho >> "deb http://mirrors.163.com/ceph/debian-squid/ bookworm main" echo >> "deb-src http://mirrors.163.com/ceph/debian-squid/ bookworm main"#安装源 cephadm install #开始初始化一个最…

详解电子邮箱工作原理|SMTP、POP3、IMAP、SPF、MIME

写在前面 电子邮件&#xff08;Email&#xff09;是一种通过互联网进行异步通信的技术&#xff0c;工作原理涉及多个协议、服务器和客户端协同工作。 接下来我们来介绍一下电子邮箱的工作原理 1. 电子邮件的核心组成部分 邮件客户端&#xff1a;用户直接交互的软件&#xf…

【安全靶场】信息收集靶场

靶场&#xff1a;https://app.hackinghub.io/hubs/prison-hack 信息收集 子域名收集 1.subfinder files.jabprisons.com staging.jabprisons.com cobrowse.jabprisons.com a1.top.jabprisons.com cf1.jabprisons.com va.cobrowse.jabprisons.com vs.jabprisons.com c…

LVDS接口总结--(5)IDELAY3仿真

仿真参考资料如下&#xff1a; https://zhuanlan.zhihu.com/p/386057087 timescale 1 ns/1 ps module tb_idelay3_ctrl();parameter REF_CLK 2.5 ; // 400MHzparameter DIN_CLK 3.3 ; // 300MHzreg ref_clk ;reg …

DeepSeek的大模型介绍

文章目录 DeepSeek是什么DeepSeek平台使用DeepSeek的使用场景DeepSeek的本地部署 DeepSeek是什么 DeepSeek是一家2023/7月年成立的人工智能公司&#xff0c;致力于开发高效、高性能的生成式AI模型&#xff0c;在短短一年多的时间里推出了多款强大的开源模型&#xff0c;包括De…

【devops】Github Actions Secrets | 如何在Github中设置CI的Secret供CI的yaml使用

一、Github Actions 1、ci.yml name: CIon: [ push ]jobs:build:runs-on: ubuntu-lateststeps:- name: Checkout codeuses: actions/checkoutv3- name: Set up Gouses: actions/setup-gov4with:go-version: 1.23.0- name: Cache Go modulesuses: actions/cachev3with:path: |…

C语言基本概念————讨论sqrt()和pow()函数与整数的关系

本文来源&#xff1a;C语言基本概念——讨论sqrt()和pow()函数与整数的关系. C语言基本概念——sqrt和pow函数与整数的关系 1. 使用sqrt()是否可以得到完全平方数的精确的整数平方根1.1 完全平方数的计算结果是否精确&#xff1f;1.2 为什么不会出现误差&#xff08;如 1.99999…

日常知识点之面试后反思裸写string类

1&#xff1a;实现一个字符串类。 简单汇总 最简单的方案&#xff0c;使用一个字符串指针&#xff0c;以及实际字符串长度即可。 参考stl的实现&#xff0c;为了提升string的性能&#xff0c;实际上单纯的字符串指针和实际长度是不够了&#xff0c;如上&#xff0c;有优化方案…

【AI论文】10亿参数大语言模型能超越405亿参数大语言模型吗?重新思考测试时计算最优缩放

摘要&#xff1a;测试时缩放&#xff08;Test-Time Scaling&#xff0c;TTS&#xff09;是一种通过在推理阶段使用额外计算来提高大语言模型&#xff08;LLMs&#xff09;性能的重要方法。然而&#xff0c;目前的研究并未系统地分析策略模型、过程奖励模型&#xff08;Process …

【漫话机器学习系列】088.常见的输出层激活函数(Common Output Layer Activation Functions)

在神经网络中&#xff0c;输出层&#xff08;Output Layer&#xff09; 的激活函数&#xff08;Activation Function&#xff09;直接决定了模型的输出形式&#xff0c;并影响损失函数的选择及训练效果。不同的任务类型&#xff08;如分类或回归&#xff09;需要使用不同的激活…

在实体机和wsl2中安装docker、使用GPU

正常使用docker和gpu&#xff0c;直接命令行安装dcoker和&#xff0c;nvidia-container-toolkit。区别在于&#xff0c;后者在于安装驱动已经cuda加速时存在系统上的差异。 1、安装gpu驱动 在实体机中&#xff0c;安装cuda加速包&#xff0c;我们直接安装 driver 和 cuda 即可…

麒麟v10 server版安装ollama跑Deepseek

麒麟v10 server版安装ollama跑Deepseek 1. 环境 2. 安装docker yum install docker 发现源只有18.x版本&#xff0c;启动ollama&#xff0c;发现调用CPU&#xff0c;没调用GPU docker19.x以上才 会调用GPU, 可以添加centos8的原&#xff0c;安装docker-ce3.启动ollama&#…

LabVIEW用户界面(UI)和用户体验(UX)设计

作为一名 LabVIEW 开发者&#xff0c;满足功能需求、保障使用便捷与灵活只是基础要求。在如今这个用户体验至上的时代&#xff0c;为 LabVIEW 应用程序设计直观且具有美学感的界面&#xff0c;同样是不容忽视的关键任务。一个优秀的界面设计&#xff0c;不仅能提升用户对程序的…

如何使用Java语言在Idea和Android中分别建立服务端和客户端实现局域网聊天

手把手教你用Java语言在Idea和Android中分别建立服务端和客户端实现局域网聊天 目录 文章目录 手把手教你用**Java**语言在**Idea**和**Android**中分别建立**服务端**和**客户端**实现局域网聊天**目录**[toc]**基本实现****问题分析****服务端**Idea:结构预览Server类代码解…

【实战篇】DeepSeek + ElevenLabs:让人工智能“开口说话”,打造你的专属语音助手!

最近,AI语音合成技术真是火得不行,各种“开口脆”的AI声音层出不穷,听得我直呼“这也太像真人了吧!” 作为一个科技爱好者,我当然不能错过这股潮流,这不,最近就沉迷于用 DeepSeek 和 ElevenLabs 这两款神器,捣鼓各种人声音频,简直停不下来! 先来科普一下这两位“主角…

vscode/cursor+godot C#中使用socketIO

在 Visual Studio Code(VS Code)中安装 NuGet 包&#xff08;例如SocketIOClient&#xff09;&#xff0c;你可以通过以下几种方法&#xff1a; 方法 1&#xff1a;使用dotnet cli 打开终端&#xff1a;在 VS Code 中按下Ctrl 或者通过菜单View -> Terminal打开终端。 导…

ETL的使用(sqoop):数据导入,导出

ETL ETL: 是数据抽取&#xff08;Extract&#xff09;、数据转换&#xff08;Transform&#xff09;和数据加载&#xff08;Load&#xff09;的整个过程 常用的ETL工具 sqoop 1.Apache Sqoop 是 Apache 软件基金会旗下的一个开源项目&#xff0c;旨在帮助用户高效地在 Hado…