第3章
基本数据类型和表达式




计算机解决各种实际问题的本质是对数据进行处理,程序中对数据处理由对应的程序语句来完成。因此,需要掌握数据在计算机中的表示和存储形式,掌握利用运算符、变量、常量按一定规则组成表达式对数据进行运算。只有掌握了这些基本知识,才能顺利地进行C++语言程序设计。

本章主要介绍C++语言程序设计的基本部分,包括基本数据类型、常量与变量、运算符与表达式、数据类型转换及常用库函数。

3.1数 据 类 型

程序处理的对象是数据,数据分为常量和变量,每个常量或变量都有数据类型。C++语言中的数据类型分为两大类: 基本数据类型和导出数据类型。其中,基本数据类型是C++语言中预定义的类型,包含整型(int)、字符型(char)、布尔型(bool)、单精度浮点型(float)、双精度浮点型(double)和空类型(void); 导出数据类型也称自定义数据类型,是用户根据程序设计需要,按语法规则由基本数据类型构造的,包含数组、指针、结构体、联合体、枚举和类等。表31中列出了C++语言的基本数据类型。


表31C++语言的基本数据类型


类型字节数取 值 范 围


bool(布尔型或逻辑型)1true或false
[signed]char(有符号字符型)1-128~+127
unsigned char(无符号字符型)10~255
[signed]int(有符号整型)4-231~+231-1(-2147483648~+2147483647)
unsigned[int](无符号整型)40~232-1(0~4294967295)
[signed]long[int](有符号长整型)4-231~+231-1(-2147483648~+2147483647)
unsigned long[int](无符号长整型)40~232-1(0~4294967295)
[signed]short[int](有符号短整型)2-215~+215-1(-32768~+32767)
unsigned short[int](无符号短整型)20~216-1(0~65535)
float(单精度浮点型)4-3.4×10-38~+3.4×1038
double(双精度浮点型)8-1.7×10-308~+1.7×10308
long double(长双精度型)8/16-1.7×10-4932~+1.7×104932
void(空值型)



说明: 

(1) 表31中的符号“[]”表示可选,其中的内容为默认,在定义变量时“[]”中的内容可以缺省。例如,signed char等同于char,表示有符号字符型; signed int等同于int,表示有符号整型。

(2) 符号修饰符signed、unsigned与长短修饰符short、long连同类型名int可以随意组合。例如,unsigned long int、long unsigned int、int unsigned long都表示无符号长整型。

(3) 空值型用于描述没有返回值的函数及通用指针类型。

(4) 表31中的字节数和取值范围是基于32位操作系统给出的。在64位操作系统中,long、unsigned long为8字节,其余相同。

(5) 单精度型浮点数(float)的有效数字为7位,双精度型浮点数(double)的有效数字为15位,长双精度型浮点数(long double)的有效数字为15位(占8字节时)或19位(占16字节时)。

(6) 不同的编译系统对long double的处理方法不完全相同,有的分配8字节,有的分配16字节。

【例3.1】输入圆的半径,求圆的面积并输出。



#include<iostream>

using namespace std;

const double PI=3.14159;

int main()

{double r,c,area;  //变量r表示圆的半径,c表示圆的周长,area表示圆的面积

cout<<"输入圆的半径:";        //提示用户输入圆的半径

cin>>r;

c=2*PI*r;

area=PI*r*r;

cout<<"pi="<<PI<<endl;

cout<<"圆的周长:"<<c<<endl;

cout<<"圆的面积:"<<area<<endl;

return 0;

}






例3.1中定义了双精度类型变量r、c和area,运行时根据输入的r值计算area和c。2*PI*r是表达式,表达式中有常量PI和2。常量和变量有什么区别?常量和变量应该如何定义?表达式怎样表示?这些问题将在本章逐一讲解。

3.2常量

常量是指在程序运行过程中值不能被改变的量。常量分为字面常量(直接常量)和符号常量。不加任何说明就可直接使用的常量称为字面常量,例3.1中语句“c=2*PI*r;”中的2是字面常量; 用符号表示的常量称为符号常量,例3.1中的PI为符号常量。

3.2.1字面常量

字面常量按类型分为整型常量、浮点型常量、字符型常量、字符串常量和布尔型常量,其值自动地决定了它的数据类型。例如,32为整型常量中的int类型,32.0为浮点型常量中的double类型。

1. 整型常量

整型常量可以采用十进制、八进制、十六进制的形式表示。

(1) 十进制整数: 由数字0~9组成,是整型常量的默认表示形式,如-15、0、126等。

(2) 八进制整数: 以数字0开头,由数字0~7组成。例如,0126表示八进制整数126,即(126)8,对应十进制数1×82+2×81+6×80=86; -015表示八进制整数-15,即(-15)8,对应十进制数-13。

(3) 十六进制整数: 以0x(或0X)开头,由数字0~9、字母A~F(或a~f)组成。例如,0x126表示十六进制整数126,即(126)16,对应十进制数1×162+2×161+6×160=294; 0XFF表示十六进制整数FF,即(FF)16,对应十进制数255。

对于整型常量,可以使用后缀L或l表示长整型数,使用U或u表示无符号整数。例如,126L、015L、0XFFL表示长整型数,126U、0XFFU表示无符号整数,0XFFUL、126LU表示无符号长整型数。针对没有明确指定为长整型或无符号整型的常量,由编译系统根据值的大小自动识别。例如,取值范围在-231~+231-1(-2147483648~+2147483647)的数识别为int,取值范围在231~232-1(2147483647~4294967295)的数识别为unsigned long int。

2. 浮点型常量

浮点型常量是指含有小数点或包含有10的幂次的实数,也称为浮点数。浮点型常量有以下两种表示形式: 

(1) 十进制小数形式: 由数字0~9和小数点组成。例如,0.123、252.6、.12、-89.都是合法的浮点型常量。

(2) 指数形式: 又称为科学计数法,把浮点型常量用“尾数×10指数”的形式表示,在程序中基数10用字母E(或e)代替,表示为“尾数E(e)指数”。例如,浮点数252.62可表示为0.25262E3、2.5262e2。注意,在字母E(或e)前后必须有数字,且E(或e)之后的指数部分必须是整数。例如,12.3E、E5、1.3e1.2都不是合法的浮点数。

需要说明的是,浮点型常量在C++语言编译系统中默认按双精度浮点型(double)处理。只有在实数后面加上F(或f)才表示float型; 在实数后面加上L(或l)表示long double型。例如: 



