Chapter 6分支语句和逻辑运算符

6.1 if语句

语法:

if(test-conditon)
	statement
6.1.1 if else 语句

通用格式:

if(test-condition)
	statement
else
	statement
6.1.2 格式化if else语句

if else的操作都是一条语句,如果需要多条语句,需要{}括起来

6.1.3 if else if else结构

猜数游戏,程序如下:

// ifelseif.cpp 
#include<iostream>
const int Fave = 32;
int main()
{
    using namespace std;
    int n;
    cout << "Enter an number in the rang 1-100 to find ";
    cout << "my favourite number: ";
    do
    {
        cin >> n;
        if(n > Fave)
            cout << "Too high. -- guess again";
        else if(n < Fave)
                cout << "Too Low. -- guess again";
            else
                cout << n << " is right.\n";

    } while (n != Fave);
    return 0;
}
  • 条件运算符和错误防范
    将variable == value 写成 value == variable

6.2 逻辑表达式

测试多种条件。逻辑OR(||),逻辑AND(&&),逻辑NOT(!)。

6.2.1 逻辑OR运算符:||

C++规定,||运算符是个顺序点,可以先修改左侧的值进行判定,不满足在对右侧的值进行判定。

6.2.2 逻辑AND运算符:&&

将两个测试条件组合成一个条件。

6.2.3 用&&来设置取值范围
  • 取值范围测试
    if(age > 17 && age <35)是对的。

    if(17<age<35),无编译错误,但会计算(17<age)<35

6.2.4 逻辑NOT运算符:!

!运算符对于返回true-false值或可以被解释为true-false值的函数来说很有用。
下面代码实现了筛选可赋值给变量int的数字输入:

// not.cpp -- using the not operator
#include<iostream>
#include<climits>
bool is_int(double);
int main()
{
    using namespace std;
    double num;

    cout << "Yo, dude! Enter an integer value: ";
    cin >> num;
    while (!is_int(num))
    {
        cout << "Out of range -- please try again: ";
        cin >> num;
    }
    int val = int (num);
    cout << "You have enter the integer " << val << " \nBye\n";
    return 0;
}
bool is_int(double x)
{
    if(x <= INT_MAX && x >= INT_MIN)
        return true;
    else
        return false;
}

bool is_int()函数限制了取值范围,确定输入有效后,程序将其赋给一个int变量。

6.2.5 逻辑运算符细节
  • C++逻辑OR和逻辑AND运算符的优先级都低于关系运算符。
  • !运算符的优先级高于所有的关系运算符和算数运算符。
  • 逻辑运算符AND的优先级高于逻辑OR运算符

6.3 字符函数库cctype

  • isalpha(ch),是字母返回一个非零值,不是返回零,注意不是bool值

  • ispunct(ch),是标点符号将返回true,

  • isspace(),是否是空格

  • isdigits(),是否是数字
    cctype中的字符函数

6.4 ?:运算符

?:运算符常被用来代替if else语句的运算符,它是C++中唯一需要三个操作数的运算符。
expression1 ? expression2 : expression3

6.5 switch语句

switch 适合从大型列表中选择:

switch(integer-expression)
{
	case1 label : statement(s)
	case2 label : statement(s)
	case3 label : statement(s)
	...
	default		: statement(s)
}

在执行玩一个标签的语句后,因该添加break;否则会继续执行下一个标签的语句,知道遇到break;。

6.5.1 将枚举量用作标签

cin无法识别枚举类型,因此在输入选项时会要求用户输入一个整数。
当switch语句将int和枚举量标签进行比较是,会将枚举量提升为int型。

6.5.2 switch和if else

if else:

  • 可以处理取值范围
  • 适合选项较少<3使用

switch:

  • 每一个标签是一个单独的值
  • 适合处理多个选项>=3
  • 就代码长度和效率而言,switch语句的效率更高

6.6 break 和 continue语句

break: 跳过循环;
continue: 跳过循环体剩下的代码,开始新一轮循环。
goto: goto paris: 该语句将跳到paris:作为标签的位置

