2.6 赋值表达式和类型转换
2.6.1 赋值表达式含有赋值运算符的表达式叫做赋值表达式。其一般形式为:
variable = expression
可以看出,在赋值表达式中,赋值运算符的左操作数必须是一个变量,而右操作数可以是任一合法的表达式。赋值表达式的值就是其右操作数的值。
由于赋值运算符要求其右操作数为一个表达式,而赋值表达式是一个合法的表达式,所以可以将赋值表达式用做赋值运算符的右操作数,从而构成所谓的“串连”赋值表达式。如:
i = j = 3 * 5
2.6.2 增量减量运算符
++ --
增量和减量运算符都是隐含有赋值操作的运算符,它们将其操作数(必须是 int 或 char 型变量)的值加 1 或减 1。这两个运算符虽然都是一元运算符,但由于操作数即可以放在运算符的左边(后置),又可以放在运算符的右边(前置),
从而使得它们对其他运算产生不同的影响。设 i 是一个 int 型变量,则增量和减量运算符将有以下 4 种使用形式:
++ i // 前置增量
-- i // 前置减量
i ++ // 后置增量
i -- // 后置减量对于单个增减量表达式所构成的语句来说,前置和后置的运算结果是没有什么区别的。而对于还包含有其他运算的表达式来讲,前置和后置的运算结果将会产生不同的效果。
例:
//…
i = 3;
j = i ++; // j 的值为 3,i 的值为 4
k = ++ i; // k 的值为 5,i 的值为 5
注意:由于不同的编译器对增减量运算符处理的不同,所以类似以下的用法将存在移植性问题。
cout << i ++ << '\t' << i ++ << endl;
2.6.3 复合赋值运算符
+= -= *= /= %=
&= |= ^= <<= >>=
复合赋值运算符均是二元运算符,它们的运算过程为:先将运算符左右操作数的值进行运算符所规定的算术或位运算,然后将运算的结果赋给左操作数。
例:
i += 2; // 等效于,i ++; i ++
i *= i + j; // 等效于,t = i + j; i = i * t;
2.6.4 表达式中的类型转换
C++ 语言支持不同数据类型的混合运算。当一个表达式中存在不同类型的数据时,编译器会自动地对数据进行转换,以使所有参加运算的数据之类型趋于相同,从而保证运算的精度。自动转换的一般原则是短数据被转换成长数据。
例:
f = i + j * 0.5
double
double
应当说明的是,类型转换都是临时性的,转换并不改变变量的数据类型,
仅改变变量的值。因此,使用不当有可能导致数据精度的丧失。例如:设
i,j 是 int 型变量,j 的值为 3,则:
i = j * 0.3
后,i 的值为 0。
2.6.5 强制类型转换编译器的自动类型转换可控性较差,有时甚至不能满足程序的需要。比如:设 i 为 int 型变量,其值为 5; f 为 float 型变量。则
f = i / 4 + 20.3
后,f 的值为 21.3 而不是预期的 21.55。
强制类型转换( cast) 是解决这一类问题的有效手段,其一般形式为:
(type)expression 或 type(expression)
例:
f = float(i) / 4 + 20.3 f = i / 4.0 + 20.3
2.7 简单变量的初始化
2.7.1 变量的初始化初始化就是指在说明变量的同时为它指定一个初值,其一般形式为:
<storage> type var_name = expression;
例:
int i = 3,j = 5;
C++ 语言还允许采用以下的形式来初始化变量:
<storage> type var_name(expression);
例:
int i(3),j(5);
2.7.2 const 和 volatile 修饰符关键字 const 和 volatile 是 C++ 语言的两个类型修饰符,他们均可以用来修饰变量,前者还可以修饰函数。
被 const 修饰的变量叫做常量标识符,即该变量虽然具有变量的形式,但其值是不允许修改的。因此,必须对常量标识符进行初始化。
例:
const int i = 5;
//…
i = 3; // 非法操作
volatile 修饰符由于涉及底层操作,且极少使用,这里就不做进一步介绍。
第 3章 程序控制语句
3.1 C++ 语言的语句
3.1.1 C++ 语句的基本形式
C++ 语句的基本形式就是一个表达式后跟一个分号(,;”)。
例:
a = b + c; // 典型语句
i + j; // 合法语句,但无实用价值; // 空语句
C++ 语言中,变量说明也是语句,因此它可以出现在任何语句可以出现的地方。
3.1.2 块语句块语句也叫复合语句,它是用一对花括号括起来的多条语句,
而在语法上却等效于一条语句。
例:
//…
{
int t = a;
a = b;
b = t;
}
3.2 选择语句
3.2.1 if 语句
3.2.1.1 基本的 if 语句
if(expression)
statement;
其中,expression 是一个关系表达式; statement 是 一条 语句。
例:
if(a > 10) if(x < y) {
a -= 5; int t = x;
a += 3;
x = y;
y = t;
}
3.2.1.2 扩展的 if 语句
if(expression)
statement1;
else
statement2;
例:
if(a >= b)
nMax = a;
else
nMax = b;
#include <iostream.h>
int main()
{
int x,y;
cout << "Please input two integers,";
cin >> x >> y;
if(x >= y)
cout << "The max is " << x << endl;
else
cout << "The max is " << y << endl;
return 0;
}
3.2.2 if 语句的嵌套例:输出 3 个数中的最大数。
#include <iostream.h>
int main()
{
int a,b,c;
cin >> a >> b >> c;
cout << "The maximum is ";
if(a >= b)
if(a >= c)
cout << a << endl;
else
cout << c << endl;
else
if(b >= c)
cout << b << endl;
else
cout << c << endl;
return 0;
}
3.2.3 三元条件表达式三元运算符,?:”的一般使用形式为:
expression? expression1,expression2
它等效于如下的 if 语句:
if(expression)
expression1;
else
expression2;
例:
cout << (a >= b? a,b) << endl;
例:输出 3 个数中的最大数的另一版本。
#include <iostream.h>
int main()
{
int a,b,c;
cin >> a >> b >> c;
cout << "The maximum is ";
cout << (a >= b? (a >= c? a,c),(b >= c? b,c)) << endl;
return 0;
}
3.2.4 switch 语句
switch 语句也叫开关语句,其一般形式为:
switch(expression) {
case value1:
statement1;
<break;>
…
case valuen:
statementn;
<break;>
<default:
statementn+1;
<break;>>
}
switch 语句的执行过程为:若某个 case 后边的常量 valuei
的值与表达式 expression 的值相等(匹配),则执行该分支中的语句,直到遇到 break 语句为止。若表达式的值与任何一个常量的值都不相等,则:如果存在 default 分支,则执行该分支中的语句;否则什么都不作。
注意,switch 语句执行过程决定了若某一分支必须执行多条语句,则不必使用块语句。
例:一个简单的计算器程序
#include <iostream.h>
int main()
{
int n1,n2;
char op;
cout << "Enter a simple arithmetic expression,";
cin >> n1 >> op >> n2;
switch(op) {
case '+':
cout << n1 + n2 << endl;
break;
case '-':
cout << n1 - n2 << endl;
break;
case '*':
cout << n1 * n2 << endl;
break;
case '/':
cout << n1 / n2 << endl;
break;
default:
cout << "Illegal operator!" << endl;
}
return 0;
}
例:将上例改为 if 语句
#include <iostream.h>
int main()
{
int n1,n2;
char op;
cout << "Enter a simple arithmetic expression,";
cin >> n1 >> op >> n2;
if(op == '+')
cout << n1 + n2 << endl;
else
if(op == '-')
cout << n1 - n2 << endl;
else
if(op == '*')
cout << n1 * n2 << endl;
else
if(op == '/')
cout << n1 / n2 << endl;
else
cout << "Illegal operator!" << endl;
return 0;
}
例:根据用户输入的月份,输出从元旦到该月底的总天数。
#include <iostream.h>
int main()
{
int year,month,days = 0;
cin >> year >> month;
switch(month) {
case 12,days += 31;
case 11,days += 30;
case 10,days += 31;
case 9,days += 30;
case 8,days += 31;
case 7,days += 31;
case 6,days += 30;
case 5,days += 31;
case 4,days += 30;
case 3,days += 31;
case 2:
if(year % 4 == 0 && year % 100 != 0 ||
year % 400 == 0)
days += 29;
else
days += 28;
case 1,days += 31;
}
if(days == 0)
cout << "Wrong month!" << endl;
else
cout << days << endl;
return 0;
}
3.3 循环语句
3.3.1 while 语句
while(expression)
statement;
其中,expression 是一个关系表达式; statement 是 一条 语句,叫做 循环体 。
while 语句的执行过程为:当表达式 expression 的值为真时反复地执行语句 statement。因此,while 循环也常被叫做
“当”型循环。
例:
#include <iostream.h>
#include <conio.h>
int main()
{
char ch = 'a';
while(ch != '.') {
ch = getch();
if(ch == 'z' || ch == 'Z')
putch(ch - 25);
else
putch(ch + 1);
}
return 0;
}
程序中的 getch() 和 putch() 是
C++ 语言中的“标准函数”,
前者是一个输入函数,它要求用户从键盘上键入一个字符,
并返回该字符。但它并不显示键入的字符。后者的功能恰恰相反,它将其参数(括号中表达式的值)所代表的字符显示在屏幕上。
3.3.2 do-while 语句
do {
statement;
} while(expression);
do-while 语句的执行过程为:反复地执行循环体 statement,
直到表达式 expression 的值为假。因此,do-while 循环也常被叫做“直到”型循环。
例:
#include <iostream.h>
#include <conio.h>
int main()
{
char ch;
do {
ch = getch();
if(ch == 'z' || ch == 'Z')
putch(ch - 25);
else
putch(ch + 1);
} while(ch != '.');
return 0;
}
3.3.3 for 语句
3.3.3.1 for 语句的基本形式
for(initialization; condition; increment)
statement;
其中,initialization 叫做 初始化部分,它通常是一个赋值表达式; condition 叫做 循环条件部分,它通常是一个关系表达式;
increment 叫做 增量部分,它通常也是一个赋值表达式。它们共同构成了 for 语句的控制部分。 statement 是 一条 语句,
即循环体。
for 语句的一般执行过程为:在初始化部分为一个变量(叫做循环控制变量或循环变量)赋一个初值;在循环条件部分给定循环的条件;在增量部分给出循环变量的增量方式和增量值。在循环条件为真的前提下反复执行循环体,且每执行一次就按增量部分所给方式修改循环变量的值。直到循环条件被破坏为止。
例:输出大写字母 A~Z 的 ASCII 码值
#include <iostream.h>
int main()
{
for(char ch = 'A'; ch <= 'Z'; ch ++)
cout << ch << "->" << int(ch) << endl;
return 0;
}
例:输出大写字母 A~Z 的 ASCII 码值的另一个版本
#include <iostream.h>
int main()
{
for(int i = 0; i < 26; i ++)
cout << char('A' + i) << "->" << int('A' + i) << endl;
return 0;
}
3.3.3.2 含有逗号表达式的 for 语句
#include <iostream.h>
int main()
{
int i,j;
for(i = 1,j = 1; i <= 10,j < 30; i ++,j ++) {
cout << i * j << " ";
j += 3;
}
cout << endl;
return 0;
}
该程序的输出结果为:
1 10 27 52 85 126 175 232
对于本例,若将循环体中的
j += 3 删去,并将增量部分的
j ++ 改为 j += 4,for 循环的执行过程将更加清晰。
3.3.3.3 for 语句的省略
for 语句控制部分的 3 个组成均允许省略。省略时必须保留各部分的分号,以便编译器识别。
例:
for(; ;) {
//…
}
这是一个将 控制部分的 3 个组成全部省略的例子。应当说明的是,对于这样的 for 循环,循环体中必须存在中断循环的语句,否则它将是一个死循环。
#include <iostream.h>
int main()
{
char ch = 'a';
for(; ch != '.';) {
ch = getch();
if(ch == 'z' || ch == 'Z')
putch(ch - 25);
else
putch(ch + 1);
}
return 0;
}
习题:
1,2,3
2.6.1 赋值表达式含有赋值运算符的表达式叫做赋值表达式。其一般形式为:
variable = expression
可以看出,在赋值表达式中,赋值运算符的左操作数必须是一个变量,而右操作数可以是任一合法的表达式。赋值表达式的值就是其右操作数的值。
由于赋值运算符要求其右操作数为一个表达式,而赋值表达式是一个合法的表达式,所以可以将赋值表达式用做赋值运算符的右操作数,从而构成所谓的“串连”赋值表达式。如:
i = j = 3 * 5
2.6.2 增量减量运算符
++ --
增量和减量运算符都是隐含有赋值操作的运算符,它们将其操作数(必须是 int 或 char 型变量)的值加 1 或减 1。这两个运算符虽然都是一元运算符,但由于操作数即可以放在运算符的左边(后置),又可以放在运算符的右边(前置),
从而使得它们对其他运算产生不同的影响。设 i 是一个 int 型变量,则增量和减量运算符将有以下 4 种使用形式:
++ i // 前置增量
-- i // 前置减量
i ++ // 后置增量
i -- // 后置减量对于单个增减量表达式所构成的语句来说,前置和后置的运算结果是没有什么区别的。而对于还包含有其他运算的表达式来讲,前置和后置的运算结果将会产生不同的效果。
例:
//…
i = 3;
j = i ++; // j 的值为 3,i 的值为 4
k = ++ i; // k 的值为 5,i 的值为 5
注意:由于不同的编译器对增减量运算符处理的不同,所以类似以下的用法将存在移植性问题。
cout << i ++ << '\t' << i ++ << endl;
2.6.3 复合赋值运算符
+= -= *= /= %=
&= |= ^= <<= >>=
复合赋值运算符均是二元运算符,它们的运算过程为:先将运算符左右操作数的值进行运算符所规定的算术或位运算,然后将运算的结果赋给左操作数。
例:
i += 2; // 等效于,i ++; i ++
i *= i + j; // 等效于,t = i + j; i = i * t;
2.6.4 表达式中的类型转换
C++ 语言支持不同数据类型的混合运算。当一个表达式中存在不同类型的数据时,编译器会自动地对数据进行转换,以使所有参加运算的数据之类型趋于相同,从而保证运算的精度。自动转换的一般原则是短数据被转换成长数据。
例:
f = i + j * 0.5
double
double
应当说明的是,类型转换都是临时性的,转换并不改变变量的数据类型,
仅改变变量的值。因此,使用不当有可能导致数据精度的丧失。例如:设
i,j 是 int 型变量,j 的值为 3,则:
i = j * 0.3
后,i 的值为 0。
2.6.5 强制类型转换编译器的自动类型转换可控性较差,有时甚至不能满足程序的需要。比如:设 i 为 int 型变量,其值为 5; f 为 float 型变量。则
f = i / 4 + 20.3
后,f 的值为 21.3 而不是预期的 21.55。
强制类型转换( cast) 是解决这一类问题的有效手段,其一般形式为:
(type)expression 或 type(expression)
例:
f = float(i) / 4 + 20.3 f = i / 4.0 + 20.3
2.7 简单变量的初始化
2.7.1 变量的初始化初始化就是指在说明变量的同时为它指定一个初值,其一般形式为:
<storage> type var_name = expression;
例:
int i = 3,j = 5;
C++ 语言还允许采用以下的形式来初始化变量:
<storage> type var_name(expression);
例:
int i(3),j(5);
2.7.2 const 和 volatile 修饰符关键字 const 和 volatile 是 C++ 语言的两个类型修饰符,他们均可以用来修饰变量,前者还可以修饰函数。
被 const 修饰的变量叫做常量标识符,即该变量虽然具有变量的形式,但其值是不允许修改的。因此,必须对常量标识符进行初始化。
例:
const int i = 5;
//…
i = 3; // 非法操作
volatile 修饰符由于涉及底层操作,且极少使用,这里就不做进一步介绍。
第 3章 程序控制语句
3.1 C++ 语言的语句
3.1.1 C++ 语句的基本形式
C++ 语句的基本形式就是一个表达式后跟一个分号(,;”)。
例:
a = b + c; // 典型语句
i + j; // 合法语句,但无实用价值; // 空语句
C++ 语言中,变量说明也是语句,因此它可以出现在任何语句可以出现的地方。
3.1.2 块语句块语句也叫复合语句,它是用一对花括号括起来的多条语句,
而在语法上却等效于一条语句。
例:
//…
{
int t = a;
a = b;
b = t;
}
3.2 选择语句
3.2.1 if 语句
3.2.1.1 基本的 if 语句
if(expression)
statement;
其中,expression 是一个关系表达式; statement 是 一条 语句。
例:
if(a > 10) if(x < y) {
a -= 5; int t = x;
a += 3;
x = y;
y = t;
}
3.2.1.2 扩展的 if 语句
if(expression)
statement1;
else
statement2;
例:
if(a >= b)
nMax = a;
else
nMax = b;
#include <iostream.h>
int main()
{
int x,y;
cout << "Please input two integers,";
cin >> x >> y;
if(x >= y)
cout << "The max is " << x << endl;
else
cout << "The max is " << y << endl;
return 0;
}
3.2.2 if 语句的嵌套例:输出 3 个数中的最大数。
#include <iostream.h>
int main()
{
int a,b,c;
cin >> a >> b >> c;
cout << "The maximum is ";
if(a >= b)
if(a >= c)
cout << a << endl;
else
cout << c << endl;
else
if(b >= c)
cout << b << endl;
else
cout << c << endl;
return 0;
}
3.2.3 三元条件表达式三元运算符,?:”的一般使用形式为:
expression? expression1,expression2
它等效于如下的 if 语句:
if(expression)
expression1;
else
expression2;
例:
cout << (a >= b? a,b) << endl;
例:输出 3 个数中的最大数的另一版本。
#include <iostream.h>
int main()
{
int a,b,c;
cin >> a >> b >> c;
cout << "The maximum is ";
cout << (a >= b? (a >= c? a,c),(b >= c? b,c)) << endl;
return 0;
}
3.2.4 switch 语句
switch 语句也叫开关语句,其一般形式为:
switch(expression) {
case value1:
statement1;
<break;>
…
case valuen:
statementn;
<break;>
<default:
statementn+1;
<break;>>
}
switch 语句的执行过程为:若某个 case 后边的常量 valuei
的值与表达式 expression 的值相等(匹配),则执行该分支中的语句,直到遇到 break 语句为止。若表达式的值与任何一个常量的值都不相等,则:如果存在 default 分支,则执行该分支中的语句;否则什么都不作。
注意,switch 语句执行过程决定了若某一分支必须执行多条语句,则不必使用块语句。
例:一个简单的计算器程序
#include <iostream.h>
int main()
{
int n1,n2;
char op;
cout << "Enter a simple arithmetic expression,";
cin >> n1 >> op >> n2;
switch(op) {
case '+':
cout << n1 + n2 << endl;
break;
case '-':
cout << n1 - n2 << endl;
break;
case '*':
cout << n1 * n2 << endl;
break;
case '/':
cout << n1 / n2 << endl;
break;
default:
cout << "Illegal operator!" << endl;
}
return 0;
}
例:将上例改为 if 语句
#include <iostream.h>
int main()
{
int n1,n2;
char op;
cout << "Enter a simple arithmetic expression,";
cin >> n1 >> op >> n2;
if(op == '+')
cout << n1 + n2 << endl;
else
if(op == '-')
cout << n1 - n2 << endl;
else
if(op == '*')
cout << n1 * n2 << endl;
else
if(op == '/')
cout << n1 / n2 << endl;
else
cout << "Illegal operator!" << endl;
return 0;
}
例:根据用户输入的月份,输出从元旦到该月底的总天数。
#include <iostream.h>
int main()
{
int year,month,days = 0;
cin >> year >> month;
switch(month) {
case 12,days += 31;
case 11,days += 30;
case 10,days += 31;
case 9,days += 30;
case 8,days += 31;
case 7,days += 31;
case 6,days += 30;
case 5,days += 31;
case 4,days += 30;
case 3,days += 31;
case 2:
if(year % 4 == 0 && year % 100 != 0 ||
year % 400 == 0)
days += 29;
else
days += 28;
case 1,days += 31;
}
if(days == 0)
cout << "Wrong month!" << endl;
else
cout << days << endl;
return 0;
}
3.3 循环语句
3.3.1 while 语句
while(expression)
statement;
其中,expression 是一个关系表达式; statement 是 一条 语句,叫做 循环体 。
while 语句的执行过程为:当表达式 expression 的值为真时反复地执行语句 statement。因此,while 循环也常被叫做
“当”型循环。
例:
#include <iostream.h>
#include <conio.h>
int main()
{
char ch = 'a';
while(ch != '.') {
ch = getch();
if(ch == 'z' || ch == 'Z')
putch(ch - 25);
else
putch(ch + 1);
}
return 0;
}
程序中的 getch() 和 putch() 是
C++ 语言中的“标准函数”,
前者是一个输入函数,它要求用户从键盘上键入一个字符,
并返回该字符。但它并不显示键入的字符。后者的功能恰恰相反,它将其参数(括号中表达式的值)所代表的字符显示在屏幕上。
3.3.2 do-while 语句
do {
statement;
} while(expression);
do-while 语句的执行过程为:反复地执行循环体 statement,
直到表达式 expression 的值为假。因此,do-while 循环也常被叫做“直到”型循环。
例:
#include <iostream.h>
#include <conio.h>
int main()
{
char ch;
do {
ch = getch();
if(ch == 'z' || ch == 'Z')
putch(ch - 25);
else
putch(ch + 1);
} while(ch != '.');
return 0;
}
3.3.3 for 语句
3.3.3.1 for 语句的基本形式
for(initialization; condition; increment)
statement;
其中,initialization 叫做 初始化部分,它通常是一个赋值表达式; condition 叫做 循环条件部分,它通常是一个关系表达式;
increment 叫做 增量部分,它通常也是一个赋值表达式。它们共同构成了 for 语句的控制部分。 statement 是 一条 语句,
即循环体。
for 语句的一般执行过程为:在初始化部分为一个变量(叫做循环控制变量或循环变量)赋一个初值;在循环条件部分给定循环的条件;在增量部分给出循环变量的增量方式和增量值。在循环条件为真的前提下反复执行循环体,且每执行一次就按增量部分所给方式修改循环变量的值。直到循环条件被破坏为止。
例:输出大写字母 A~Z 的 ASCII 码值
#include <iostream.h>
int main()
{
for(char ch = 'A'; ch <= 'Z'; ch ++)
cout << ch << "->" << int(ch) << endl;
return 0;
}
例:输出大写字母 A~Z 的 ASCII 码值的另一个版本
#include <iostream.h>
int main()
{
for(int i = 0; i < 26; i ++)
cout << char('A' + i) << "->" << int('A' + i) << endl;
return 0;
}
3.3.3.2 含有逗号表达式的 for 语句
#include <iostream.h>
int main()
{
int i,j;
for(i = 1,j = 1; i <= 10,j < 30; i ++,j ++) {
cout << i * j << " ";
j += 3;
}
cout << endl;
return 0;
}
该程序的输出结果为:
1 10 27 52 85 126 175 232
对于本例,若将循环体中的
j += 3 删去,并将增量部分的
j ++ 改为 j += 4,for 循环的执行过程将更加清晰。
3.3.3.3 for 语句的省略
for 语句控制部分的 3 个组成均允许省略。省略时必须保留各部分的分号,以便编译器识别。
例:
for(; ;) {
//…
}
这是一个将 控制部分的 3 个组成全部省略的例子。应当说明的是,对于这样的 for 循环,循环体中必须存在中断循环的语句,否则它将是一个死循环。
#include <iostream.h>
int main()
{
char ch = 'a';
for(; ch != '.';) {
ch = getch();
if(ch == 'z' || ch == 'Z')
putch(ch - 25);
else
putch(ch + 1);
}
return 0;
}
习题:
1,2,3