3.14159//double型(默认)

3.14159f   //float型(以f结尾)

3.14159L  //long double型

1.23E5	  //double型(默认)

1.23E5f	  //float型(以f结尾)

1.23E5L	  //long double型







3. 字符型常量

用英文单引号括起来的单个字符称为字符型常量,如' a'、' A'、' 0'、' %'都是合法的字符型常量。字符型常量在计算机内存储时占用1字节,实际在存储单元中以二进制的形式存放,存储的是该字符的ASCII码值。例如,字符' a'、' A'、' 0'被存储在存储单元中的内容为0110 0001、0100 0001、0011 0000,对应的ASCII码值分别为97、65与48。

ASCII码表中的大小写英文字母、数字等字符可直接用单引号括起来表示成字符型常量,但其中的32个控制字符(如回车、退格、换行等)、单引号、双引号、反斜杠(\)等无法用上述方法表示,这些字符需要使用C++语言提供的“转义字符”形式来表示。

转义字符以转义符(\)开头,有以下几种情况: 

(1) 所有的ASCII码字符都可以用“\”加一个整型常量来表示,该整型常量必须是一个不超过3位的八进制或不超过2位的十六进制整数,取值范围为0~255。例如,' \062'、' \141'、' \x62'、' \X41'都是合法的字符型常量,分别表示字符常量' 2'、' a'、' b'、' A'。虽然这种形式的转义序列可表示任意一个字符型常量,但其可读性差。

(2) 常见的但不能显示的ASCII字符采用特定字母前加“\”的形式表示,如\v、\t、\n等。注意,此时“\”后面的字符均不是它本来的ASCII字符的意思。

(3) 某些具有特殊含义的字符用转义字符表示。例如,单引号(')是字符常量定界符,表示单引号时需用转义字符'\''。此外,双引号用'\"'表示,“\”字符用'\\'表示。

表32列出了C++语言中预定义的常用转义字符及其含义。


表32C++语言中预定义的常用转义字符及其含义


转义字符含义ASCII码值(十进制)


\a响铃(alert)7
\b退格(backspace),将当前位置移到前一列8
\f走纸(feed)换页,将当前位置移到下页开头12
\n换行(newline),将当前位置移到下一行开头10
\r回车(return),将当前位置移到本行开头13
\t水平制表符(HT)(跳到下一个Tab位置)9
\v垂直制表符(VT)11
\\代表一个反斜线字符''\'92
\'代表一个单引号(')字符39
\"代表一个双引号(")字符34
\0空字符(NULL)0
\dddASCII码值为八进制ddd的字符ddd(八进制)
\xhhASCII码值为十六进制hh的字符hh(十六进制)



【例3.2】转义字符的应用。



#include<iostream>

using namespace std;

int main()

{cout<<'A'<<'\t'<<'B'<<'\n';

cout<<'\101'<<'\011'<<'\102'<<'\12';	

cout<<'\x41'<<'\x9'<<'\x42'<<'\xA';

cout<<'C'<<':'<<'\\'<<endl;

return 0;

}







程序运行结果如下: 



AB

A       B

A       B

C:\






通过例3.2可以发现,前3行的输出效果相同。当输出字符A时,可以使用' A'、' \101'、' \x41',显然用'A'可读性好。另外,在输出语句中,经常用' \t'和' \n'等转义字符来调整输出格式。其中,' \t'将当前光标移到下一个输出区(一个输出区占8列字符宽度);' \n'相当于按Enter键,表示将当前光标移动到下一行行首。要输出“\”,则应该在语句中用转义字符' \\'。

4.  字符串常量

用英文双引号(" ")括起来的字符序列称为字符串常量。在存储字符串常量时,编译系统会自动在字符串末尾添加'\0'作为结束标记。编写程序时,通常用这一特性来判断字符串是否结束。

以下给出的都是合法的字符串: 



"China"	//字符串长度5,占6字节

"a"			  //字符串长度1,占2字节,注意与字符常量'a'的区别

""			  //空串,长度0,占1字节

"你好" 		  //中文字符串,长度4,占5字节(一个汉字占2字节)

"a+b="		  //字符串长度4,占5字节

"I\'m a student.\n"  //字符串长度15,占16字节







其中,字符串"China"在存储空间的二进制表示形式如图31所示。




图31字符串"China"在存储空间的二进制表示形式



【例3.3】字符串常量测试示例。



#include<iostream>

using namespace std;

int main()

{ cout<<"I\'m a student."<<endl;

 cout<<"字符串长度:"<<strlen("I\'m a student.\n")<<endl;

 cout<<"字符串所占字节数:"<<sizeof("I\'m a student.\n")<<endl;

 return 0;

}







程序运行结果如下: 



I'm a student.

字符串长度:15

字符串所占字节数:16







说明: 

(1) 字符用单引号作定界符,而字符串用双引号作定界符。

(2) 字符常量只能表示单个字符,而字符串常量中包含零个(空串)或多个字符。

(3) 字符占1字节的存储空间,而字符串占的字节数等于字符串的长度加1。

(4) 例3.3中的sizeof运算符用于求参数所占的字节数,strlen()函数用于求字符串的长度,具体用法见后续章节。

5. 布尔型常量

布尔型的值只有两个: true和false,分别对应逻辑值“真”和“假”。在C++语言中,布尔型数据可以参与执行算术运算、逻辑运算和关系运算。在算术运算中,把布尔型数据当作整型数据,true和false分别当作1和0; 在逻辑运算中,把非0当作true,把0当作false; 在关系运算中,成立的关系值表示为true,不成立的关系值表示为false。

3.2.2符号常量

用标识符表示的常量称为符号常量或标识符常量。在C++语言中,有两种方法定义符号常量。

(1) 使用编译预处理指令,格式如下: 

#define 符号常量名 数值

(2) 使用常量说明符const,格式如下: 

const 数据类型 符号常量名=值; 


例如: 



#define PI 3.14159

const double PI=3.14159;






两种方法的区别如下:  用#define定义的符号常量是用一个符号代替一个指定值,在预编译时会把所有符号常量替换为所指定的值(把程序中出现的PI替换为3.14159)。其没有类型,在内存中不存在以符号常量命名的存储单元。而用const定义的符号常量有数据类型,内存中存在以它命名的存储单元。

