C++提供了if和switch语句来进行决策,还有逻辑运算符和条件运算符。
使用if语句来统计语句中的空格总数,实现如下:
if.cpp
#include
using namespace std;
int main()
{
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 << " charachers total in sentence.\n";
return 0;
}
结果:
The balloonist was an airhead
with lofty goals.
6 spaces, 46 charachers total in sentence.
只要当ch为空格时,语句spaces++才被执行。因为语句total位于if语句的外面,因此每轮循环中都被执行。
if (test-condition)
statement1
else
statement2
如果测试条件为true,则程序将执行statement1,跳过statement2;如果测试条件为false,则程序将跳过statement1,执行statement2。
如果操作部分需要多条语句,需要使用大括号将它们括起来,组成一个语句块。
if (ch == 'z')
{
zorro++;
cout << "Another zorro candidate\n";
}
else
{
dull++;
cout << "Not a Zorro candidate\n";
}
实际中,可能需要程序提供两个以上的选择:
if (ch == 'A')
a_grade++;
else
if (ch == 'B')
b_grade++;
else
soso++;
可以写成如下形式:
if (ch == 'A')
a_grade++;
else if (ch == 'B')
b_grade++;
else
soso++;
修改后的格式更为清晰。
ifelseif.cpp
#include
using namespace std;
const int Fave = 27;
int main()
{
int n;
cout << "Enter a number in the range 1-00 to find my favorite nmber: \n";
do
{ cin >> n;
if (n > Fave)
cout << "Too high -- guess again:";
else if (n < Fave)
cout << "Too low -- guess agin: ";
else
cout << Fave << " is right!\n";
}while (n != Fave);
return 0;
}
结果:
Enter a number in the range 1-00 to find my favorite nmber:
22
Too low – guess agin: 44
Too high – guess again:27
27 is right!
错误防范:
表达式variable == value反转写成value == varibale。这样,可以捕获将相等运算符误写成赋值运算符的错误。
if (3 = var)
将一个变量赋给一个常量,编译器将生成错误信息。
if (var = 3)
这样,将3赋给一个变量,正确的语法,编译不会报错,于是会导致程序出错。
C++提供了三种逻辑运算符,分别是:逻辑OR(||)、逻辑AND(&&)和逻辑NOT(!)。
如果表达式中的任意一个或全部都为true,则得到的表达式为true。
5 == 5 || 5 == 9 //true
3 <= 5 || 5 >= 3 //true
1 > 2 || 2 > 3 //False
||运算符的优先级比关系运算符低,因此不需要添加括号。
C++规定,||运算符是个顺序点。即,先修改左侧的值,再对右侧的值进行判定。例如:
i++ < 6 || i == j
假设i越来的值为10,则在对i和j进行比较时,i的值将为11。另外,如果左侧的表达式为true,则C++将不会去判定右侧的表达式,因为只要一个表达式为true,则整个逻辑表达式为true。
仅当两个表达式都为true时,得到的表达式才为true。
5 == 5 && 4 == 4//true
5 < 3 && 3 > 2 //false
&&运算符的优先级低于关系运算符,因此没必要添加括号。和||运算符一样,&&运算符也是顺序点,因此将先判定左侧,并且在右侧判定之前产生所有的副作用。如果左侧为false,则整个逻辑表达式为false,这种情况下,C++将不会再对右侧进行判定。
&&运算符还允许建立一系列if else if else语句,其中每种选择都对应一个特定的取值范围。
if (age > 17 && age < 35)
index = 0;
else if (age >= 35 && age < 50)
index = 1;
else if (age >= 50 && age < 65)
index = 2;
else
index = 3;
注意,下面语句:
if (17 < age < 35)
编译器不会捕获这种错误,因为它仍然是合法的C++语法。<运算符是从左向右结合,因此表达式含义如下:
if ((17 < age) < 35)
但(17 !运算符将它后面的表达式的真值取反。!运算符的优先级高于所有的关系运算符和算术运算符。因此,要对表达式取反,必须使用括号将其括起来,如下: !运算符对于返回true-false值或可以被解释为true-false值的函数是很有用的。比如: 下面的程序来筛选可赋给int变量的数字输入。 not.cpp 结果: 布尔函数is_int()使用了climits文件中定义的两个符号常量INT_MIN和INT_MAX来确定int类型的范围。 AND和OR运算符的优先级都低于关系运算符。 !运算符的优先级都高于所有关系运算符和算符运算符。 逻辑AND运算符的优先级高于逻辑OR运算符,因此: 被解释为: 当然,还可以使用括号来将所希望的解释告诉程序。例如: C++确保程序从左向右进行逻辑运算表达式,并在知道了答案立刻停止。 使用标识符and、or和not来表示三种逻辑运算符。 | 运算符 | 另一种表示方式 | C++继承了一个与字符相关的、非常方便的函数软件包,他可以简化如确定字符是否为大小写字母、数字、标点符号等工作,这些函数的原型在头文件cctype(老式的风格ctype.h)中定义。 下面使用AND和OR来测试字符ch是不是字母字符的代码: 与使用isalpha()相比: isslpha()不仅更容易使用,而且更通用。 下面程序演示cctype库函数。 cctypes.cpp 结果: cctype中的字符函数: | 函数名称 | 返回值 | C++常用?:运算符来代替if else语句,它C++中唯一的3个操作数的运算符。通用格式如下: 如果expression1为true,则整个表达式的值为expression2;否则,整个表达式的值为expression3。如下: condit.cpp 结果: 将条件表达式嵌套在另一个条件表达式中,如下: 这是一种费解的方式,他按下面的顺序打印3个字符串: 从可读性来说,条件运算符最适合简单关系和简单表达式的值。 用户从5个选项中选择一个,虽然可以扩展if else if else来处理,但C++的switch语句能够更容易地从大型列表中进行选择。switch语句的通用格式: switch.cpp 当用户输入5时,while循环结束。输入1到4将执行switch列表中相应的操作,输入6将执行默认语句。 同时,也可以使用字符(而不是整数)作为菜单选项和switch标签,则可以为大写标签和小写标签提供相同的语句: 由于case 'a’后面没有break语句,因此程序将执行下一行–case 'A’后面的语句。 使用enum定义了一组相关常量,然后在switch语句中使用这些常量。通常,cin无法识别枚举类型,因此该程序要求用户选择选项时输入一个整数。将switch语句将int值和枚举标签进行对比时,将枚举类型提升为int。 enum.cpp 结果: switch语句和if else语句都允许程序从选项中进行选择。if else更通用,它可以处理取值范围。而switch并不是为处理范围而设计的,switch语句中的每一个case标签都必须时一个单独的值。另外,这个值必须是整数(包括char),因此switch无法处理浮点测试。另外,case标签值必须是常量。 break和continue语句都是程序能过跳过部分代码。可以在switch语句或任何循环中使用break语句,使程序跳到switch或循环后面的语句处执行。continue语句用于循环中,让程序跳过循环体中余下的代码,并开始新一轮循环。如下图: jump.cpp 结果: 程序说明 虽然continue语句导致该程序跳过循环体的剩余部分,但不会跳过循环的更新表达式。在for循环中,continue语句使程序直接跳到更新表达式,然后跳到测试表达式。然而,对于while循环,continue将使程序直接跳到测试表达式,因此while循环中位于continue之后的更新表达式都被跳过。在某些情况下,这是一个问题。 将一系列数字读入数组中,并允许用户在数组填满之前结束输入,利用如下代码: 如果用户输入一个单词,而不是一个数字,发送这种类型匹配情况时,将发生4种情况: 假设编写一个程序,来计算每天捕获的鱼的重量。这里假设每天最多捕获5条鱼,因此一个包含5个元素的数组将足以存储所以的数据,但也可能没有捕获这么多。如果数组被填满或输入了非数字输入,循环将结束。 cinfish.cpp 结果: 上述程序中,cin>>fish[i]实际上是一个cin方法函数调用,该函数返回cin。如果cin位于测试条件中,则将被转化为bool类型。如果输入成功,则转换后为true,否则为false。 当用户输入的不是数字时,该程序将不再读取输入。下面再看一个例子,假设程序要求用户提供5个高尔夫得分,以计算平均分。如果用户输入非数字,程序拒绝,并要求用户继续输入数字。可以看到,可以使用cin输入表达式来检测输入是不是数字。程序发现用户输入了错误内容时,应采取3个步骤: cingolf.cpp 结果: clear()方法重置输入,如果省略这条语句,程序将拒绝继续读取输入。程序中如下代码的作用是: 读取行尾之前的所有输入,从而删除这一行的错误输入。 C++使得将读取键盘输入和在屏幕上显示输出的技巧用于文件输入/输出(文件I/O)非常简单。 使用cin进行输入时,程序将输入视为一系列的字节,其中每个字节都被解释为字符编码。不管目标数据类型是什么,输入一开始都是字符数据–文本数据。然后,cin对象负责将文本转换为其他类型。 输入实例为: 38.5 19.2 输入行中的第一个字符被赋给ch。在这里第一个字符是数字3,其字符编码(二进制)被存储在变量ch中。输入和目标变量都是字符,因此不需要进行转换。注意,这里存储的不是数值3,而是字符3的编码。 在这种情况下,cin将不断读取,直到遇到非数字符号。也就是说,它读取3和8,这样句点将成为输入队列中的下一个字符。cin通过计算发现,这两个字符对应数字是38,因此将38的二进制编码复制到变量n中。 接下来看double类型: 在这种情况下,cin将不断读取,直到遇到第一个不属于浮点数的字符。即,cin读取3、8、句点和5,使得空格成为输入队列中的下一个字符。cin通过计算发现,这四个字符对应数字38.5,因此将38.5的二进制编码复制到变量x中。 接下来看看char数组的情况: 在这种情况下,cin将不断读取,直到遇到空白字符。即,它读取3、8、句点和5,使得空格成为输入队列中的下一个字符。然后,cin将这4个字符编码存储到输入word中,并在末尾加上一个空字符,这里需要进行任何转换。 最后,看一下另一种使用char数组来存储输入的情况: 在这种情况下,cin将不断读取,直到遇到换行符。所有字符都将被存储到数组word中,并在末尾添加一个空字符。换行符被丢弃,输入队列中的下一个字符是下一行的第一个字符。这里不进行任何转换。 对于输出,将执行相反的操作。即整数被转换为数字字符序列,浮点数被转换为数字字符和其他字符组成的字符序列。字符数据不需要做任何转换。 这里的要点是:输入一开始都是文本。因此,控制台输入的文件版本是文本文件,即每个字节都存储了一个字符编码的文件。并非所有的文件都是文本文件,比如,数据块和电子表格以数值格式(即二进制整数或浮点格式)存储数值数据。 文件输出: iostream头文件提供了一个预先定义好的名为cout的ostream对象,但您必须声明自己的ofstream对象,为其命名,并将其同文件关联。声明对象如下: 关联文件如下: open()接受一个c-风格字符串作为输入,可以是字面字符串,也可以是存储在数组中的字符串。 使用文件输出的主要步骤如下: outfile.cpp 结果: 在程序运行之前,并不存在carinfo.txt文件。在这种情况下,open()将新建一个名为carinfo.txt的文件。如果在此程序运行前,该文件已存在。默认情况下,open()将首先截断该文件,即将其长度截断为零—丢弃原有的内容,然后将新的输入加入到该文件中。 文件输入: ifstream对象的声明: 关联文件: 如果试图打开一个不存的文件用于输入,这种错误将导致后面使用ifstream对象进行输入时失败。检查文件是否被成功打开的方法:is_open()。 函数exit()的原型在头文件cstdlib中定义的,在该头文件中,还定义了一个用于同操作系统通信的参数数值EXIT_FAILURE。函数exit()终止程序。 方法is_open()是C++中比较新的内容。可以使用方法good()来代替。 sumafile.cpp 结果: 文件循环读取设计时,需要注意几点。首先,程序读取文件时不应超过EOF。如果最后一次读取数据时遇到EOF,方法eof()返回true。其次,程序可能遇到类型不匹配,方法fail()返回true(如果遇到EOF,该方法也返回true)。最后,可能出现意外的问题,如文件损坏或硬件故障。如果最后一次读取文件出现了这样的问题,方法bad()将返回true。不要分布检查这些情况,一种更简单的方式是使用good()方法,该方法在没有发送任何错误时返回true。同时,可以使用其他方法来确定循环终止的原因,如下: 方法god()指出最后一次读取输入的操作成功与否。标准的做法: 由于表达式inFile >> value的结果为inFile,而在需要一个bool值的情况下,inFile的结果为inFile().good(),即true或false。于是,两条输入语句用一条用作循环测试的语句代替。因此可以简化上面标准做法,如下: if语句、if else语句和switch语句 逻辑运算符 文件输出和输入6.2.4 逻辑NOT运算符
!( x > 5);
!x > 5; // 该表达式总是为false,!x为1或0,总是小于5
!strcmp(s1,s2);
#include
Enter an integer value:1000000000000000
Out of range -- please try again:-1000000000000
Out of range -- please try again:444
You've entered the integer 444
6.2.5 逻辑运算符细节
age > 30 && age < 45 || weight > 300
(age > 30 && age < 45) || weight > 300
(age > 30 || weight > 300) && donation > 1000
6.2.6 其他表示方式
|—|
| && | and |
| || | OR |
| ! | NOT |6.3 字符函数库cctype
if (ch >= 'a' and ch <= 'z') || (ch >= 'A' && ch <= 'Z')
if (isalpha(ch))
#include
Enter text for analysis and type @ to terminate input:
AdrenalVision Internationsl producer Adrienne Vismonger
announced production of their new 3-D film, a remake of
"My Dinner with Andre," scheduled for 2013.
@
123 letters, 23 whitespace, 5 digits, 6 punctuations, 0 others.
|—|
| isalnum() | 如果参数是字母数字,即字母或数字,该函数返回true|
| isalpha() | 如果参数是字母,该函数返回true |
| iscntrl() | 如果参数是控制字符,该函数返回true |
| isdigit() | 如果参数是数字(0~9),该函数返回true |
| isgraph() | 如果参数是除空格之外的打印字符,该函数返回true |
| islower() | 如果参数是小写字母,该函数返回true |
| isprint() | 如果参数打印字符(包括空格),该函数返回true |
| ispunct() | 如果参数是标点符号,该函数返回true |
| isspace() | 如果参数是标准空白字符,如空格、换行符、回车、制表符,该函数返回true |
| isupper() | 如果参数是大写字母,该函数返回true |
| isxdigit() | 如果参数是十六进制,该函数返回true |
| tolower() | 如果参数是大写字母,则返回小写字母 |
| toupper() | 如果参数是小写字母,则返回大写字母 |6.4 ?:运算符
expression1 ? expression2 : expression3
5 > 3 ? 10 : 12 //5>3为true,所以该表达式的值为19
3 == 0 ? 25 : 18 // 3==0为false,所以表达式的值为18
#include
Enter two integers: 2 3
The larger of 2 and 3 is 3
const char x[2][20] = {"Jason ", "at your serviece\n"};
const char * y = "Quillstone ";
for (int i = 0; i < 3; i++)
cout << ((i < 2) ? !i ? x[i]:y : x[i]);
Jasn Qullstone at your service
6.5 switch语句
switch (integer-expression)
{
case label1: statement(s);
case label2: statement(s);
default: statement(s);
}
#include
char choice;
switch (choice)
{
case 'a' :
case 'A' : cout << "\a\n";
break;
case 'b' :
case 'B' : report();
break;
case 'c' :
case 'C' : cout << "The boss was in all day.\n";
break;
case 'd' :
case 'D' : comfort();
break;
default : cout << "That's not a choce.\n";
}
6.5.1 将枚举用作标签
#include
Enter color code(0-6):0
Her lips were red.
Enter color code (0-6):2
Her sheos were yellow.
Enter color code (0-6):6
Others.
Enter color code (0-6):7
Bye!
6.5.2 switch和if else
6.6 break和continue
#include
Enter a line of text:
Let's do lunch today. you can pay!
Complete line:
Let's do lunch today. you can pay!
Line through first period:
Let's do lunch today.
17 letters.
6.7 读取数字的循环
int n;
cin >> n;
#include
Please enter the weights of your fish.
You may enter up to 5 fish < q to terminate>.
fish #1: 10.2
fish # 2: 2.3
fish # 3: 4.5
fish # 4: q
5.66667 average weight of 3 fish.
[root@localhost ~]# ./a.out
Please enter the weights of your fish.
You may enter up to 5 fish < q to terminate>.
fish #1: q
No fisht.
#include
Enter your golf scores.
You must enter 5 rounds.
Round# 1 : 88
Round# 2 : i
Please enter a number: k
Please enter a number: 4
Round# 3 : 5
Round# 4 : 9
Round# 5 : ?
Please enter a number: 44
30 = average score 5 rounds.
while(cin.get()!='\n')
continue;
6.8 简单文件输入/输出
6.81 文本I/O和文本文件
char ch;
cin >> ch;
int n;
cin >> n;
double x;
cin >> x;
char word[50];
cin >> word;
char word[50];
cin.getline(word,50);
6.8.2 写入的文本文件中
ofstream outFile;
outFile.open("fish.txt");
char filename[50];
cin >> filename;
outFile.open(filename);
#include
6.8.3 读取文本文件
ifstream inFile;
inFlie.open("bowling.txt");
inFile.open("bowling.txt");
if (!inFile.is_open())
exit(EXIT_FAILURE);
#include
if (inFile.eof())
cout << "End of file reached.\n";
else if (inFile.fail())
cout << "Input terminatd by data mismatch.\n";
else
cout << "Input terminated for unknown reasion.\n";
inFile >> value;
while (inFile.good())
{
++count ;
sum += value;
inFile >> value;
}
while(inFile >> value)
{
sum += value;
++count;
}
6.9 总结