第五章循环和关系表达式
2020-02-24 10:43:38 5 举报
AI智能生成
C++ plus
作者其他创作
大纲/内容
do while 循环
特点
不同与前面两种循环,是出口条件循环
至少执行一次
通常,入口条件循环比出口条件循环好。但有时do while 更加合理,eg:<br>请求用户输入时,程序必须先获得输入,然后对它测试。
循环和文本数输入
循环常见、重要的任务
逐字符地读取来自文件或键盘上的文本
思考编写:计算输入中的字符数、行数、和字数的程序
用原始cin进行输入
子主题
子主题
说明
输出时省略空格 ,因为 cin 读取char 时候会忽略空格和换行符,所以空格也没有<br>统计进去
按回车输入的内容才被发送给程序,因为发送给cin 的输入被缓冲
使用cin.get(char)补救
子主题
关于cin.get()函数重载
cin.get(name,Arsize)
name 是 char *<br>Arsize 是 int
cin.get(ch)
ch 是 char
说明
cin.get(ch)调用将一个值放在 ch 中,因为改变了值,<br>在C语言中,改变变量的值,必须将变量的地址传递给<br>函数。但是这个传递的不是&ch,而是ch,这样子在C++<br>上是有效的,只要函数将参数声明为引用类型。<br>//怎么声明为引用类型???
cin.get()
没有参数
说明
这种现象时函数重载。函数重载允许对多个相关的函数使用相同的名称,<br>条件它们的参数列表不一样。
文件尾条件EOF
前言
统计字符数,但是#也是字符,难以信服
如果文本来自文件,可以用——检测文件尾(EOF)技术
不是文件,有些实现支持模仿这个功能,<ctrl>+<z> <enter>
原理
检测到EOF,cin将两位(eofbit和failbit)都设置为1 。<br>既如果检测到EOF ,则cin.eof() 、cin.fail返回true,否则返回flase.<br>一般用cin.fail() 这个可用于更多实现中。
代码
<div>//reading char end of file</div><div>#include<iostream></div><div>int main()</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>using namespace std;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>char ch;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>int count = 0;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cin.get(ch); //attempt to read a char</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>while(cin.fail()== false)//test for EOF</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cout<<ch; //echo character</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>++count;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cin.get(ch); //attempt to read another char</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cout<<count<<endl;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>return 0;</div><div>} </div>
结果
<div>i am a student</div><div>i am a student </div><div>you are a teacher</div><div>you are a teacher</div><div>^Z</div><div>33</div>
说明
^Z一定要另起一行,要在行首,再按enter
空格,换行符不会被忽略,也算一个字符
EOF结束输入
设置这个EOF后,cin 不读取输入,再次调用cin也不管用。<br>对于文件——防止读取超出文件的内容。<br>对于键盘输入——用模拟EOF结束,但要稍后读取其他输入。可用cin.clear()清除EOF。<br>但是有些系统,ctrl+z 结束输入输出,cin.clear()无法恢复输入输出
常见的字符输入做法
每次读取一个字符,直到遇EOF停止
cin.get(ch);<br>while ( cin.fail() == false )<br>{<br> .....<br> cin.get(ch);<br>}
修改 1
while ( !cin.fail() )
while ( !cin.eof() )
修改 2
cin.get(ch);<br>while ( cin )<br>{<br> .....<br> cin.get(ch);<br>}
原因
cin.get(ch) 返回一个cin 对象。<br>但是 cin 可转换为bool 值函数,当cin 出现在需要bool 值的地方时候。<br>如果最后一次读取成功——返回true,失败——false<br><br>
意义
更通用,而且可以检测其他失败原因,eg磁盘故障
修改3
<br>while ( cin.get(ch))<br>{<br> ....<br>}
说明
cin.get(ch)只出现一次,没有出现循环前一次,循环后一次
原理
判断循环测试条件,程序调用 cin.get(ch)。成功,值写入ch,返回cin 对象。<br>程序对cin进行bool 转换,输入成功 true ,失败 flase
三条指导原则(确定结束条件、对条件进行初始化、更新条件)<br>都被放在循环测试条件中
修改4
char ch;<br>cin.get(ch);<br>while ( ch != EOF )<br>{<br> .....<br> cin.get(ch);<br>} //不标准,看下cin.get()如何处理EOF
ch 无论是char 还是 int 都可以用 ch != EOF 来判断——错误的,不标准,虽然有些系统适用
在有些系统中,char 是无符号的,因此 char 变量不可能是 EOF 值(-1)
//正确<br>int ch;<br>ch = cin.get(); //键盘中输入字符,就算ch为char 型,返回的值也是整数<br>while ( ch != EOF)<br>{<br> .....<br> ch = cin.get();<br>}
<div>int n;<br>cin>>n;</div><div>cout<<n; // 输入字母 ,输出0<br><br></div><div>n=cin.get();</div><div>cout<<n;//输入字母,输出字母的ascaii 码</div><div> <br>cin.get(n);</div><div>cout<<n; // 错误,cin.get(n),n不能是int 必须是char</div>
虽然 char ch ;这样定义ch还是起作用,但是如果实现char 是unsigned char类型,<br>EOF没法用char 表示
注意EOF是另起一行才能起作用
<div>sdsfsdf^Z</div><div>sdsfsdf</div><div><br></div><div>^Z</div>
EOF 不是可以在iostream中吗,为什么DEV 要写上stdio.h 才起作用
<span style="color: rgb(51, 51, 51); font-family: 'PingFang SC', 'Lantinghei SC', 'Microsoft YaHei', arial, 宋体, sans-serif, tahoma; font-size: 14px; line-height: 24px;">这是文件结束符 需要</span>#include<fstream>
用fstream不用std名称空间也可以
总结
可使用cin 和eof(),fail() 判断输入是否成功
另一个cin.get()版本
cin三者区别
char ch;<br>cin>>ch
子主题
ch=cin.get()
返回值
cin.get()返回字符,将字符编码作为Int 返回值
参数
ch 可以是int ,也可以是char
cin.get()如何处理EOF
函数达到EOF,没有返回字符,cin.get()返回一个字符常量EOF(定义为-1)
EOF在头文件iostream中
cin.fail() == false 可替换为 ch != EOF
ch=getchar()
返回值
ditto ,相似,返回字符,将字符编码作为Int 返回值
参数
ch必须是char???返回值相同 为什么
cin.get(ch)
返回值
返回一个对象(cin?),不是读取的字符
参数
ch必须是 char
不能处理EOF
cin.get(char)函数达到 EOF 时候,不会将一个特殊的值赋给ch,<br>不会赋任何值。
区别总结
<span style="font-family: Arial; font-size: 14px; line-height: 26px; color: rgb(255, 0, 0);">cin.get()和cin.get(ch)之间的区别:</span><br style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;"><span style="font-family: Arial; font-size: 14px; line-height: 26px; color: rgb(0, 0, 153);">属性 cin.get(ch) ch=cin.get()<br>传递输入字符的方式 赋给参数ch 将返回值赋给ch<br>用于字符输入时函数返回值 istream类对象(执行bool转换后为true) int类型的字符编码<br>到达EOF时函数的返回值 istream类对象(执行bool转换后为false) 符号常量EOF</span>
使用选择
<span style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;">使用字符参数的版本更符合对象的方式,因为其返回值是istream对象。这意味着可以将它们拼接起来。如,下面的代码将输入中的下一个字符读入到ch1中,并将接下来的一个字符读入到ch2中:</span><br style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;"><span style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;">cin.get(ch1).get(ch2);</span><br style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;"><span style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;">函数cin.get(ch1)返回一个cin对象,然后便可以通过该对象调用get(ch2)。</span><br style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;"><span style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;">get()的主要用途是能够将stdio.h的getchar() putchar()函数转换为iostream的cin.get()和cout.put()方</span>
输出区别
putchar(ch)
参数
可以为int ,也可以是char
cout.put(ch)
参数
一些C++实现中,只允许 char 类型,给int 参数导致错误
原因
转换Int 的方式不止一种,可能是 put(char) ,put(signed char),put(unsigned char )
强制转换
cout.put( (char)ch )
dev C++允许int 作为参数
嵌套循环和二维数组
三种字符串的方法
char *cities[Cities]=<br>{<br>"Gribble City",<br>"Gribbleletoen",<br>"New Gribble",<br>"San Gribble",<br>"Gribble Vista"<br>};
节省空间,但是不能修改字符串
char cities[Cities][25]=<br>{<br>"Gribble City",<br>"Gribbleletoen",<br>"New Gribble",<br>"San Gribble",<br>"Gribble Vista"<br>};
可以修改字符串,strcpy
string cities[Cities]=<br>{<br>"Gribble City",<br>"Gribbleletoen",<br>"New Gribble",<br>"San Gribble",<br>"Gribble Vista"<br>};
节省空间,修改更容易
for循环
for(),括起的中间部分叫控制部分
组成
for(initialization ; test -expression; updata-expression)
初始化表达式、测试表达式、更新表达式
for( ; ; )
省略测试表达式时,结果为true,循环会一直执行下去
for 循环体由一条语句组成
函数不能命名为for
区分for ,while ,if和函数
for 和括号之间有空格,函数没有
for 用缩进
3>5 结果为bool类型,默认 cout会打出1/0,用cout.setf(ios_base::boolalpha);<br>也可能是 cout.setf(ios::boolalpha),下用cout 会显示flase\true
显示十六进制?
判定表达式的值时改变了内存中的数据——表达式有副作用。
eg: ++x+15
for 可修改为
1.for(int i=0;i<5;i++)
可以这种格式,i只在for 循环内部有效。
2.for( for-init-statement condition ; expression)<br> statement;//???例子???
在for 循环内部声明的变量,只在循环体内有作用。
在循环体内声明变量比在复合语句外声明要慢?因为每次都要被分配和释放
修改步长
for(int i=0;i<5;i=i+by)
for ( cin >> x ; x == 0 ; cin >> x)
是可以的
for ( char ch = 'a' ; strcmp(str,"mate") ; ch++ )
非0执行循环,即使是负数
副作用和顺序点
副作用
计算表达式时对某些东西(存储在变量中的值)作了修改
顺序点
程序执行过程的一个点。C++中,语句中的;是一个顺序点
C++11不在用循序点这个概念
y=(4 + x++) + (6 + x++ )
不同系统不同结果,应尽量避免不用
int guest = 0;<br>while (guest++ < 10) //判断就算不行也会+1<br>;<br>cout<<guest;<br>结果: 11
递增/递减表达式
区别
使用效果
递增表达式的值没有被使用,使用效果是相同的(x++,++x)
效率
前缀,后缀对执行速度有差别。<br>内置类型——没什么区别:<br>类(用户定义的类型)——前缀比后缀版本效率高
前缀——将值+1,返回结果<br>后缀——复制一个副本,将其+1,将复制的副本返回
递增、递减运算符和指针
优先级
前缀运算符和解除引用运算符的优先级相同,结合从右→左
后缀运算符比前缀运算符的优先级高
例子
*++pt
++pt 再 *
++*pt
*pt 再 将引用的值+1
(*pt)++
*pt++
先pt++,再引用
变量作用域
int x = 20;<br>{<br> cout << x << endl;// x=20<br> int x = 100;<br> cout << x << endl;//x=100,new hide old<br>}<br>cout << x << endl;//x=20
逗号运算符
cata=17,240
cata = 240
(cata = 17) , 240
17
cata = (17 ,240)
240
关系表达式
使用范围
数字( int \float \double)
char 字符
string 类字符串
c-风格字符串不可以
比较
strcmp(,)
参数
函数接受两个字符串地址作为参数,所以参数可以是指针、字符串常量或字符数组名
原理
子主题
说明
大小写不一样,ascii 码中大写在小写之前
返回值
第一个 大于 第二个(排在第二个后)
正数
等于
0
小于
负数
比较
str1 > str2...真 1(true) ,错0
str1 != "mate"
内容
<,<=,>,>=,==,!=
基于范围的for 循环
作用
遍历数组
格式
不可修改数组
double prices[5] = {4.99 , 10.99 , 6.87 , 7.99 , 8.49}<br>for (double x : prices )<br> std::cout<<x<<std:endl;
= for(int i=0 ; i<N ; i++)<br> {<br> double x=prices[i];<br> std::cout << x ; <br> }
可修改数组
for ( double &x : prices )<br> x=x*0.80 ;
结合基于范围的for 循环和初始化列表
for ( int x : { 3, 5, 2, 8, 6})<br> cout<< x;
while 循环
组成
while (test-condition)<br> body;
测试条件表达式
应用
遍历字符串
c-风格字符串
while( str[i] ) = while (str[i] != '\0')
string 类
<div>int i=0;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>string str1 , str2;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>str1="ancd";</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>while (str1[i] !='\0')</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cout<<str1[i];</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>i++;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>}</div>
疑问:string 类对象不使用空字符来标记字符串末尾,那为什么<br>还可以这样???
for 与 While 循环区别
相同
两者基本等效
应用
次数
for
子主题
常见错误
while (); 后面加了 分号 ;
等待一段时间
函数
clock()
返回值
返回程序开始执行后所用的系统时间
注意:系统时间有系统时间的单位,不是秒什么的。
不同时间返回的clock()值是不同的
头文件
time.h
应用
得到秒数
系统时间(clock())/ CLOCKS_PER_SEC
CLOCKS_PER_SEC 常量为每秒钟包含的系统时间单位数
得到以系统时间单位为单位的时间
秒数(日常生活中的秒数)* CLOCK_PER_SEC
得到时间的载体(变量)
clock_t 为clock 返回类型的别名,所以可以声明 clock_t 类型的变量
clock_t类型由实现决定,可能是long ,也可能是unsigned long
代码
子主题
类型别名
方式
预处理器#define
#define BYTE char
问题
指针 #define FLOAT_POINTER float *;<br>FLOAT_POINTER pa,pb; 只有pa 是指针,pb 不是。<br>用typedef 不会发生这种情况
关键字 typedef
typedef char byte;
c-风格字符串内容
数组字符串
“i am a student ”的字面值
使用const 符可以避免无意间修改这些字符串
const char * qualify[4] =<br>{<br> "10,000-meter race.\n",<br> "mud tug-of-war.\n",<br> "masters caneo jousting.\n",<br> "pie-throwing festiva.\nl"<br>}
0 条评论
下一页
为你推荐
查看更多