在程序中,通常将频繁使用的常量或具有特殊意义的数值(如上例中的PI)定义成符号常量,这是一种良好的程序设计习惯。与字面常量相比,使用符号常量增强了程序的可读性,能做到“见名知意”。另外,若要调整程序中某个频繁出现的常量的值,对于字面常量来说要修改多处,很容易遗漏或出错; 而对于符号常量来说,只需在定义处进行修改即可。

3.3变量

变量是指在程序执行过程中值可以被改变的量。变量有3个基本要素: 变量名、类型和值。从计算机系统实现角度来看,变量是用来存储数据的内存区域,变量名是该区域的名称或标识符,区域的大小由编译系统根据变量定义时的数据类型决定,值是存储在该区域的具体内容。

3.3.1标识符和关键字

在C++语言中,用来标识变量名、符号常量名、函数名、自定义类型名、类名等名称的有效字符序列称为标识符。简单地说,标识符就是某一实体的名字。C++语言中标识符的构成规则如下: 

(1) 以字母或下画线“_”开头。

(2) 由字母、数字、下画线“_”组成,不得使用其他字符。

(3) 区分字母大小写,如sum、Sum、SUM是3个不同的标识符。

(4) 不能使用关键字,C++语言中的关键字详见表33。


表33C++语言中的关键字



asmconst_castexplicitinlinepublicstructtypename

autocontinueexportintregisterswitchunion
booldefaultexternlongreinterpret_casttemplateunsigned
breakdeletefalsemutablereturnthisusing
casedofloatnamespaceshortthrowvirtual
catchdoublefornewsignedtruevoid
chardynamic_castfriendoperatorsizeoftryvolatile
classelsegotoprivatestatictypedefwchar_t
constenumifprotectedstatic_casttypeidwhile



关键字是预定义的具有特殊用途的一些名词,也称保留字,表示为C++语言保留,不能用作标识符。例如,与数据类型有关的关键字有bool、char、int、long、unsigned、float和double等,与程序流程控制有关的关键字有if、else、switch、case、default、while、do、for、break、continue和return等,与动态内存管理有关的关键字有new和delete,与类和对象有关的关键字有class、private、protected、public和this等。表33中的常用关键字及其用法将在后续章节中介绍。

结合上述规则,可知下面列出的是合法标识符: 



Sumarea_nameMax_Value1







而下面列出的均为不合法标识符: 



6ab//不能以数字开头

Sum#  //不能使用除大小写字母、数字、下画线以外的字符"#"

this	  //不能使用关键字	






C++语言没有规定标识符的长度(字符个数),但各个具体的编译系统都有自己的规定。例如,Visual C++2010规定标识符最长为2048个字符。在符合构成规则的前提下,标识符尽量采用简单且有含义的名字(如student、area、flag、count、num等),做到“见名知意”,提高程序可读性。

3.3.2变量的定义

变量遵循“先定义后使用”的原则。定义变量的语句格式如下: 

类型名 变量名1, 变量名2, 变量名3, …, 变量名n; 


其中,类型名是变量的数据类型,它可以是C++语言中预定义的数据类型,也可以是用户自定义的数据类型; 变量名的命名需遵循标识符的构造规则。

可以同时定义n个相同类型的变量。例如: 



int num1,num2;//定义了2个int型变量

float x,y,z;		  //定义了3个float型变量

double area;		  //定义了1个double型变量






在C++语言中,同一变量不能重复定义。变量定义语句可以出现在程序中语句可出现的任何位置,只要在第一次使用该变量之前进行定义即可。但是,从程序可读性方面考虑,通常将变量定义语句放在函数体或程序块(复合语句)的开始处。

3.3.3变量赋初值

变量首次使用时必须有明确的值,该值称为变量的初值。初值可以是常量,也可以是一个有确定值的表达式。如果未对变量赋初值,则该变量的初值是一个随机值,即该存储单元中的内容是不可知的。可用以下两种方法给变量赋初值。

1. 在定义变量的同时初始化

格式如下: 

类型名 变量名=初值; 

类型名 变量名(初值); 


例如: 



int a=1,b=2,c=3;//定义整型变量a, b, c,并分别将其初始化为1, 2, 3

char c1='A',c2='a';         //定义字符型变量c1, c2,并分别将其初始化为'A','a'

double x,y=12.6;           //定义双精度型变量x, y,并只将y初始化为12.6







上述语句的等价形式如下: 



int a(1),b(2),c(3);

char c1('A'),c2('a');

double x,y(12.6);







2. 变量定义后使用赋值语句赋初值

例如: 



double r,area;

r=3.6;	//给变量r赋初值3.6

area=3.14159*r*r;	       //使用有确定值的表达式给变量area赋初值







3.3.4变量的使用

变量定义后就可以多次使用。取一个变量的值,称为对变量的引用。对变量的赋值与引用统称为对变量的操作或使用。

3.4运算符与表达式

运算符是用于描述对数据的操作、体现数据之间运算关系的符号,参与运算的数据称为操作数。根据运算符所需操作数的个数,可以把运算符分为单目运算符、双目运算符和三目运算符; 根据运算符的功能,可以把运算符分为算术运算符、关系运算符、逻辑运算符、位运算符等。

表达式是由运算符、圆括号和操作数构成的合法式子,经过运算会得到某种类型的确定值,其操作数可以是常量、变量或函数等。使用不同的运算符可以构成不同类型的表达式,如算术表达式、赋值表达式、关系表达式和逻辑表达式等。

C++语言提供了十分丰富的运算符,当在一个表达式中出现多种运算符时,其运算顺序需要考虑运算符的优先级和结合性。表34列出了常用运算符的优先级和同级别运算符的运算顺序,详见附录B。表34中优先级别的数字越小,表示优先级越高。


表34常用运算符及其优先级和结合性


优先级运算符含义操作数个数结合性

1
()圆括号或函数调用
. 、->成员访问符
[]下标运算符
::作用域运算符
. *、-> *成员指针运算符
&引用自左向右
2
*取变量运算符
&取指针运算符
new申请动态内存
delete释放动态内存
!逻辑非运算符
~按位取反运算符
++自增运算符
--自减运算符
+、-正、负号运算符
sizeof求占用内存字节长度1自右向左


3*、/、%乘、除、取余(模运算符)2
4+、-加、减2
5<<、>>左移位、右移位2
6<、<=、>、>=小于、小于或等于、大于、大于或等于2
7==、!=等于、不等于2
8&按位与运算符2
9^按位异或运算符2
10|按位或运算符2
11&&逻辑与运算符2
12||逻辑或运算符2
13?  : 条件运算符3自左向右

