if (test-condition)
statement
if
else
if
else if
else
逻辑OR运算符:||
C++规定,||运算符是个顺序点(sequence point)。也是说,先修改左侧的值,再对右侧的值进行判定。例如,如下表达式
i++ < 6 || i == j
假设 i 原来的值为10,在将i++与6进行比较时,i++的值为10,但在将i与j进行比较时,i的值为11;
另外,如果左侧的表达式为true,则C++将不会去判定右侧的表达式,因为只要一个表达式为 true,则整个逻辑表达式为 true(冒号和逗号运算符也是顺序点)
逻辑AND运算符:&&
逻辑NOT运算符:!
一些细节:
C++逻辑OR和逻辑AND运算符的优先级都低于关系运算符。
这意味着下面的表达式:
x > 5 && x < 10
将被解释为:
(x>5) && (x<10)
另一方面,!运算符的优先级高于所有的关系运算符和算术运算符。因此,要对表达式求反,必须用括号将其括起,如下所示:
!(x>5)
而!x > 5 的值总是false,因为!x的值只能为true或false,而它们将被转换为 1 或 0.
逻辑 AND 运算符的优先级高于逻辑 OR 运算符。因此,表达式:
age > 30 && age < 45 || weight > 300
会被解释为 :(age > 30 && age < 45) || (weight > 300)
如果这两个条件中的一个或全部都为 true,则整个表达式为true。
但最简单的方法就是用括号,这样代码容易阅读,避免读者查看不常使用的优先级规则,并减少由于没有准确记住所使用的规则而出错的可能性。
C++提供了逻辑运算符的另一种表示方式:
&& ----- and
|| ------ or
! ----- not
这意味着 and、or、not 都是C++保留字,不能用作变量名。它们并不是C语言的保留字,但是在程序中包含了iso646.h头文件,C程序也可以将它们用作运算符。
C++从C语言继承了一个与字符相关的、非常方便的函数软件包,它可以简化诸如确定字符是否为大写字母、数字、标点符号等工作,这些函数的原型是在头文件cctype(老式风格为ctype.h)中定义的。例如,如果ch是一个字母,则 isalpha(ch) 函数返回一个非零值,否则返回0。同样,如果 ch 是标点符号(如逗号或句号),函数 ispunct(ch) 将返回 true。(这些函数的返回类型为 int,而不是 bool,但通常 bool 转换 可以让程序员把它们当作 bool 类型。)
函数名称 | 返回值 |
---|---|
isalnum() | 如果参数是字母数字,即字母或数字,该函数返回true |
isalpha() | 如果参数是字母,该函数返回 true |
iscntrl() | 如果参数是控制字符,该函数返回 true |
isdigit() | 如果参数是数字(0~9),返回 true |
isgraph() | 如果参数是除空格之外的打印字符,返回true |
islower() | 如果参数是小写字母,返回true |
isprint() | 如果参数是打印字符(包括空格),返回true |
ispunct() | 如果参数是标点符号,返回 true |
isspace() | 如果参数是标准空白字符,如空格、进纸、换行符、回车、水平制表符或者垂直制表符,返回true |
isupper() | 如果参数是大写字母,返回 true |
isxdigit() | 如果参数是十六进制数字,即 0~ 9、a~ f或 A ~ F,返回 true |
tolower() | 如果参数是大写字符,则返回其小写,否则返回该参数 |
toupper() | 如果参数是小写字符,则返回其大写,否则返回该参数 |
C++有一个常被用来代替 if else 语句的运算符,这个运算符被称为条件运算符(?:),条件运算符(?:)是 C++ 中唯一一个需要 3 个操作数的运算符。该运算符的通用格式如下:
expression1 ? expression2 : expression3
如果 expression1 为 true,则整个表达式的值为 expression2 的值;否则,整个表达式的值为 expression3 的值。下面的两个示例演示了该运算符是如何工作的:
5 > 3 ? 10 : 12 // 5>3 is true, so expression value is 10
3 == 9 ? 25 : 18 // 3 == 9 is false, so expression value is 18
用一句话概括就是:真前假后
switch (integer-expression){
case label1 : statement(s)
case label2 : statement(s)
case label3 : statement(s)
...
default : statement(s)
}
顾名思义,interger-expression 必须是一个结果为整数值的表达式,相应的,每个标签都必须是整数常量表达式。
最常见的标签是 int 或 char 常量,也可以是枚举量。
如果 integer-expression 不与任何标签匹配,则程序将跳到标签为 default 的那一行。
Default 标签是可选的,如果被省略,而又没有匹配的标签,则程序将跳到 switch 后面的语句处执行。
C++ 中的 case 标签只是行标签,而不是选项之间的界限。也就是说,程序跳到switch中特定代码行之后,将依次执行之后的所有语句,除非有明确的其它指示。程序不会在执行到下一个case处自动停止,要让程序执行完一组特定语句后停止,必须使用 break 语句,这将导致程序跳到 switch 后面的语句处执行。switch语句会执行第一次进入case之后的所有语句,包括在那之后的其它case的语句
char choice;
cin >> choice;
while (choice != 'Q' && choice != 'q'){
switch(choice){
case 'a':
case 'A': cout << "\a\n";
break;
case 'r':
case 'R': report();
break;
case 'c':
case 'C': comfort();
break;
default : cout << "That's not a choice.\n"
}
showmenu();
cin >> choice;
}
由于case ‘a’ 后面没有 break 语句,因此程序将接着执行下一行——case ‘A’ 后面的语句。
switch 语句 和 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;
然而,switch并不是为处理取值范围而设计的。switch语句中的每一个case标签都必须是一个单独的值。另外,这个值必须是整数(包括 char),因此 switch 无法处理浮点测试。另外 case 标签值还必须是常量。如果选项设计取值范围、浮点测试或两个变量的比较,则应使用 if else 语句。
然而,如果所有的选项都可以使用整数常量来标识,则可以使用 switch 语句 或 if else 语句。由于switch语句是专门为这种情况设计的,因此,如果选项超过了两个,则就代码长度和执行速度而言,switch语句的效率更高。
break 和 continue 语句都使程序能够跳过部分代码。可以在 switch 语句或任何循环中使用 break 语句,使程序跳到 switch 或循环后面的语句处执行。continue 语句用于循环中,让程序跳过循环体中余下的代码,并开始新一轮循环。
虽然 continue 语句会跳过循环体的剩余部分,但不会跳过循环的更新表达式。在for循环中,continue 语句使程序直接跳到更新表达式处,然后跳到测试表达式处。
然而,对于while循环来说,continue 将使程序直接跳到测试表达式处,这意味着位于continue之后的更新表达式都将被跳过。在某些情况下,这可能是一个问题。
和 C 语言一样, C++ 也有goto语句。下面的语句将跳到使用 paris: 作为标签的位置:
goto paris;
也就是说,可以有下面这样的代码:
char ch;
cin >> ch;
if(ch == 'P')
goto paris;
cout << ...
...
paris: cout << "You've just arrived at Paris.\n";
在大多数情况下(有些人认为,在任何情况下),使用 goto 语句不好,而应使用结构化控制语句(如 if else、switch、continue 等)来控制程序的流程。
int n;
cin >> n
如果用户输入一个单词,而不是一个数字,情况将如何呢?发生这种类型不匹配的情况时,将发生4种情况:
int golf[Max];
cout << "Please enter your golf scores.\n";
cout << "You must enter " << Max << " rounds.\n";
int i;
for (i=0; i < Max; i++){
cout << "round #" << i+1 << ": ";
while(!(cin>>golf[i])){
cin.clear()
while (cin.get() != '\n')
continue;
cout << "Please enter a number: ";
}
}
C++使得将读取键盘输入和在屏幕上显示输出(统称为控制台输入/输出、控制台I/O)的技巧用于文件输入/输出(文件I/O)非常简单。
这里讨论文本文件,即每个字节都存储了一个字符编码的文件。
先总结一下有关将cout用于控制台输出的基本事实,为文件输出做准备:
文件输出与此极其相似
注意,虽然头文件iostream提供了一个预先定义好的名为cout的ostream对象,但您必须声明自己的ofstream对象,为其命名,并将其同文件关联起来。
下面演示了如何声明这种对象:
ofstream outFile;
ofstream fout;
下面演示了如何将这种对象与特定的文件关联起来:
outFile.open(“fish.txt”);
char filename[50];
cin >> filename;
fout.open(filename)
方法open()接受一个C-风格字符串作为参数,这可以是一个字面字符串,也可以是存储在数组中的字符串。
下面演示了如何使用这种对象:
double wt = 125.8;
outFile << wt;
char line[81] = “Objects are closer than they appear.”;
fout << line << endl; // write a line of text
重要的是,声明一个 ofstream 对象并将其同文件关联起来后,便可以像使用 cout 那样使用它。所有可用于 cout 的操作和方法(如 <<、endl 和 setf())都可用于 ofstream 对象(如前述示例中的 outFile 和 fout)。
总之,使用文件输出的主要步骤如下:
默认情况下,open()将首先截断该文件,即将其长度截短到零——丢其原有的内容,然后将新的输出加入到该文件中。
打开文件用于接受输入时可能失败。例如,指定的文件可能已经存在,但是禁止对其进行访问。因此细心的程序员将检查打开文件的操作是否成功,这将在下一个例子中介绍。
接下来介绍文本文件输入,它是基于控制台输入的。控制台输入涉及多个方面,下面首先总结这些方面:
文件输入于此极其相似:
如果试图打开一个不存在的文件用于输入,情况将如何呢?这种错误将导致后面使用 ifstream 对象进行输入时失败。检查文件是否被成功打开的首先方法是使用方法 is_open(),为此,可以使用类似于下面的代码:
inFile.open("bowling.txt");
if ( !inFile.is_open()){
exit(EXIT_FAILURE);
}
inFile >> value;
while(inFile.good()){
...
}
if(inFile.eof()){
}
else if (inFile.fail()){
}
else{
}
inFile.close();
注意,good()方法指出最后一次读取输入的操作是否成功,这一点至关重要。为此,一种标准的方法是,在循环之前(首次执行循环测试之前)放置一条输入语句,并在循环的末尾(下次执行循环测试之前)放置另一条输入语句:
inFile >> value;
while(inFile.good()){
...
inFile >> value;
}
或者,直接改为
while(inFile >> value){
…
}