switch内部的变量定义
看书的过程中遇到这样一个switch执行流程的问题,假如现在有一个switch语句,里面有两个case:true和false,在这两个语句中因为程序的逻辑需要定义和初始化一个变量,如果在true里面定义和初始化,当控制流直接跳过true去执行false分支,说来也巧,false里面正好又要用到这个true里面定义和初始化的变量怎么办。
答案是:如果在某处有一个带有初值的变量位于作用域外,在另一处该变量位于作用域之内,则从前一处跳到后一处的行为是非法的。
如果需要定义并初始化一个变量,那就把这条声明语句放在一个中括号括起来的语句块内部。
迭代器和迭代语句
书中给出的迭代语句的定义是:迭代语句通常被称为循环,它重复执行操作直到满足某个条件才会停下来。
迭代器:访问string对象的字符或者vector对象的元素。
使用迭代器的背景是:所有标准容器都可以使用迭代器,但是只有少数几种支持下标运算符。
在这里我不禁产生了一个联想,迭代器也是一种循环,既然想到这,那就去看看源码
好吧,看了一圈一个看不明白,直接放弃,但是还是找到了一些有用的内容:
STL中iterator主要是用来遍历容器中的数据节点,要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。
综合一下,迭代语句和迭代器既然名字都差不多,那么可以在理解的过程中并在一起去理解一下,迭代语句最为典型的就是:while、for、范围for、do while。
关于while(cin>>num)
定义在while条件部分或者while循环体内的变量每次迭代都经历从创建到销毁的过程,那cin被销毁之后呢
在解决这个问题之前就需要了解一下cin,首先cin>>会以tab、enter、空格为分隔符进行连续输入,其中>>是提取运算符,更准确一些:<<和>>运算符的内置含义是对其运算对象执行基于二进制的位运算操作,在处理输入和输出操作时使用的其实是标准IO库定义发<<运算符和>>运算符的重载版本。
什么是重载版本呢?
C++ 允许多个函数拥有相同的名字,只要它们的参数列表不同就可以,这就是函数的重载(Function Overloading)。借助重载,一个函数名可以有多种用途。那重载版本其实就是同样的运算符实现不同的功能。
说到重载版本又不得不提一下位移运算符,简单写一个例子吧:
1UL<<27;//1UL就是一个无符号long类型元素:00000000000000000000000000000001
位移运算就是把这个二进制1向左移动27位:00001000000000000000000000000000
再细致的就不再说了,回到最开始的问题,cin被销毁,cin是缓冲流,cin>>会从缓冲区中读取数据,若缓冲区有空格等分隔符就会忽略并清除这些继续读取下一个字符,cin读取完一个字符后会将其清除,所以每次读取都是从头读取,然后每读取一次就对num进行赋值,赋值后cin会返回一个goodbit作为while判断的依据,我们举个例子来理解一下吧:
#include<iostream>
using namespace std;
int main(){
int num;
while (cin>>num)
{
cout<<num<<"*******"<<endl;
}
}
while实现查找连续重复出现的单词
#include<iostream>
#include<string>
using namespace std;
int main(){
int cnt=1,maxval=0;
string tmpstr,prestr="",maxstr;
while (cin>>tmpstr)
{
if(tmpstr==prestr){
++cnt;
if(maxval<cnt){
maxval=cnt;
maxstr=tmpstr;
}
}else
{
cnt=1;
}
prestr=tmpstr;
}
if (maxval>1)
{
cout<<"max number of all is "<<maxstr<<" max is "<<maxval<<endl;
}else
{
cout<<"all is 1 time"<<endl;
}
}
上面这是C++Primer 5.4.1节练习题。
检查一个vector是否是另一个vector的前缀
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(){
int val;
vector<int> v1;
vector<int> v2={1,2,3,4};
while (cin>>val)
{
v1.push_back(val);
}
for (decltype(v2.size()) i = 0,j=v2.size(); i !=j && v1[i]==v2[i]; ++i)
{
cout<<"position "<<i<<" is same";
}
}
do while 流控制
int main(){
string rsp;
do
{
cout<<"Enter two values : ";
int v1=0,v2=0;
cin>>v1>>v2;
cout<<"sum is "<<v1+v2<<"\n\n"<<"More? Enter yes or no: ";
cin>>rsp;
} while (!rsp.empty()&&rsp[0]!='n');
}
dowhile和while的区别就是do里面的内容至少会执行一遍,执行一遍之后再根据条件判断是否跳出循环。这个东西在初学的时候很友好,就拿上面的代码来讲,当第一个cin我们输入之后可以按enter键让代码继续往下运行,当第二个cout输出之后,又有一个cin可以让我们输入,输入后按enter进入条件的判断。
编写一段程序,从标准输入中读取string对象的序列直到连续出现两个相同的单词或所有单词都读完为止。使用while循环一次读取一个单词,当一个单词连续出现两次时使用break语句终止循环。输出连续重复出现的单词,或输出一个消息说明没有任何单词是连续出现的。
#include<vector>
#include<iostream>
#include<string>
using namespace std;
int main(){
string curstr,prestr="";
while (cin>>curstr)
{
if (curstr==prestr)
{ cout<<curstr<<endl;
break;
}else if (curstr=="EOF")
{
cout<<"nothing"<<endl;
break;
}
prestr=curstr;
}
}