14=、+=、-=、*=、
/=、%=、<<=、>>=、
&=、^=、|=赋值运算符、复合赋值运算符2自右向左
15,逗号运算符自左向右



1. 优先级

运算符的优先级确定了运算的优先次序,当一个表达式中包含多个运算符时,先执行优先级高的,再执行优先级低的。例如,在表达式a*b+c中,运算符“*”的优先级高于“+”,则先进行a*b运算,再将其结果加上c。

2.  结合性

如果表达式中同时出现了优先级相同的运算符,则其运算顺序由运算符的结合性决定。运算符的结合性分为左结合和右结合。

(1) 左结合: 在优先级相同的情况下,左边的运算符优先与操作数结合起来进行运算,即按从左到右的顺序计算。例如,表达式a*b%c,先乘后取模。

(2) 右结合: 在运算符优先级相同的情况下,右边的运算符优先与操作数结合起来进行运算,即按从右到左的顺序计算。例如,表达式a=b*=c,先执行b*=c,再执行a=b。

值得注意的是,C++语言的运算符很多,其优先级和结合性较复杂,在书写比较复杂的表达式而又对运算次序把握不准时,可通过适当增加圆括号来明确指定表达式的求值顺序。

本章主要介绍算术运算符、关系运算符、逻辑运算符、自增与自减运算符、赋值与复合赋值运算符、sizeof运算符、逗号运算符,其他运算符将在以后各章中陆续介绍。

3.4.1算术运算符与算术表达式

1. 算术运算符

算术运算符主要用于数值型数据的算术运算。C++语言中的算术运算符共有7个,如表35所示。


表35算术运算符


优先次序算术运算符含义
示例(a=7,b=2)
表达式值



1

+正值运算符,用于取正+a7
-负值运算符,用于取负-a-7

2

*乘法运算符a*b14
/除法运算符a/b3
%取余运算符、模运算符a%b1

3

+加法运算符a+b9
-减法运算符a-b5


说明: 

(1) 算术运算符中,+(正值运算符)、-(负值运算符)属于单目运算符,其余均为双目运算符。取正操作的结果与操作数相同,所以正值运算符很少使用; 取负操作是取操作数的相反值。


(2) %(取余运算符)用于求两个操作数作除法运算的余数,要求两个操作数均为整型数据,所得余数的符号与左操作数的符号相同。例如: 



7%2	//结果为1

-7%2	  //结果为-1

7% -2	  //结果为1

7.5 %2	  //错误,无法正确运行






(3) /(除法运算符)用于求两个操作数的商。如果两个操作数均为整型,则作整除运算(去尾取整); 当操作数中至少有一个是浮点型数据时,则作数学中的除法运算。例如: 



7/2//结果为3

7.0/2	  //结果为3.5(double型)

7/2.0	  //结果为3.5(double型)

7.0f/2	  //结果为3.5(float型 )







(4) 在使用算术运算符时,需要注意运算结果的溢出(超出了对应类型的数据表示范围)问题。在除法运算时,若除数为0或运算的结果溢出,则系统认为产生了一个严重错误,将终止程序的执行; 两个整数作加法、减法或乘法运算时,产生结果溢岀时并不认为是一个错误,但这时的计算结果已不正确,编程时要格外注意。例如: 



#include<iostream>

using namespace std;

int main()

{ int n=60000;

 cout<<n*n<<endl;

 short int a=32767,i=1;  //short int 数据取值范围为-32768~+32767

 a=a+i;

 cout<<a<<endl;

 return 0;

}







程序运行结果如下: 



-694967296

-32768






以上程序的运行结果显然是错误的,因为n*n的值超出了int型的数值范围,a+1超出了short int型的数值范围,产生高位溢出。此类问题可以通过改变变量的数据类型来解决。例如,将语句“int n=60000;”改为“unsigned int n=60000;”、将语句“short int a=32767,i=1;”改为“int a=32767,i=1;”便可得到正确结果。

2. 算术表达式

算术表达式是由算术运算符、圆括号和操作数构成的符合C++语言语法规则的式子。书写算法表达式时应注意: 

(1) 所有运算要用指定的运算符表示,不能省略运算符。例如,数学中可以用ab表示a乘以b,但在C++语言中不可以省略运算符“*”。例如,描述数学式ab2时,对应的算术表达式为a*b/2。必要时,可添加圆括号来描述正确的运算次序。例如,描述数学式xy2(c+d)时,如果只添加运算符,则对应的表达式为x*y/2*(c+d),这显然是错误的。此时需要添加圆括号来维持原有数学式的含义,其正确的表达式为x*y/(2*(c+d))。

(2) 数学式中特殊含义的值(如圆周率π)需要写成具体的数值。例如,描述数学式2πr时,可以用字面常量3.14表示π,写成2*3.14*r。在程序中,也可以先定义符号常量再使用,例3.1中的语句“const double PI=3.14159;”定义了符号常量PI,求圆面积时可将表达式写为“PI*r*r”。

(3) 表达式求值时,表达式中的每个变量都应有确定的值。

3.4.2关系运算符与关系表达式

1. 关系运算符

关系运算符用于比较两个操作数之间的关系是否成立,比较后返回的结果为bool型值,当给定关系成立时返回true,不成立时返回false。

需要特别注意的是,编译系统处理布尔型数据时,将true存储为1,false存储为0。布尔型变量占1字节,存储的内容是1或0。

C++语言中有6个关系运算符,如表36所示。 


表36关系运算符


优先次序关系运算符含义
示例(a=7,b=2)
表达式值(bool型)

1
<小于a<bfalse
<=小于或等于a<=bfalse
>大于a>btrue
>=大于或等于a>=btrue
2

==等于a==bfalse
!=不等于a!=btrue



说明: 

(1) 关系运算符都是双目(二元)运算符。关系运算符的优先级低于算术运算符。例如,在表达式a+b>c+d中,算术运算符“+”的优先级高于关系运算符“>”,所以先计算a+b和c+d的值,再进行比较,等价于表达式(a+b)>(c+d)。

(2) 关系运算符可以连续使用,但此时的运算结果与想要表达的含义有可能截然不同,需引起注意。例如,当a=5、b=4、c=3时,关系表达式a>b>c的返回值为false,因为运算符“>”的结合方向为从左到右,原表达式等价于(a>b)>c。其先计算a>b,返回值为true(实际存储单元中的内容是1); 再比较1>3,关系不成立,返回false(实际存储单元中的内容是0)。