6.7 读取数字的循环

定义一个数字,用户输入一个单词,将发生4种情况:

  • n的值保持不变
  • 不匹配的输入将被保留在输入队列中;
  • cin对象中的一个错误标记被设置
  • 对cin方法的调用将返回fasle(如果被转换成bool类型)

输入字符后,想继续输入内容:

if(!cin)
{
	cin.clear(); //reset input
	cin.get(); // read q
}
cin.get();			//read end of line after last input
cin.get();			//wait for user to press<Enter>

当输入的不是数字时,应采取三个步骤

  • 重置cin以接受新的输入
  • 删除错误输入
  • 提示用户在输入
    实现的代码如下:
while(!(cin >> num))
{
	cin.clear();
	while(cin.get() != '\n')
	{
		continue;
	}
	cout << "Please enter a numebr";
}

6.8 简单文件输入/输出

6.8.1 文本I/O和文本文件

如下输入行:
38.5 19.2
不同数据类型的变量存储时,cin如何处理该输入行。

  • char ch; cin >> ch;
    输入行第一个字符被赋给ch,在这里第一个字符是数字3,其字符编码(二进制)存储在变量ch中,注,存储的不是数值,而是3的编码。
    执行完上述语句后,输入队列的下一个字符为8,下一个输入操作对其进行处理。
  • int n; cin >> n;
    在该情况下,cin将不断读取,直到遇到非数字字符。也就是说,它将读取3和8,这样句点将成为输入队列的下一个字符。cin通过计算发现,两个字符对应数值38,因此将38的二进制编码复制到变量n中。
  • double x; cin >> x;
    在该情况下,cin将不断读取,直到遇到非浮点数字符。空格成为输入队列的下一个字符。cin通过计算发现,两个字符对应数值38.5,因此将38.5的二进制编码(浮点格式)复制到变量n中。
  • char word[50]; cin >> word;
    在该情况下,cin将不断读取,直到遇到空白字符。空格成为输入队列的下一个字符。然后cin将这4个字符的字符编码存储到word中,并在末尾加上一个空字符。这里不需要进行任何转换。
  • char word[50]; cin.getline(word,50);
    在这种情况下,cin将不断读取,直到遇到换行符。所有字符被存储到数组word中,并在末尾加上一个空字符。换行符被丢弃,输入队列中下一个字符是下一行的第一个字符。
6.8.2 写入到文本文件中

文件写入准备:

  • 必须包含头文件fstream。
  • 头文件fstream定义了一个用于处理输出的ofstream类。
  • 需要声明一个或多个ofstream变量(对象),并以自己喜欢的方式对其进行命名,条件是遵守常用的命名规则。
  • 必须知名名称空间std;
  • 需要将ofstream对象与文件关联起来,方法是使用open()方法。
  • 使用完文件后,应使用方法close()将其关闭。
  • 可结合使用ofstream对象和运算符<<来输出各种类型的数据。
    注:运行open()时,如果文件不存在,将会创建一个文件;如果文件存在,默认会丢失文件原有的内容,然后添加新的输出。
6.8.3 读取文本文件

文件读取准备:

  • 必须包含头文件fstream。
  • 头文件fstream定义了一个用于处理输出的ifstream类。
  • 需要声明一个或多个ifstream变量(对象),并以自己喜欢的方式对其进行命名,条件是遵守常用的命名规则。
  • 必须知名名称空间std;
  • 需要将ifstream对象与文件关联起来,方法是使用open()方法。
  • 使用完文件后,应使用方法close()将其关闭。
  • 可结合使用ifstream对象和运算符>>来输出各种类型的数据。

检查文件是否被成功打开的代码:

inFile.open("bowling.txt");
if(!inFile.open())
{
	exit(EXIT_FAILUTE);
}

检测文件尾:inFile.eof();
检测输入是否正确,到达文件尾inFile.good();

6.9 复习题

