第五章循环和关系表达式
2020-02-24 10:43:38 5 举报
AI智能生成
C++ plus
作者其他创作
大纲/内容
do while 循环
特点
不同与前面两种循环,是出口条件循环
至少执行一次
通常,入口条件循环比出口条件循环好。但有时do while 更加合理,eg:
请求用户输入时,程序必须先获得输入,然后对它测试。
请求用户输入时,程序必须先获得输入,然后对它测试。
循环和文本数输入
循环常见、重要的任务
逐字符地读取来自文件或键盘上的文本
思考编写:计算输入中的字符数、行数、和字数的程序
用原始cin进行输入
子主题
子主题
说明
输出时省略空格 ,因为 cin 读取char 时候会忽略空格和换行符,所以空格也没有
统计进去
统计进去
按回车输入的内容才被发送给程序,因为发送给cin 的输入被缓冲
使用cin.get(char)补救
子主题
关于cin.get()函数重载
cin.get(name,Arsize)
name 是 char *
Arsize 是 int
Arsize 是 int
cin.get(ch)
ch 是 char
说明
cin.get(ch)调用将一个值放在 ch 中,因为改变了值,
在C语言中,改变变量的值,必须将变量的地址传递给
函数。但是这个传递的不是&ch,而是ch,这样子在C++
上是有效的,只要函数将参数声明为引用类型。
//怎么声明为引用类型???
在C语言中,改变变量的值,必须将变量的地址传递给
函数。但是这个传递的不是&ch,而是ch,这样子在C++
上是有效的,只要函数将参数声明为引用类型。
//怎么声明为引用类型???
cin.get()
没有参数
说明
这种现象时函数重载。函数重载允许对多个相关的函数使用相同的名称,
条件它们的参数列表不一样。
条件它们的参数列表不一样。
文件尾条件EOF
前言
统计字符数,但是#也是字符,难以信服
如果文本来自文件,可以用——检测文件尾(EOF)技术
不是文件,有些实现支持模仿这个功能,<ctrl>+<z> <enter>
原理
检测到EOF,cin将两位(eofbit和failbit)都设置为1 。
既如果检测到EOF ,则cin.eof() 、cin.fail返回true,否则返回flase.
一般用cin.fail() 这个可用于更多实现中。
既如果检测到EOF ,则cin.eof() 、cin.fail返回true,否则返回flase.
一般用cin.fail() 这个可用于更多实现中。
代码
//reading char end of file
#include<iostream>
int main()
{
using namespace std;
char ch;
int count = 0;
cin.get(ch); //attempt to read a char
while(cin.fail()== false)//test for EOF
{
cout<<ch; //echo character
++count;
cin.get(ch); //attempt to read another char
}
cout<<count<<endl;
return 0;
}
结果
i am a student
i am a student
you are a teacher
you are a teacher
^Z
33
说明
^Z一定要另起一行,要在行首,再按enter
空格,换行符不会被忽略,也算一个字符
EOF结束输入
设置这个EOF后,cin 不读取输入,再次调用cin也不管用。
对于文件——防止读取超出文件的内容。
对于键盘输入——用模拟EOF结束,但要稍后读取其他输入。可用cin.clear()清除EOF。
但是有些系统,ctrl+z 结束输入输出,cin.clear()无法恢复输入输出
对于文件——防止读取超出文件的内容。
对于键盘输入——用模拟EOF结束,但要稍后读取其他输入。可用cin.clear()清除EOF。
但是有些系统,ctrl+z 结束输入输出,cin.clear()无法恢复输入输出
常见的字符输入做法
每次读取一个字符,直到遇EOF停止
cin.get(ch);
while ( cin.fail() == false )
{
.....
cin.get(ch);
}
while ( cin.fail() == false )
{
.....
cin.get(ch);
}
修改 1
while ( !cin.fail() )
while ( !cin.eof() )
修改 2
cin.get(ch);
while ( cin )
{
.....
cin.get(ch);
}
while ( cin )
{
.....
cin.get(ch);
}
原因
cin.get(ch) 返回一个cin 对象。
但是 cin 可转换为bool 值函数,当cin 出现在需要bool 值的地方时候。
如果最后一次读取成功——返回true,失败——false
但是 cin 可转换为bool 值函数,当cin 出现在需要bool 值的地方时候。
如果最后一次读取成功——返回true,失败——false
意义
更通用,而且可以检测其他失败原因,eg磁盘故障
修改3
while ( cin.get(ch))
{
....
}
while ( cin.get(ch))
{
....
}
说明
cin.get(ch)只出现一次,没有出现循环前一次,循环后一次
原理
判断循环测试条件,程序调用 cin.get(ch)。成功,值写入ch,返回cin 对象。
程序对cin进行bool 转换,输入成功 true ,失败 flase
程序对cin进行bool 转换,输入成功 true ,失败 flase
三条指导原则(确定结束条件、对条件进行初始化、更新条件)
都被放在循环测试条件中
都被放在循环测试条件中
修改4
char ch;
cin.get(ch);
while ( ch != EOF )
{
.....
cin.get(ch);
} //不标准,看下cin.get()如何处理EOF
cin.get(ch);
while ( ch != EOF )
{
.....
cin.get(ch);
} //不标准,看下cin.get()如何处理EOF
ch 无论是char 还是 int 都可以用 ch != EOF 来判断——错误的,不标准,虽然有些系统适用
在有些系统中,char 是无符号的,因此 char 变量不可能是 EOF 值(-1)
//正确
int ch;
ch = cin.get(); //键盘中输入字符,就算ch为char 型,返回的值也是整数
while ( ch != EOF)
{
.....
ch = cin.get();
}
cin.get(n);
int ch;
ch = cin.get(); //键盘中输入字符,就算ch为char 型,返回的值也是整数
while ( ch != EOF)
{
.....
ch = cin.get();
}
int n;
cin>>n;
cin>>n;
cout<<n; // 输入字母 ,输出0
n=cin.get();
cout<<n;//输入字母,输出字母的ascaii 码
cin.get(n);
cout<<n; // 错误,cin.get(n),n不能是int 必须是char
虽然 char ch ;这样定义ch还是起作用,但是如果实现char 是unsigned char类型,
EOF没法用char 表示
EOF没法用char 表示
注意EOF是另起一行才能起作用
sdsfsdf^Z
sdsfsdf
^Z
EOF 不是可以在iostream中吗,为什么DEV 要写上stdio.h 才起作用
这是文件结束符 需要#include<fstream>
用fstream不用std名称空间也可以
总结
可使用cin 和eof(),fail() 判断输入是否成功
另一个cin.get()版本
cin三者区别
char ch;
cin>>ch
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,
不会赋任何值。
不会赋任何值。
区别总结
cin.get()和cin.get(ch)之间的区别:
属性 cin.get(ch) ch=cin.get()
传递输入字符的方式 赋给参数ch 将返回值赋给ch
用于字符输入时函数返回值 istream类对象(执行bool转换后为true) int类型的字符编码
到达EOF时函数的返回值 istream类对象(执行bool转换后为false) 符号常量EOF
属性 cin.get(ch) ch=cin.get()
传递输入字符的方式 赋给参数ch 将返回值赋给ch
用于字符输入时函数返回值 istream类对象(执行bool转换后为true) int类型的字符编码
到达EOF时函数的返回值 istream类对象(执行bool转换后为false) 符号常量EOF
使用选择
使用字符参数的版本更符合对象的方式,因为其返回值是istream对象。这意味着可以将它们拼接起来。如,下面的代码将输入中的下一个字符读入到ch1中,并将接下来的一个字符读入到ch2中:
cin.get(ch1).get(ch2);
函数cin.get(ch1)返回一个cin对象,然后便可以通过该对象调用get(ch2)。
get()的主要用途是能够将stdio.h的getchar() putchar()函数转换为iostream的cin.get()和cout.put()方
cin.get(ch1).get(ch2);
函数cin.get(ch1)返回一个cin对象,然后便可以通过该对象调用get(ch2)。
get()的主要用途是能够将stdio.h的getchar() putchar()函数转换为iostream的cin.get()和cout.put()方
输出区别
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]=
{
"Gribble City",
"Gribbleletoen",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
{
"Gribble City",
"Gribbleletoen",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
节省空间,但是不能修改字符串
char cities[Cities][25]=
{
"Gribble City",
"Gribbleletoen",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
{
"Gribble City",
"Gribbleletoen",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
可以修改字符串,strcpy
string cities[Cities]=
{
"Gribble City",
"Gribbleletoen",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
{
"Gribble City",
"Gribbleletoen",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
节省空间,修改更容易
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);
也可能是 cout.setf(ios::boolalpha),下用cout 会显示flase\true
也可能是 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)
statement;//???例子???
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;
while (guest++ < 10) //判断就算不行也会+1
;
cout<<guest;
结果: 11
while (guest++ < 10) //判断就算不行也会+1
;
cout<<guest;
结果: 11
递增/递减表达式
区别
使用效果
递增表达式的值没有被使用,使用效果是相同的(x++,++x)
效率
前缀,后缀对执行速度有差别。
内置类型——没什么区别:
类(用户定义的类型)——前缀比后缀版本效率高
内置类型——没什么区别:
类(用户定义的类型)——前缀比后缀版本效率高
前缀——将值+1,返回结果
后缀——复制一个副本,将其+1,将复制的副本返回
后缀——复制一个副本,将其+1,将复制的副本返回
递增、递减运算符和指针
优先级
前缀运算符和解除引用运算符的优先级相同,结合从右→左
后缀运算符比前缀运算符的优先级高
例子
*++pt
++pt 再 *
++*pt
*pt 再 将引用的值+1
(*pt)++
*pt++
先pt++,再引用
变量作用域
int x = 20;
{
cout << x << endl;// x=20
int x = 100;
cout << x << endl;//x=100,new hide old
}
cout << x << endl;//x=20
{
cout << x << endl;// x=20
int x = 100;
cout << x << endl;//x=100,new hide old
}
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}
for (double x : prices )
std::cout<<x<<std:endl;
for (double x : prices )
std::cout<<x<<std:endl;
= for(int i=0 ; i<N ; i++)
{
double x=prices[i];
std::cout << x ;
}
{
double x=prices[i];
std::cout << x ;
}
可修改数组
for ( double &x : prices )
x=x*0.80 ;
x=x*0.80 ;
结合基于范围的for 循环和初始化列表
for ( int x : { 3, 5, 2, 8, 6})
cout<< x;
cout<< x;
while 循环
组成
while (test-condition)
body;
body;
测试条件表达式
应用
遍历字符串
c-风格字符串
while( str[i] ) = while (str[i] != '\0')
string 类
int i=0;
string str1 , str2;
str1="ancd";
while (str1[i] !='\0')
{
cout<<str1[i];
i++;
}
疑问:string 类对象不使用空字符来标记字符串末尾,那为什么
还可以这样???
还可以这样???
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 *;
FLOAT_POINTER pa,pb; 只有pa 是指针,pb 不是。
用typedef 不会发生这种情况
FLOAT_POINTER pa,pb; 只有pa 是指针,pb 不是。
用typedef 不会发生这种情况
关键字 typedef
typedef char byte;
c-风格字符串内容
数组字符串
“i am a student ”的字面值
使用const 符可以避免无意间修改这些字符串
const char * qualify[4] =
{
"10,000-meter race.\n",
"mud tug-of-war.\n",
"masters caneo jousting.\n",
"pie-throwing festiva.\nl"
}
{
"10,000-meter race.\n",
"mud tug-of-war.\n",
"masters caneo jousting.\n",
"pie-throwing festiva.\nl"
}
0 条评论
下一页