(3) 描述相等关系时用“==”,不要误写成赋值运算符“=”。

2. 关系表达式

用关系运算符将操作数连接起来的式子称为关系表达式,其中操作数可以是变量、常量、算术表达式、函数等。

【例3.4】测试关系表达式的值。



#include <iostream>

using namespace std;

int main()

{int a=98,b=66,c=5;

cout<<"测试关系表达式的值:";

cout<<(a>b+c)<<'\t';//①计算b+c,得71; ②a>71关系成立,返回true,输出1

cout<<(a>b+4!=c)<<'\t';   //①计算b+4,得70; ②a>70关系成立,结果为1; ③1!=c成立,

//输出1

cout<<('a'==a)<<'\t'; //字符常量'a'的ASCII码为97,与变量a不相等,关系不成立,输出0







cout<<(a<b<c)<<endl;  //①a<b关系不成立,结果为0; ②0<c关系成立,输出1

return 0;

}






程序运行结果如下: 



测试关系表达式的值:1101







3.4.3逻辑运算符与逻辑表达式

1. 逻辑运算符

关系表达式只能表示单一条件,但在实际编程中经常需要判断多个关系组合以后的成立情况,此时需要使用逻辑运算符来实现逻辑运算,完成逻辑判断。例如,要判断一个变量是否在给定区间,如判断x∈(a,b),在C++语言中不能写成a<x<b,正确的表达式为x>a && x>b,这里用逻辑与运算符描述两个关系同时成立。

C++语言中有3种逻辑运算符,即“!”(逻辑非)、“&&”(逻辑与)、“||”(逻辑或)。其中,逻辑非是单目运算符,逻辑与、逻辑或是双目运算符。逻辑运算符与算术运算符、关系运算符的优先级由高到低的顺序如下: 

逻辑非(!)→算术运算符→关系运算符→逻辑与(&&)→逻辑或(||)


给定布尔值a、b,逻辑运算符真值表如表37所示。


表37逻辑运算真值表


ab!aa&&ba||b


falsefalsetruefalsefalse
falsetruetruefalsetrue
truefalsefalsefalsetrue
truetruefalsetruetrue



说明: 

(1) 在C++语言中,原则上逻辑运算符的操作数是布尔型的值,一般以关系运算的结果作为操作数,返回结果为true或false。但事实上,C++语言允许逻辑运算的操作数是其他类型,这种情况下,C++语言进行自动类型转换,将非0值转换为true,0转换为false。设x=5、y=6、z=-2,则表达式x<y && z的返回值为true。因为x<y成立,返回true; z作为逻辑运算的操作数,是非0值,转换为true; true && true结果为true。

(2) 逻辑与(&&)、逻辑或(||)可以进行短路求值。这两个运算符具有自左向右的结合性,如果根据运算符左边的计算结果能得到整个表达式的结果,那么运算符右边的表达式就不需要进行计算了,这个规则就是短路求值。根据真值表(表37)不难发现,无论右操作数取何值,false &&(?)的结果一定是false,而true||(?)的结果一定是true,这种情况下不再对右操作数进行计算。也就是说,当逻辑与(&&)的左操作数为true,逻辑或(||)的左操作数为false时,表达式的最终结果由右操作数的值决定,这种情况下才需要计算右操作数的值。

2. 逻辑表达式

用逻辑运算符连接起来的式子称为逻辑表达式。编程时,需要逆转操作数的逻辑状态时用逻辑非(!),即!true为false、!false为true; 判断两个条件是否同时成立时用逻辑与(&&); 需要至少有一个条件成立时用逻辑或(||)。

【例3.5】写出判断字符变量ch是否为字母的表达式。

分析: 字母包含小写字母' a' ~' z'及大写字母' A' ~' Z',判断表达式为: 



ch>=' a' &&ch=<' z'||ch=>' A' &&ch<=' Z'







【例3.6】写出判断某一年是否是闰年的表达式。闰年是指年份值能被4整除,但不能被100整除; 或者能被400整除。年份用整型变量year表示。

分析: 判断变量能否被一个数整除,可以用取余运算符(%),如果余数为0则表示能被整除,否则表示不能被整除。条件中能被4整除可用year%4==0表示,不能被100整除可用year%100!=0表示; 能被400整除可用year%400==0表示。

综上,判断闰年的逻辑表达式如下: 



(year%4==0 && year %100 !=0) || year%400==0







3.4.4赋值运算符与复合赋值运算符

1. 赋值运算符与赋值表达式

赋值运算符“=”的作用是将一个数据赋给一个变量。赋值表达式是由赋值运算符将一个变量和一个表达式连接起来的合法式子,其格式如下: 

变量=表达式


其功能是将右边表达式的值存放到左边变量对应的内存单元中。注意,赋值运算符的左操作数只能是变量。

一个表达式应该有一个值,赋值表达式也是表达式,一样有值,它的值即为左边变量的值。例如,a=6,表示将6赋给变量a,即变量a对应内存单元的值为6,表达式的值也为6; 赋值表达式“a =6*5”的值为30,执行表达式后,变量a的值是30。

赋值运算符的优先级低于算术运算符、关系运算符和逻辑运算符。多个赋值运算符同时出现时,计算顺序是自右向左。

例如,设a、b、c均为整型变量,c的初值为5,有赋值表达式a=b=c+3,其执行过程如图32所示。



图32赋值运算执行过程


2. 复合赋值运算符

在C++语言中,凡是二元(双目)运算符都可以与赋值运算符一起组合成复合赋值运算符。复合赋值运算符共有10个: +=、-=、*=、/=、%=、<<=、>>=、&=、^=、|=。

复合赋值运算符的优先级和结合性与赋值运算符相同。复合赋值运算符的使用格式如下: 

变量 @= 表达式


等价于: 

变量=变量 @ (表达式)


其中,@代表复合赋值运算符中的算术或位运算符。

例如: 





a+=5//等同于a=a+5

a*=b+5	  //等同于a=a*(b+5)

a/=b-c*2	    //等同于a=a/(b-c*2)

a%=b	  //等同于a=a%b







【例3.7】设整型变量a的初值为10,执行表达式a+=a-=a*a后,求变量a的值。

分析: 赋值运算符具有右结合性,运算顺序自右向左,表达式等同于

