五、循环和关系表达式
5.1for循环
执行重复的任务
#include <iostream>
int main()
{
using namespace std;
for (int i=0;i<5;i++)\\i++ 递增运算符
cout<<"loops.\n";//不加大括号时,只管一句话;包含多条语句时,需要使用复合语句或代码块
cout<<"stop.\n";
return 0;
}
递增运算符:++
递减运算符:–
变体: ++x;x++
对操作数的影响是一样的,但是影响的时间不同
#include <iostream>
int mian()
{
using std::cout;
int a=20;
int b=20;
cout<<"a= "<<a<<": b="<<b<<"\n";
cout<<"a++ ="<<a++<<":++b="<<++b<<"\n";\\a++=20,++b=21
cout<<"a= "<<a<<": b="<<b<<"\n";\\21,21
}
将递增运算符用于指针和基本变量,把指针的值增加其指向的数据类型占用的字节数
double arr[5]={21.1,32.8,23.4,45.6}
double *pt=arr;//指向arr[0]
++pt;
i +=by;// +=运算符将两个操作数相加,并将结果赋给左边的操作数
类似于 +=,-=,*=,/=,%=
复合语句:用两个花括号来构造一条复合语句(代码块)。
语句块张定义一个新的变量,当仅程序执行该语句块中的语句中,该变量才存在。执行完该语句块后,变量被释放。
逗号运算符:允许将两个表达式放到C++语法只允许放一个表达式的地方
int i,j;
char temp;
for(j=0,i=word.size()-1;j<i;--i,++j)
{
temp=word[i];
word[i]=word[j];
word[j]=temp;
}
//不能用逗号运算符将两个声明组合起来
i=20,j=2*i;//确保先计算第一个表达式,然后计算第二个表达式,逗号表达式的值是第二部分的值,为40,逗号的优先级最低
关系表达式
< <= == > >= !=
注意等于运算符 == 和赋值运算符=的区别;
用==判断两个变量是否相等
对于c风格字符串比较
使用strcmp()函数,该函数接受两个字符串地址作为参数,如果字符串相同,返回0;如果第一个字符串按字母顺序排在第二个字符串之前,则返回负数;反之,返回正数 。
//compstr1.cpp;显示一个单词,修改其首字母,然后再次显示这个单词,循环往复,直到strcmp()确定该单词与字符串“mate”相同为止
#include <iostream>
#include <cstring>
using namespace std;
int main(void)
{
char word[5]="?ate";
//strcmp()字符串相同返回0;false
for(char ch='a';strcmp(word,"mate");ch++)
{
cout<<word<<endl;
word[0]=ch;
}
cout<<"finally "<<word<<endl;
return 0;
}
?ate
aate
bate
cate
date
eate
fate
gate
hate
iate
jate
kate
late
finally mate
对于string类字符串
类重载(重新定义)了这些运算符
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string word="?ate";
//strcmp()字符串相同返回0;false
for(char ch='a';word!="mate";ch++)
{
cout<<word<<endl;
word[0]=ch;
}
cout<<"finally "<<word<<endl;
return 0;
}
5.2while循环
while循环是没有初始化和更新部分的for循环,只有测试条件和循环体
while(test)
body
for和while本质上相同
等待一段时间,编写延时循环
让程序等待一段时间 ,比如显示延时,
long wait=0;
while (wait<1000)
wait++;
但是这个问题是,当计算机处理器速度发生变化时,必须修改技术限制。更好的方法是让系统时钟来完成这种工作。
clock(),返回程序开始执行后所用的系统时间。但clock()返回时间的单位不一定是s,其次,返回类型可能是long或者其他类型。
头文件ctime(time.h) 提供解决方法
定义一个符号常量CLOCKS_PER_SEC,该常量等于每秒钟包含的系统时间单位数,用系统时间除以它可得s数,ctime将clock_t作为clock()返回类型的别名,即声明变量为clock_t类型,编译器把他转换为long,unsigned int或其他类型。
//waiting.cpp
#include <iostream>
#include <ctime>
using namespace std;
int main(void)
{
cout<<"enter time,(s): "<<endl;
float secs;
cin>>secs;
//定义delay时间
clock_t delay=secs*CLOCKS_PER_SEC;
cout<<"starting"<<endl;
//现在的时间
clock_t start =clock();
while (clock()-start<delay)
{
}
cout<<"done"<<endl;
return 0;
}
//以系统时间单位计算延迟时间,就不转换为秒了
类型别名
C++为类型建立别名的方式有两种。
//一种是使用预处理器
#define BYTE char
//预处理器在编译程序时用char替代所以BYTE,使BYTE称为char别名
//使用关键字typedef创建别名
typedef char byte;
typedef char *byte_pointer;
//typedef能处理更复杂的类型别名
5.3do while循环
第三种c++循环是do while,它不同于另外两种循环,他是出口条件循环,即首先执行循环体,在判断表达式,决定是否循环,条件false循环终止。循环通常至少执行一次。
do
body
while(test)
通常入口条件循环 比出口循环好,但有时do while更合理,例如程序输入,需要先获得 输入,然后测试
//dowhile.CPP
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
int n;
cout<<"enter 1-10:"<<endl;
cout<<"my favorite number\n"<<endl;
do
{
cin>>n;
} while (n!=7);
cout<<"yes,7 is !"<<endl;
return 0;
}
5.4基于范围的for循环
c++ 11 新增了一种循环,基于范围的for循环,这简化了一种常见的循环,对数组(或容器类,如vector和array)的每个元素执行相同的操作,如下例所示:
double price[5]={4.99,10.99,6.87,7.99,2.33};
for (double x :pricecs)
cout<<x<<endl;
//x是数组price的第一个元素,依次表示数组其他全苏
5.5循环和文本输入
循环完成的一项最常见、最重要的任务:逐字符读取来自文件或键盘的文本。
5.5.1使用原始的cin进行输入
要使用循环读取来自键盘的文本输入,必须有办法知道何时停止读取,一种方法是选择某个特殊字符,将其作为停止标记。例如遇到#结束
#include <iostream>
using namespace std;
int main(void)
{
char ch;
int count=0;
cout<<"enter characters;# stop"<<endl;
cin>>ch;
while (ch!='#')
{
cout<<ch;
count++;
cin>>ch;
}
cout<<endl<<count<<endl;
return 0;
}
5.5.2使用cin.get(char)进行补救
cin.get(ch)读取输入中的下一个字符(即使他是空格)
#include <iostream>
using namespace std;
int main(void)
{
char ch;
int count=0;
cout<<"enter characters;# stop"<<endl;
cin>>ch;
while (ch!='#')
{
cout<<ch;
count++;
cin.get(ch);
}
cout<<endl<<count<<endl;
return 0;
}
5.5.3文件尾条件
不使用检测特殊符号,使用更强大的技术–检测文件尾
unix----ctrl+D
windows-----ctrl+z和enter
cin.get(ch);
while(cin.fail()==false)
{
cin.get(ch);
}
while(!cin.fail())
while(cin)
5.6嵌套循环和二维数组
for循环是一种处理数组的工具,下一步讨论如何使用嵌套for循环中来处理二维数组。
C++没有提供二维数组类型,但用户可以创建每个元素本身是数组的数组。
int maxtemps[4][5];
//包含4个元素数组,每个元素由五个整数组成的数组
for(int row=0;row<4;row++)
{
for(int col=0;col<5;++col)
cout<<maxtemps[row][col]<<"\t";
cout<<endl;
}
5.6.1 初始化二维数组
int maxtemps[4][5]=
{
{1,2,3,4,5},
{1,2,3,4,5},
{1,2,3,4,5},
{1,2,3,4,5}
};
5.6.2使用二维数组
将列循环放在外面,将行循环放在内面。
//nested.cpp
#include <iostream>
using namespace std;
const int citi=5;
const int years=4;
int main(void)
{
//字符串指针数组
const char * cities[citi]=
{
"xiix",
"haha",
"hxs",
"cchdsj",
"cdsbh"
};
int maxtemps[years][citi]=
{
{1,2,3,4,5},
{5,4,3,2,1},
{0,9,8,6,5},
{3,4,5,6,7}
};
cout<<"max temp"<<endl;
for(int i=0;i<citi;i++)
{
cout<<cities[i]<<":\t";
for(int j=0;j<years;++j)
{
cout<<maxtemps[j][i]<<"\t";
}
cout<<endl;
}
return 0;
}
5.7总结
三种循环 for, while, do while
关系表达式
六、分支语句和逻辑运算符
6.1 if语句
决定是否执行某个操作时,常使用if语句来实现选择。if 有两种格式:if和if else。
if (test)
statement
#include <iostream>
using namespace std;
int main(void)
{
char ch;
int spaces=0;
int total =0;
cin.get(ch);
while(ch!='.')
{
if (ch==' ')
++spaces;
++total;
cin.get(ch);
}
cout<<spaces<<"spaces, "<<total;
cout<<"characters total in sentence \n";
return 0;
}
6.1.1 if else 语句
if(test)
{statement1}
else
{staterment2}
if (answer==1492)
{cout<<"haha"<<endl;}
else
{cout<<"xixi"<<endl;}
6.1.2if else if else结构
if (ch=='A')
a++;
else
if(ch=='b')
b++;
else s++
if (ch=='A')
a++;
else if (ch=='b')
b++;
else
s++;
6.2逻辑表达式
三种逻辑运算符分别是
逻辑OR ||
逻辑AND &&
逻辑NOT !
- 逻辑OR运算符 ||
两个条件中有一个或全部满足某个要求时,可以用or来指明情况。
5>3||5<10
//||优先级比关系运算符低
//顺序点,先看左侧如果ture不去执行右侧
- 逻辑ANSD运算符 &&
当两个表达式都为ture是,表达式的值才为true
5>3 && 7>5
//&&优先级比关系运算符低
//顺序点,先看左侧如果false不去执行右侧
用 &&来设置取值范围
&&运算符还允许建立一系列if else if else语句,其中每种选择都对应于一个特定的取值范围
3**.逻辑NOT运算符:!**
!运算符将它后面的表达式的真值取反
4.逻辑运算符细节
C++逻辑OR和AND运算符的优先级都低于关系运算符
!运算符的优先级高于所有的关系运算符和算术运算符,因此,对表达式求反,必须用括号将器括起。
逻辑AND云孙福的优先级高于逻辑OR运算符
!(x>5);
!x>5;//!x只能是ture和false,会被转换为1或0
5**.其他表示方式**
标识符 and、or、not都是C++保留字
运算符 | 另一种表达方式 |
---|---|
&& | and |
|| | or |
! | not |
6.3字符函数库cctype
c++从c语言继承了一个与字符相关的 ,非常方便的函数软件包,可以简化诸如确定字符是否为大写字母,数字、标点符号等工作
这些函数的原型是在头文件cctype中定义的。
例如,ch是一个字母。则isalpha(ch)函数返回一个非零值,否则返回0。同样,如果ch是标点符号,函数ispunct(ch)将返回true。
if(isalpha(ch));
函数名称 | 返回值 |
---|---|
isalnum() | 如果参数是字母或数组,返回true |
isalpha() | 如果参数是字母,返回true |
iscntrl() | 如果参数是控制字符,返回true |
isdigit() | 如果参数是数字(0-9),返回true |
isgraph() | 如果参数是处空格之外的打印字符,返回true |
islower() | 如果参数是小写字母,返回true |
ispunct() | 如果参数是标点符号,返回true |
isupper() | 如果参数是大写字母,返回true |
tolower() | 如果参数是大写字符,返回其小写,否则返回该参数 |
6.4 ?:运算符
C++有一个常被用来代替if else语句的运算符,这个运算符被称为条件运算符(?😃,他是c++中唯一一个需要3个操作数的运算符。
5>3 ? 10 : 12;
//如果5>3 为true,则 整个表达式为10,否则为12
条件运算符更简洁
6.5switch语句
假设要创建一个屏幕菜单,要求用户从5个选项中选择一个,switch语句更容易
switch(integer-expression)
{
case labe1:statement(s)
case label2:statement(s)
……
default:statement(S)
}
如果integer-expression=4,执行case4;
每个标签都必须是整数常量表达式,常见的是int或char常量。也可以是枚举量,如果不跟任何标签匹配,跳到default,可选,如果没有就跳到switch后面的语句处执行。
程序不会在执行到下一个case处自动停止,要让程序执行完一组特定语句后停止必须使用break语句,这将导致程序跳到switch后面的语句执行。
#include <iostream>
using namespace std;
void showmenu();
void report();
void comfort();
int main(void)
{
showmenu();
int choice;
cin>>choice;
while(choice!=5)
{
switch(choice)
{
case 1: cout<<"\a\n";
break;
case 2:report();
break;
case 3: cout<<"all day.\n";
break;
case 4: comfort();
break;
default: cout<<"not.\n";
}
showmenu();
cin>>choice;
}
cout<<"byby"<<endl;
return 0;
}
void showmenu()
{
cout<<"enter 1-5:\n"
"1alarm 2 report 3 alibi 4 comfort 5 quit \n";
}
void report()
{
cout<<"business report"<<endl;
}
void comfort()
{
cout<<"comfort"<<endl;
}
将枚举量用于标签
enum {red,orange,yellow,green};
while(code>=red&&code<<green)
{
switch (code)
{
case red:cout<<"red"<<endl;break;
case yellow:cout<<"red"<<endl;break;
}
}
6.6break和continue语句
break和continue语句都能使程序跳过部分代码,可以在switch语句或任何循环中使用
break语句,使程序跳到switch或循环后面的语句处执行
continue语句,用于循环中,让程序跳过循环体中余下的代码,并开始新一轮循环
6.7简单的文件输入、输出
6.7.1写入到文本文件
类似于cout,open(),close()
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
char mobile[50];
int year;
double a_price;
double b_price;
ofstream outFile;//创建一个ofstream对象
outFile.open("1.txt");//将该对象同一个文件关联起来
cout<<"enter:"<<endl;
cin.getline(mobile,50);
cout<<"enter year"<<endl;
cin>>year;
cout<<"enter pricce:"<<endl;
cin>>a_price;
b_price=0.5*a_price;
cout<<fixed;//表示用一般的方式输出浮点数
cout.precision(2);//设置精确度为2位并返回上一次的设置。
cout.setf(ios_base::showpoint);//在c++中是为了保留原有的类型精度
cout<<"mark:"<<mobile<<endl;
cout<<"$"<<a_price<<" $ "<<b_price<<endl;
outFile << fixed;
outFile.precision(2);
outFile.setf(ios_base::showpoint);
outFile<<"Make :"<<mobile<<endl;
outFile<<"year "<<year<<endl;
outFile<<"$ "<<a_price<<"$ "<<b_price<<endl;
outFile.close();
return 0;
}
大体意思就是和cout一样,只不过不显示在屏幕上,而是写入了我们命名的文件中。而且cin\cout的操作和方法都可以应用于ifstream和ofstream上
6.7.2 读取文本文件
#include<iostream>
#include<fstream>
#include<cstdlib>//exit()
using namespace std;
const int SIZE=60;
int main(void)
{
char filename[SIZE];
ifstream inFile;
cout<<"enter file name:"<<endl;
cin.getline(filename,SIZE);
inFile.open(filename);//紫色块是方法
if(!inFile.is_open())
{
cout<<"not open"<<endl;
exit(EXIT_FAILURE);//宏定义
}
double value;//关键字
double sum=0;
int count=0;
inFile>>value;
while (inFile.is_open())
{
++count;
sum+=value;
inFile>>value;
}
if(inFile.eof())
cout<<"end"<<endl;
else if(inFile.fail())
cout<<"mismatch"<<endl;
else
cout<<"unknown"<<endl;
if(count==0)
cout<<"No data"<<endl;
else
{
cout<<"count: "<<count<<endl;
cout<<"sum: "<<sum<<endl;
}
inFile.close();
return 0;
}