1. 请看下面两个计算空格和换行符数目的代码片段:
// Version 1
while (cin.get(ch))
{
	if(ch == ' ')
		spaces++;
	if(ch == '\n')
		newlines++;
}

// Version 2
while (cin.get(ch))
{
	if (ch == ' ')
		spaces++;
	else if(ch == '\n')
		newlines++;
}

第二种格式比第一种格式好在哪里?
两个版本给出的答案下同,if else的效率更高。考虑ch为空格的情况,版本1还需要查看ch是不是换行符,而版本2不需要,效率更高。

2. 在程序清单6.2中,用ch+1替换++ch将发生什么情况呢?

替换之后会发生输出的字符与输入的字符一样。
本题考虑的不是运算优先级的问题,而是ch + 1将改变字符的数据类型,变为int将作为int打印。

3. 请认真考虑下面的程序:
#include<iostream>
using namespace std;
int main()
{
	char ch;
	int ct1,ct2;
	ct1 = ct2 = 0;
	while((ch = cin.get()) != '$')
	{
		cout << ch;
		ct1++;
		if(ch = '$')
			ct2++;
		cout << ch;
	}
	cout << "ct1 = " << ct1 << ", ct2 = " << ct2 << "\n";
	return 0;
}

假设输入如下(请在每行末尾按回车键):
Hi!
Send $10 or \(20 now! 则输出将是什么(还记得吗,输入被缓冲)? H\)i\(!\)
\(S\)e\(n\)d$ $ct1 = 9, ct2 = 9

4. 创建下述条件的逻辑表达式:
  • a.weight大于或等于115,但小于125
    weight >= 115 && weight <125
  • b.ch为q或Q
    ch == 'q' or ch == 'Q'
  • c.x为偶数,但不是26
    (x % 2) == 0 && 26 != x
  • d.x为偶数,但不是26的倍数
    (x % 2) == 0 && (x % 26) != 0
  • e.donation 为1000-2000或guest为1
    (donation >= 1000 && donation <= 2000) or 1 == guest
  • f.ch是小写字母或大写字母(假设小写字母是依次编码的,大写字母也是依此编码的,但在大小写字母间编码不是连续的)
    ((ch >= 'a' && ch <= 'z') or (ch >= 'A' && ch <= 'Z'));
5. 在英语中,“I will not not speak”的意思与“I will speak”相同,在C++中, !!x 是否与x相同呢。

不相同不一定 x = 5,!!x = 1.;x为bool变量,则!!x = x。

6. 创建一个条件表达式,其值为变量的绝对值。也就是说,如果变量x为正,则表达式x的值为x;但如果x的值为负,则表达式的值为-x——这是一个正值。

x > 0 ? x:-x
(x >= 0)?x:-x

7. 用switch修改下面的代码片段:
if(ch == 'A')
	a_grade++;
else if(ch == 'B')
	b_grade++;
else if(ch == 'C')
	c_grade++;
else if(ch == 'D')
	d_grade++;
else 
	f_grade++;

switch代码如下:

switch(ch)
	case 'A' : a_grade++;break;
	case 'B' : b_grade++;break;
	case 'C' : c_grade++;break;
	case 'D' : d_grade++;break;
	default: f_grade++;//break;

default需要加break;

8. 对于程序清单6.10,与使用数字相比,使用字符(如a和c)表示菜单选项和case标签有何优点呢?(提示:想想用户输入q和输入5的情况)
  • 使用字符,当输入数字时,可以提醒用于错了,重新输入,而使用数字,输入字符会使程序陷入死循环(挂起)
9. 请看下面的代码片段:
int line = 0;
char ch;
while (cin.get(ch))
{
	if(ch == 'Q')
		break;
	if(ch != '\n')
		coutinue;
	line++;
}

请重写该代码片段,不要使用break和continue语句。

int line = 0;
char ch;
while (cin.get(ch)&& (ch != 'Q'))
{
	if(ch == '\n')
		line++;
}
posted @ 2021-12-10 16:28  Fight!GO  阅读(56)  评论(0编辑  收藏  举报