a=a+(a-=a*a)


其按以下顺序执行: 

(1) a-=a*a: 等同于a=a-a*a,即a=10-10*10,运算后a=-90,表达式a-=a*a的值也为-90。

(2) a=a+(a-=a*a): 变量a的值加赋值表达式“a-=a*a”的值,即a=-90+(-90)=-180,运算后变量a=-180。

含有复合赋值运算符的表达式也属于赋值表达式。使用复合赋值运算符可简化表达式的书写,提高编译效率,生成的目标代码也较少。

3.4.5自增运算符与自减运算符

除了复合赋值运算符之外,C++语言还提供了两个使用方便且效率高的运算符: 自增(++)和自减(--)运算符,作用分别是使变量的值增1或减1,它们都是单目运算符。自增(++)和自减(--)运算符使用时有前置和后置两种形式,前置是指将运算符置于变量之前,后置是指将运算符置于变量之后。例如: 





++i;//前置,先执行i=i+1,再使用i的值

i++;	  //后置,先使用i的值,再执行i=i+1

--i;	  //前置,先执行i=i-1,再使用i的值

i--;	  //后置,先使用i的值,再执行i=i-1







说明: 

(1) 当仅需将一个变量值增1或减1,而不参与其他运算时(不与其他运算符同时出现在一个表达式中时),自增(++)和自减(--)运算符前置和后置的作用相同。例如: 





int i=6,x,y;++i;x=y=i;//++前置,运行后结果:i=7,y=7,x=7

int i=6,x,y;i++;x=y=i;	  //++后置,运行后结果:i=7,y=7,x=7






(2) 当自增(++)或自减(--)运算符与其他运算符出现在同一表达式中时,前置和后置的作用不同。

① ++(或--)前置时,表示先将对应变量的值增1(或减1),再使用该变量的值参与表达式的运算。

② ++(或--)后置时,表示先使用该变量的值参与表达式的运算,再将对应变量的值增1(或减1)。

例如,有语句“int i=6,x,y;”,执行下列语句后的结果是不同的。



y=++i;x=y;//"y=++i;"等同于"i=i+1;y=i;",运行后结果:i=7,y=7,x=7

y=i++;x=y;       //"y=i++;"等同于"y=i;i=i+1;",运行后结果:y=6,i=7,x=6







(3) 自增(++)和自减(--)运算符内包含赋值运算,所以其只能用于变量,不可用于常数或表达式。例如,2++、(x+y)--是非法的。

【例3.8】有语句“int i,x=5,y=6;”,下列表达式执行后,变量的值分别是多少?

(1) i=++x==6||++y==7;  

分析: 按优先级关系,该表达式等同于i=((++x==6)||(++y==7)),逻辑或(||)具有短路求值功能,当逻辑或(||)运算符左侧表达式的值为true时,右侧表达式不再执行。

① 逻辑或(||)运算符左侧表达式可以分解为x=x+1,x==6,x值为6,表达式成立,左侧表达式值为true。

② 因为逻辑或(||)左侧表达式为true,所以右侧表达式++y==7未执行,y的值不变,仍为6。

③ 执行逻辑或(||)运算,返回true。

④ 执行赋值运算,i的值为1。其具体执行步骤如图33所示。


因此,上述语句执行后,i=1,x=6,y=6。

例3.8程序执行中,借助变量变化示意图(图34)来分析各变量当前的值。列举出各个变量,根据程序的执行流实时更新各变量的值。




图33表达式(1)的执行步骤




图34表达式(1)变量变化示意图



(2) i=x++==5 && ++y==6; 

分析: 按优先级关系,该表达式等同于i=((x++==5)&&(++y==6)),逻辑与(&&)具有短路求值功能,仅当逻辑与(&&)运算符左侧表达式的值为true时,才执行右侧表达式。

① 逻辑与(&&)运算符左侧表达式可以分解为x==5,x=x+1,左侧表达式值为true,x=6。

② 逻辑与(&&)运算符左侧表达式为true,继续执行右侧表达式。因为++前置,变量先增1,再运算,所以其可分解为y=y+1,y==6,执行后y=7,右侧表达式的值为false。

③ 执行逻辑与(&&)运算,返回false。

④ 执行赋值运算,i的值为0。其具体执行步骤如图35所示。

因此,上述语句执行后,i=0,x=6,y=7,其变量变化如图36所示。




图35表达式(2)的执行步骤




图36表达式(2)变量变化示意图



3.4.6逗号运算符与逗号表达式

在C++语言中,逗号可以作为分隔符,用于在定义语句中将若干变量隔开或调用函数时将若干个参数隔开,如“int i,j,k;”、pow(x,y); 逗号也可以作为运算符,称为逗号运算符或顺序求值运算符。逗号运算符的优先级最低,具有自左向右的结合性。用逗号将若干个表达式连接起来构成逗号表达式,其格式如下: 

表达式1, 表达式2, …, 表达式n


程序执行时,按从左到右的顺序依次求出各表达式的值,并把最后一个表达式(表达式n)的值作为整个逗号表达式的值。例如,有定义语句“int a=2,b,c;”,则逗号表达式a+=2,b=3+a,c=a*b的计算顺序如下: 先计算a+=2,a的值为4; 再计算3+a,将其值5赋给b; 最后计算a*b,将其值20赋给c。整个逗号表达式的值也为20。

3.4.7sizeof运算符

在C++语言中,sizeof运算符是单目运算符,用于计算操作数的数据类型所占的字节数。操作数可以是数据类型名、变量、常量、表达式。其格式如下: 

sizeof (类型说明符|变量名|常量|表达式)


其中,类型说明符可以是预定义的基本数据类型,也可以是用户删除自定义的数据类型。

例如: 



sizeof( int)//值为4

sizeof( float)		      //值为4

sizeof('\100')		      //字符型常量,占1字节,值为1

sizeof('A' +3.5)		  //值为8,因表达式'A'+3.5的结果类型为double

sizeof( "Hello" )	      //值为6,因字符串"Hello"占6字节

sizeof( 3.0)			  //值为8,因3.0是一个double型常量

short int x; sizeof(x)	  //值为2







3.4.8条件运算符

条件运算符也称为三目(三元)运算符,是C++语言中唯一要求有3个操作数的运算符。条件运算符能够实现简单的选择功能。条件运算符的使用格式如下: 

表达式1?表达式2: 表达式3


其中,表达式可以是任意的符合C++语言语法规则的表达式。

条件运算符的运算规则如下: 

(1) 计算表达式1。

(2) 如果表达式1的值为true(非0),则求出表达式2的值(不求表达式3的值),并把该值作为整个条件表达式的值。

(3) 如果表达式1的值为false(0),则求出表达式3的值(不求表达式2的值),并把该值作为整个条件表达式的值。

例如,有条件表达式如下: 



min=a<b?a:b;  //求两个数中较小的数,并赋值给min

ch=ch>='A' && ch<='Z'?ch+32:ch;    //若ch是大写字母,则将其转换成小写字母;否则不变







条件运算符的优先级较低,仅高于赋值运算符、复合赋值运算符和逗号运算符,具有自右向左的结合性。

3.5数据类型转换

C++语言支持不同类型数据之间的混合运算。运算时,先进行数据类型转换,转换成相同的数据类型,再进行运算。数据类型的转换有两种方式: 自动类型转换和强制类型转换。

3.5.1自动类型转换

自动类型转换又称隐式类型转换,由编译系统按类型转换规则自动完成。对于非赋值与赋值表达式来说,自动类型转换规则是不同的。

1. 非赋值表达式的类型转换

一般情况下,当算术运算符、关系运算符、逻辑运算符和位运算符两个操作数的数据类型不一致时,将根据数据类型由低到高的顺序进行转换。其顺序如图37所示。



图37转换顺序


其转换规则如下:

(1) 当操作数为布尔型(bool)、字符型(char)或短整型(short)时,系统自动转换成整型数(int)参与运算。例如,有语句: 



short s1=1,s2=2;

char ch1='a',ch2='b';







表达式s1+s2的值为3,类型为int; 表达式ch1+ch2的值为195,类型为int。

(2) 当两个操作数的类型不同时,则级别低的类型转换为级别高的类型,运算结果(表达式的值)的类型是表达式的最终类型。例如,表达式5+'a'+6.5-3.65*'b'的运算结果为double型。

(3) 对于整型数据,有符号类型和无符号类型数据进行混合运算,结果为无符号类型。例如,int类型数据和unsigned类型数据的运算结果为unsigned类型,unsigned int类型数据和long类型数据的运算结果为unsigned long类型。例如,有语句: 



int i1=-6;

unsigned int i2=65535;

long i3=5;

unsigned long int i4=4;

float f=6;







则表达式i1+i2的类型为unsigned int,i2+i3的类型为unsigned long int,i4+f的类型为float型。

2. 赋值表达式的类型转换

在赋值表达式中,当赋值号两边的数据类型不同但类型兼容时,则将赋值号右边量的类型转换为左边变量的类型。

其转换规则如下: 

(1) 将浮点型数据赋值给整型变量时,仅取其整数部分赋给整型变量; 若整数部分的值超过整型变量的取值范围,则赋值的结果错误。例如: 



double a=65536.7;

int b=a;//赋值后变量b的值为65536

short c=a;	        //赋值后变量c的值为0,赋值结果错误







(2) 将整型数据赋给浮点型变量时,将整型数据转换成浮点型数据后,再赋值。

(3) 将double型数据赋给float型变量时,要注意数值范围,溢出时赋值出错。

(4) 将少字节整型数据赋值给多字节整型变量时,采用符号位扩展的方式,即低字节部分一一对应,高字节部分按少字节数据的符号位进行扩展。图38给出了2字节整型数据向4字节扩展的示例。



图38符号位扩展示例


例如: 



short a=-1;

int b=a; //赋值后b的值为-1







(5) 将多字节数据赋值给少字节变量时,则将多字节的低位部分一一赋值,高位字节部分舍去。例如: 



int a1=65536;  //变量a1在内存中为0000 0000  0000 0001  0000 0000  0000 0000

short b1=a1;  //取变量a1的低2字节赋值给变量b1,值为0

int a2=65535;  //变量a2在内存中为0000 0000  0000 0000  1111 1111  1111 1111

short b2=a2; //取变量a2的低2字节赋值给变量b2,值为-1(-1的补码为1111 1111 1111 1111)







图39所示为4字节整型数据赋值给2字节变量。



图394字节整型数据赋值给2字节变量



例如: 



int a=256;//变量a在内存中为0000 0000  0000 0000  0000 0001  0000 0000

char ch=a;	  //取变量a的低1字节赋值给变量ch,值为0

short a1=353; 	        //变量a1在内存中为  0000 0001  0110 0001

char ch1=a;	  //取变量a1的低1字节赋值给变量ch1,值为97,即字符'a'







图310所示为4字节整型数据赋值给char型变量。



图3104字节整型数据赋值给char型变量



(6) 将无符号字符型数据赋给整型变量时,字符型数据放在整型变量的低位字节,高位字节补0; 但将有符号字符型数据赋给整型变量时,将其放到整型变量的低位字节,高位字节扩展符号位。例如: 



unsigned char ch=255;  //变量ch在内存中为1111 1111,最高位的1不表示符号

short int a=ch; //无符号字符型赋值给整型变量时,高位字节补0,即0000 0000 1111 1111,
//值为255

char ch1=255;   //变量ch1在内存中为1111 1111,其实际值为-1,最高位1为符号位

short int a1=ch1;  //高位字节扩展符号位后为1111 1111 1111 1111,值为-1







(7) 将无符号整型或长整型数据赋给整型变量时,若在整型的取值范围内,则不会产生错误; 而当超出其取值范围时,则赋值的结果错误。

3.5.2强制类型转换

强制类型转换也称显式类型转换,作用是将某种类型强制转换成指定的数据类型。其语法格式如下: 

类型说明符(表达式)


或

(类型说明符) 表达式


例如: 





double(a)	//将变量a转换成double类型的中间数据

(int)(a+b)	    //将a+b运算的结果转换成int型

5/float(3)	        //将3转换成float型







一个变量在强制类型转换后,得到一个指定类型的中间变量,但该变量本身不会改变,还是原来的数据类型。

【例3.9】强制类型转换。





#include <iostream>

using namespace std;

int main()

{float y=6.8;

int x;

x= (int)y%2;  //y的值与类型均不变,生成中间值6,取余后得0,赋值给x

cout<<"x="<<x<<'\t'<<"y="<<y<<'\n';

return 0;

}







程序运行结果如下: 




x=0y=6.8






例3.9中的变量y为float类型,而取余运算符(%)要求两个操作数均为整型,这种情况下若要正确完成运算,需要用强制类型转换符。

3.6常用库函数

C++语言分门别类地提供了多个标准函数库和面向对象类库(简称库),如常用的数学函数库cmath、字符串处理函数库cstring、输入/输出类库iostream等。每个库中提供了大量的函数,若在编程时需要使用库中的函数,只需在程序开头用编译预处理命令#include包含相关库的头文件即可。例如,求某个正整数的平方根,使用C++语言提供的函数sqrt(),则需要包含数学函数库的头文件cmath,包含头文件的编译预处理命令为#include<cmath>。


表38C++语言常用的库函数



C++头文件类别函 数 原 型功 能 简 述



cmath

开平方根函数double sqrt(double x)求x的平方根
取绝对值函数
int abs(int x)long labs(long x)double fabs(double x)分别求整型数、长整型数、浮点数的绝对值
三角函数
double sin(double x)
double cos(double x)
double tan(double x)
double asin (double x)
double acos (double x)
double atan(double x)

分别求x的正弦、余弦、正切值,x为弧度值。例如,求sin(30°)时应把度数转换为弧度,可表示为sin(3.14159*30/180)

分别求x的反正弦、反余弦、反正切值



cmath
指数函数
double pow(double x,double y)求xy,即x的y次幂
double exp(double x)求ex,即e的x次幂

对数函数
double log(double x)求ln(x)
double log10(double x)求logx10

ctime时间函数time_t time(time_t *tloc)返回从1970年1月1日至今所经历的时间(以s为单位)
cstdlib伪随机函数

void srand(unsigned seed)初始化伪随机数发生器。若每次的seed相同,则产生的伪随机数序列也相同。可配合time()函数生成不同的seed,如srand(time(NULL))
int rand()产生0~0x7fff范围内的伪随机数。例如,rand()%100产生[0,99]的随机数,rand()%(b-a+1)+a产生[a,b]的随机数





为了便于函数的使用,通常将函数的主要特征用固定的格式来描述,这种固定的格式称为函数原型(具体内容在后续函数章节讲述)。如图311所示,以计算并返回指定参数的平方根的sqrt()函数为例,其函数原型如下: 



double sqrt(double x); 









图311sqrt函数原型


使用函数时,写下函数名称后,在其后加一对圆括号,括号内根据函数原型写下该函数所需的参数(多个参数用逗号分隔),参数可以是常量、变量或表达式。例如,6可以使用sqrt(6)来描述,(20a+5.0)可以使用sqrt(20*a+5.0)来描述。


表38给出了部分常用的库函数,读者若需要了解更多的函数,可查阅对应的头文件,详见附录C。


习题

一、 选择题

1. 下列符号中可以定义为用户标识符的是。  



A. float	           B. ad            C. _56            D. 5_a

2. 下列符号中不可作为用户标识符的是。  

A. Main	        B. _int		       C. sizeof		    D. abc

3. 下列选项中,正确的C++语言标识符是。   

A. 6_ _sum	        B. sum~6		   C. sum.6		       D. _sum_6

4. 下列选项中可以作为C++语言中合法常量的是。  

A. 80		        B. 080   C. -80e2.0		    D. -80e

5. 下列选项中可以作为C++语言中合法常量的是。  

A. '\85'		       B. 0x80   C. '\x102'		    D. '\085'

6. 下列选项中不是C++语言中合法常量的是。        

A. 0789 	       B. 123UL		   C. 0XFF		       D. 1E-2

7. 下列为字符型变量赋初值的语句中不正确的是。 

A. char a='a'; 	 B. char a="3"; 	   C. char a= 97; 	 D. char a=0x61; 

8. 已知“float x=5.6,y=5.2;”,则表达式(int)x+y的值为。 

A. 10.2 B. 10   C. 10.8		    D. 11.2

9. 若有语句“int i=3, j=2;”,则表达式i/j+i%j的结果是。 

A. 1.5 B. 3   C. 2  	 D. 2.5

10. 表达式(int)((float)9/2)-9%2的值是。                



A. 0 B. 4   C. 3		 		 D. 5

11. 下列运算符要求操作数必须为整型的是。    

A. / B. ++   C. !=		     D. %

12. 若变量已正确定义并具有初值,则下列表达式正确的是。

A. x=y%1.2            B. x+y=z
C. x=y++=z            D. x=2+(y=z=2)

13. 转义字符是以开头的。                     

A. %B. &	C. \D. '

14. 设“int m=1,n=2;”,则表达式m++==n的结果是。

A. falseB. true	C. 3D. 2

15. 设“int m=1,n=2;”,则表达式++m==n的结果是。 

A. falseB. true	C. 3D. 2

16. 下列程序段执行后的输出结果是。     



int a, b, c=246;

a=c/100%9;

b=(-1)&&(-1);

cout<<a<<','<<b<<endl;






A. 2,1         B. 3,2          C. 4,3           D. 2,3


二、 填空题

1. 设有“int a=5,b=4;”,则逻辑表达式a<=6 && a+b>8的值为。

2. 设有“int a=10,b=3;”,则执行表达式b%=b++||a++后,a=、b=。 

3. 设有“int a=6,b=7;”,则执行表达式a+=a-b后,a= 、b=。

4. 设有“int a=35,b=6;”,则表达式!a+a%b的值是。

5. 设有“int x=1,y=2;”,则执行表达式“(x>y)&&(--x>0);”后x的值为。

6. 若有定义“int i=7; float x=3.1416; double y=3;”,则表达式i+'a' *x+i/y值的类型是。

7. 下列程序的运行结果是。



#include<iostream>

using namespace std;

int main()

{int a,b,c;

a=b=1;

c=a++,b++,++b;	

cout<<a<<'\t'<<b<<'\t'<<c<<'\t'<<endl;

return 0;

}







8. 将下列数学式写成C++语言的表达式。

(1) (a-b)(a+b)。

(2) -b+b2-4ac2a。

(3) sinx|x-y|。

(4) s(s-a)(s-b)(s-c)。

9. 写出表示下列条件的C++语言表达式。

(1) a和b至少有一个是偶数。

(2) a是3的倍数,b是5的倍数。

(3) 0≤x<100。

(4) a、b、c构成三角形的条件。


三、 编程题

1. 从键盘输入一个3位正整数n,求出它的各位数字之和sum并输出。

2. 用伪随机函数rand()分别产生一个两位正整数和一个在[-10,10]区间内的整数并输出。