C++运算符与表达式_第1页
C++运算符与表达式_第2页
C++运算符与表达式_第3页
C++运算符与表达式_第4页
C++运算符与表达式_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第3章运算符与表达式

运算符(operator)也称为操作符,对程序中的数据进行运算。参与运算的数据称为操作数(operand)。变量、字面常量等通过运算符组合成表达式,一个表达式也能作为操作数来构成更复杂的表达式。表达式(expression)是构成程序语句的根本要素。3.1根本运算符对于运算符,应注意以下几方面。(1)运算符的功能和语义。(2)运算符的操作数。每个运算符对其操作数的个数、类型和值都有一定限制。(3)运算符的优先级(precedence)。每个运算符都有确定的优先级。(4)运算符的结合性(associativity)。表3.1给出了C++中的主要运算符的功能、优先级、目数、结合性。表中按优先级从高到低分为16个级别。根本运算符优先级运算符功能及说明结合性目数1()改变运算优先级左向右双目::作用域解析、全局[]数组下标.->访问成员,由指针访问成员2++--后缀自增、自减运算单目newdelete动态分配或释放内存++--前缀自增、自减运算符*间接访问dereference&取地址address-of+-正、负号!逻辑非~按位取反sizeof取类型或变量的长度(type)强制类型转换右向左2*.*->*由成员指针访问成员左向右双目Operator.doc优先级运算符功能及说明结合性目数3*/%乘、除、取余左向右双目4+-加、减左向右双目5<<>>左移位、右移位左向右双目6<><=>=小于、大于、小于等于、大于等于左向右双目7==!=等于、不等于左向右双目8&按位与左向右双目9^按位异或左向右双目10|按位或左向右双目11&&逻辑与左向右双目12||逻辑或左向右双目13?:条件运算右向左三目14=*=/=%=+=-=<<=>>=&=|=^=赋值运算右向左双目15,逗号运算左向右双目3.1.1算术运算符+、-〔正号、负号,单目运算〕+、-、*、/、%〔双目运算〕+、-、*、/按通常的算术规定。注意:对于除,假设两个操作数都是整数,结果为整数〔商局部〕。1/2=05/2=2%通常称为取模运算,两个操作数必须都是整型数,结果为余数,余数的符号与左边数的符号等同。3%2=1-3%2=-13%-2=1-3%-2=-18%4=0在算术运算中需要注意溢出问题。两个整数做加法、减法或乘法运算时,即便结果溢出也不是错误。例如:shorts1=32765;s1=s1+3; //结果是否超过short的最大值?cout<<s1<<endl; //输出-32768,而不是32768。实际上,观察二进制数据,这两个值是一样的。3.1.2关系运算<、<=、>、>=、==、!===与=:注意:a=5赋值运算;a==5;判断是否相等a<=x<=b与数学上的x取值区间a

x

b不同关系运算的结果是一个表示“真”或“假”的逻辑值,即一个bool值。当关系成立时,其运算结果为真;当关系不成立时,结果为假。但C语言中没有逻辑型,关系运算的结果要用一个int值表示,0即为假,1即为真。a=2b=3c=4a>20a>b+c0a==21'a'>'A'b=='a'+1c-a==aa=='a'0a>'a'0b=a==21关系运算符的优先级为(括弧中运算符的优先级相同):(>、>=、<、<=)高于(==、!=)。关系运算符的优先级比算术运算符低,但比赋值运算符(=)高。如:inta=5,b=3,c=6,d;d=a>b==c;//等价于d=((a>b)==c);d的值为0d=a==b<c;//等价于d=(a==(b<c));d的值为0d=a>b<=c;//等价于d=((a>b)<=c);d的值为1可以使用()来改变运算符的计算次序。既然关系运算的结果是一个逻辑值,那么就可以保存在一个逻辑型bool变量中。例如:boolb=a>5;由于浮点数在计算机内进行运算和存储时会产生误差,因此在比较两个浮点数时,建议不要直接比较两数是否相等。例如,执行下面语句:doubled1=3.3333,d2=4.4444; if(d1+d2==7.7777) cout<<"相等"<<endl; else{ cout<<"不等"<<endl; cout<<d1+d2<<endl; }条件语句中用“==”来判断浮点数是否相等,结果是不等,但d1+d2输出结果却是7.7777。两个实型数即便输出结果完全一样,其内部值也可能不一样。判断两个实数是否相等的正确方法是:判断两个实数之差的绝对值是否小于一个给定的允许误差数,如判断d1是否等于d2时,应改为:fabs(d1-d2)<=1e-6其中,fabs()是计算绝对值的一个库函数,使用时要包含头文件math.h。3.1.3逻辑运算符对逻辑值进行运算的运算符就是逻辑运算符。C++语言提供了3个逻辑运算符,用于表示操作数之间的逻辑关系,它们是!(逻辑非)、&&(逻辑与)、||(逻辑或)。逻辑运算的结果仍然是逻辑值。逻辑非(!)是单目运算符,它对操作数进行取反运算。当操作数为非0(逻辑真)时,!运算后结果为0(逻辑假)。反之,假设操作数为0(逻辑假),!运算后结果为1(逻辑真)。注意,所有非0的值在逻辑上都作为“真”。例如:cout<<!4<<endl; //输出0,假cout<<!-4<<endl; //输出0,假cout<<!4.1<<endl; //输出0,假cout<<!-4.1<<endl; //输出0,假&&和||运算符是双目运算符。运算规那么如下:&&(逻辑与)表示“而且”的语义。||(逻辑或)表示“或者”的语义。例如:!(2>6) //结果为1,真7>3&&10>6 //结果为1,真5>2||4>8 //结果为1,真4&&5<6 //结果为1,真逻辑运算符的运算优先级为:!高于&&高于||。注意,!的优先级具有较高优先级,甚至高于算术运算符。而&&和||的优先级那么比算术运算符和关系运算符低。因C++将逻辑值保存为整数值,这样使得逻辑值可参与所有的运算,而且逻辑运算符可作用于所有类型的值,而没有语法错误提示。这是C/C++语法不严密之处。读者应注意防止。例3.1逻辑运算符的例子。include<iostream> //A注意,不是iostream.husingnamespacestd; //B导入命名空间stdvoidmain(void){ inta,b; boolres1,res2,res3,res4,res5;

a=3;b=5; res1=a>3&&b>=5; res2=a>3||b>=5; res3=!(b>=5); res4=!(a==b); res5=a>b&&b<6;

cout<<boolalpha; //C cout<<"res1="<<res1<<'\t'; cout<<"res2="<<res2<<'\t'; cout<<"res3="<<res3<<'\t'; cout<<"res4="<<res4<<'\t'; cout<<"res5="<<res5<<endl;}3.1.4位运算符位运算是指对字节内部的二进制位进行移位或逻辑运算。位运算是通过位运算符来完成的。位运算的操作数必须是char、short、或int值,而且结果也是char、short或int值。除了按位求反~是单目运算符,其余位运算都是双目运算符。C++提供了两类位运算:移位运算和按位逻辑运算。1.移位运算符移位运算符的格式为:operand<<n将操作数operand向左移动n个二进制位,右边补0,可能改变符号。operand>>n将操作数operand向右移动n个二进制位,保持符号不变。其中,n为整数。注意移位运算并不改变operand本身的值。例如:shortoperand=0x8,n=3;shorta=operand<<n; //结果为0x40操作数左移n个二进制位后,右边移出的空位用0补齐。当左移时,对于带符号数,最高位表示符号,可能会因为低位的1或0移到最高位,最终改变操作数的符号。如:shorts=4567;shortresult=s<<3;cout<<result;//输出:-29000如果操作数是正数,而且左移没有导致改变符号,那么左移n位,相当于乘以2n。我们知道,int型的数值范围是-231到231-1。下面代码利用左移位来得到int型的最小值和最大值。intmin=1<<31;cout<<"min="<<min<<endl;intmax=(1<<31)-1;cout<<"max="<<max<<endl;显示结果为:min=-2147483648max=2147483647对带符号数右移,操作数右移n位后,左边移出的空位用符号位补齐,最高位始终补与原来最高位相同的数,这样右移不会改变符号。如:shortoperand=-23116,m=3;//移动前为0xa5b4shortb=operand>>m;结果为0xf4b6,即-2890对于移位运算,注意以下几点:(1)不要尝试对float或double数据进行移位运算,编译会出错。(2)移动位数n应不大于左操作数的位数,如int移位应不大于32。如果n大于左操作数位数,实际移动位数要自动按字长取模:n%(sizeof(int))。例如,i<<33就是i左移1位。(3)当移动位数n为负值,C语言标准没有确定是什么结果。在VC6中,左移<<负值位数,相当于循环右移,即移出的位补回到最高位。右移>>负值位数,结果总为0。(4)左移位<<与cout<<可能混淆,右移位>>与cin>>可能混淆,可用括号消除这些错误,例如cout<<(k<<3)。按位逻辑运算符按位逻辑运算有4个:求反~、与&、或|、异或^。(1)按位求反“~”运算符是一个单目运算符,对操作数逐位取反,得到反码。假设二进制位为0,那么取反后为1;假设二进制位为1,那么取反后为0。例如:shortintm=~0xc3//结果为0xff3c运算符具有比较高的优先级,高于一般的算术运算符。而其它按位逻辑运算符的优先级那么比较低。(2)按位逻辑与“&”对两个操作数逐位进行运算。假设对应位都为1,那么该位结果为1,否那么为0。例如:0xc300000000110000110x6e0000000001101110a0000000001000010shortinta=0xc3&0x6e //结果为0x42(3)按位逻辑或“|”对两个操作数逐位进行运算。假设对应位都为0,那么该位结果为0,否那么为1。例如:shortintb=0x12|0x3d //结果为0x3f(4)按位逻辑异或“^”也是对两个操作数逐位进行运算。异或运算的规那么是,假设对应位不同,那么该位结果为1,否那么为0。例如:shortintc=0x5a^0x26 //结果为0x7c按位逻辑异或有一个特点,如果a^b=c,那么c^b=a。b将a转换为c,也能将c再复原为a。显然,两个相等的值异或运算,结果为0。不相等的两个值异或运算结果不为0。3.1.5条件运算符C++中唯一的三目运算符就是条件运算符,由两个符号“?”和“:”组成,要求有3个操作数,形式如下:<表达式1>?<表达式2>:<表达式3>根据<表达式1>为真或假,选择<表达式2>或<表达式3>作为运算结果。(1)条件表达式的执行顺序为:先求解表达式1,假设值为非0,表示条件为真,那么求解表达式2,此时表达式2的值就作为整个条件表达式的结果;假设表达式1的值为0,表示条件为假,那么求解表达式3,表达式3的值就是整个条件表达式的值。例如:a>b?a:b结果是a和b的较大值。(2)通常情况下,表达式1应该是一个关系表达式或逻辑表达式,表达式2和表达式3可以是常量、变量或表达式,而且应该是相同类型。例如:x==y?'Y':'N'(d=b*b-4*a*c)>=0?sqrt(d):sqrt(-d) //sqrt是开平方函数ch=ch>='A'&&ch<='Z'?ch+'a'-'A':ch;//大写字母转小写(3)条件表达式的优先级比较低,仅高于赋值和逗号运算符。(4)虽然C++标准文档说明条件运算符的结合性为“从右向左”,但实际上并非如此。#include<iostream.h>voidmain(void){ inti=1,j=2,k=3; cout<<"Thelargervalueof:"//求出i和j中的最大值

<<i<<"and"<<j<<"is" <<(i>j?i:j)<<endl; intmax=(i>=j?i:j)<k?k:(i>=j?i:j);//A cout<<"Thelargestvalueof:"//求出i,j和k中的最大值

<<i<<","<<j<<"and"<<k <<"is"<<max<<endl;}3.1.6赋值运算符赋值运算就是将一个表达式的值赋给一个变量。C++语言提供了两类赋值运算符:根本赋值运算符和复合赋值运算符。根本赋值运算符为“=”,复合赋值运算符有多种形式:+=、-=、*=、/=、%=、<<=、>>=、&=、^=、|=。(1)赋值运算符都是双目运算符,从右向左进行。例如,sum1=sum2=0相当于sum1=(sum2=0),先执行sum2=0,后执行sum1=sum2。(2)要求赋值运算符左操作数必须是左值,左值能存储值。例如:x=3+5 //正确,x是左值x-3=5 //语法错误,x-3不是左值(3)复合赋值运算符是将算术运算或位运算与赋值相结合,同一个变量即参加运算,也是被赋值的变量,出现在赋值运算符的两边。复合赋值运算符是一个整体,中间不能用空格隔开。例如:a*=6 //相当于a=a*6a%=6 //相当于a=a%6a+=3+6 //相当于a=a+(3+6)初学者容易犯的一个错误就是混淆“=”运算符和“==”运算符。分析下面代码:inta=5,b=3;intd=a==b; //d的值为03.1.7逗号运算符逗号“,”既是标点符号(用做分隔符),又是运算符。逗号运算符用来将两个表达式连接起来,逗号表达式的一般表达形式为:<表达式1>,<表达式2>,<表达式3>,…,<表达式n>逗号运算符是双目运算符,取其右边操作数的值作为整个表达式的结果。逗号运算符的优先级最低。例如:inti,j,k; //作标点符号用funx(x,y,z); //作标点符号用a+b,a+c //逗号运算符1+4,3.4+10,3&4 //逗号运算符x=3+6,x*3,x+6 //第一个逗号运算结果为27,第二个逗号运算结果为15x=(y=3,y+1) //y的值为3,x的值为4例3-3逗号运算符的使用。#include<iostream.h>voidmain(void){inta=3,b=7,c=4,t,x; t=(a+=1,b-=2,c+3); x=3+6,x*3,x+6; cout<<"a="<<a<<'\t'; cout<<"b="<<t<<'\t'; cout<<"c="<<c<<'\t'; cout<<"t="<<t<<endl; cout<<"x="<<x<<endl;x=(x=3+6,x*3),x+6; cout<<"x="<<x<<endl; x=(x=3+6,x*3,x+6); cout<<"x="<<x<<endl; x=(x=3+6,x=x*3,x+6); cout<<"x="<<x<<endl;}3.1.8自增、自减运算符自增、自减运算就是对一个变量加1或减1。自增用“++”运算符,而自减用“--”运算符,它们都是单目运算符。运算符“++”和“--”是一个整体,中间不能用空格隔开。自增(或自减)运算符要区分前缀和后缀两种形式。前缀形式,运算符放在操作数左边,例如++count。先使操作数自增(自减)1个单位后,然后取其值作为运算结果。后缀形式,运算符放在操作数右边,例如count++,先取操作数的值参与当前表达式的运算,然后再使操作数自增(自减)1个单位。例如:intcount=15,digit=16,number,amount; number=++count; //count和number都为16amount=digit++; //amount的值为16,digit的值为17自增、自减运算符要求操作数必须是左值,往往是一个变量。前缀式的计算结果是操作数修改后的值,因此结果仍然是一个左值;而后缀式的值是原先操作数的值,所以它不是左值。如:intamt=63,nut=96; ++++amt; //相当于++(++amt),结果为65++nut--; //相当于++(nut--),nut--不是左值,所以语法错误(++nut)--; //++nut是左值,所以语法正确自增、自减运算符具有较高的优先级,高于所有的算术运算符。例3-4自增、自减运算符的使用。#include<iostream.h>voidmain(void){ inta=2,b=3; intc,d,e; c=++a+b--; //c=3+3 cout<<"a="<<a<<'\t'<<"b="<<b<<'\t'<<"c="<<c<<endl; d=++++a+++b; //d=5+3 cout<<"a="<<a<<'\t'<<"b="<<b<<'\t'<<"d="<<d<<endl; e=a++-----b; //e=5-1 cout<<"a="<<a<<'\t'<<"b="<<b<<'\t'<<"e="<<e<<endl;}程序运行后,在屏幕上输出的结果为:a=3b=2c=6a=5b=3d=8a=6b=1e=4在上面这些运算符中,只有赋值运算符和自增自减运算符可以更改左值,常称为副作用(sideeffect)。应防止在同一个表达式中对同一个变量进行屡次自增自减运算,否那么结果难以合理解释。例如:inta=2;intb=++a+++a; 最后b的值为8,a为4。实际上b=4+4,而不是b=3+4。再如:a=2;intc=a+++++a;最后c的值为6,a为4。实际上c=3+3,而不是c=2+3。一个比较合理的解释是这里的+运算是从右向左计算的(但这违背+的结合性,从左向右),真正执行的是:intc=++a+a++;注意,尽管后缀自增自减运算符具有比较高的优先级,也不能先计算。例如: inta=2; intb=3+(a++);//等同于b=3+a++此时变量b的值是3+2,而不是3+3。3.1.9sizeof运算符每种类型的变量都占用一定大小的存储单元。存储单元的大小与变量类型、CPU及操作系统有关。sizeof运算符用于测试某种数据类型或表达式的类型在内存中所占的字节数,它是一个一元运算符。其语法格式为:sizeof(<类型名>)或sizeof(<表达式>)例如:sizeof(int) //整数类型占4个字节,结果为4sizeof(3+3.6)//3+3.6的结果为double实数,结果为83.1.10typeid运算符对于任何一个表达式,应该知道它的类型究竟是什么。例如:inti=-2;unsignedj=3;cout<<i*j<<endl; //输出4294967290表达式i*j的类型是什么?C++提供了typeid运算符(称为类型标识typeidentity),能获取一个表达式在运行时刻的类型信息。该运算符要求包含一个文件<typeinfo.h>,还要再调用一个函数name()。例3-6typeid运算符的例子。#include<iostream.h>#include<typeinfo.h>voidmain(){ inti=-2; unsignedj=3; cout<<i*j<<endl; cout<<typeid(i*j).name()<<endl; }3.2表达式表达式(expression)是由运算符、括号和操作数(operand)构成的序列,在运行时能计算出一个值的结果。按运算符的不同,可将表达式分为算术表达式、赋值表达式、关系表达式、逻辑表达式、逗号表达式等等。按表达式能否放在赋值号的左边还是右边,可将表达式分为左值表达式和右值表达式。表达式按照其中运算符的优先级和结合性来求值。每个表达式都有确定的运算结果(表达式的值)和所属类型(即结果值的类型),其类型取决于表达式中的运算符和操作数的类型。3.2.1左值表达式和右值表达式能放在赋值号左边的表达式称为左值表达式,简称左值(l-value)。左值表达式必须能指定一个存放数据的空间,一般是变量,但不能是const修饰的变量。右值表达式就是能放在赋值号右边的表达式,简称为右值(r-value)。3.2.2算术表达式由算术运算符、位运算符和操作数构成的表达式称为算术表达式。3.2.3赋值表达式由赋值运算符和操作数构成的表达式称为赋值表达式。赋值表达式要求赋值运算符左边必须是左值,其功能就是用右值表达式的值来更改左值。赋值表达式的计算顺序是从右向左进行的,运算结果取左值表达式的值。使用复合赋值表达式可使语句表达更简练。对赋值表达式说明以下几点。(1)赋值表达式的结果是左值,因此可出现在赋值运算符“=”的左边。例如:(x=5)=23+6//x=5是左值,被改为29,即x和整个表达式的值为29x=y=z=0 //先使z=0,然后再将z的值赋给y,最后将y的值赋给x(2)说明语句中的符号“=”用来初始化,尽管在书写上与赋值运算符“=”一样,但含义却不同。floatradius1=5.63f; //说明变量radius1,并初始化成5.36intsum1=total1=0; //语法错误,要求分别初始化sum1和total1floatradius; //说明变量radiusradius=5.63f; //给变量radius赋值3.2.4关系表达式由关系运算符和操作数构成的表达式称为关系表达式。其中的操作数可以是任何类型的表达式。关系表达式的结果为逻辑值,即表达式中的关系成立时,其值为逻辑真(用1表示),否那么其值为逻辑假(用0表示)。关系表达式通常用来构造简单条件表达式,用在程序流程控制语句中。例如:if(x>0) y=x; //如果x大于0,y取x的值elsey=-x; //如果x不大于0,y取-x的值,最后y是x的绝对值注意,“=”和“==”含义完全不同,注意不要误写。试比较下面两个程序段:if(x==168)… //判断x是否等于168,条件可能成立,也可能不成立if(x=168)… //将值168赋给x,计算结果为逻辑1,条件永远成立3.2.5逻辑表达式由逻辑运算符和操作数构成的表达式称为逻辑表达式。逻辑表达式的运算结果为逻辑值,一般用来构造比较复杂的条件表达式。逻辑表达式中往往包含多个关系表达式,要先计算关系表达式的值,再计算逻辑表达式。但逻辑与(&&)和逻辑或(||)运算符在运算时,从左向右计算,根据规那么一旦能确定整个表达式的值时,就结束计算,后面的表达式就不再计算。(1)对于<条件1>&&<条件2>逻辑表达式,先计算<条件1>的值,假设其值为逻辑真(非0),就再计算<条件2>的值,假设其值为非0,那么结果为1,否那么为0。假设<条件1>的值为逻辑假(值为0),就已经知道整个表达式为假,就不再计算<条件2>的值,结束整个表达式的计算。例如:year%4==0&&year%100!=0用&&来连接两个条件,前一个条件满足是后一个条件计算的前提。(2)对于<条件1>||<条件2>逻辑表达式,先计算<条件1>的值,假设其值为假,再计算<条件2>的值,并将<条件2>的值作为整个表达式的值。假设<条件1>的值为真,就已经知道整个表达式的值为真,就结束整个表达式计算。例如:year%400==0||year%4==0&&year%100!=03.2.6逗号表达式由逗号运算符和操作数组成的表达式称为逗号表达式,就是用逗号将多个表达式分隔起来,从左向右逐个计算各个表达式,并将最右边的表达式作为逗号表达式的值。例如:intp,w,x=8,y=10,z=12;w=(x++,y,z+3)-5; //w的值为(z+3)-5,即10p=x+5,y+x,z;//p的值为x+5,即15,z的值12作为逗号表达式的值如果逗号运算符的右操作数是一个左值,该逗号运算的结果也是左值。例如:(y++,z)=2 //z是左值,(y++,z)的结果也是左值,z的值被改为23.2.7表达式语句任何一个表达式后加上一个分号“;”就构成一条表达式语句。表达式语句的一般格式为:<表达式>;注意,分号是构成语句的组成局部,而不是作为语句之间的分隔符。例如:x=20;3*8-9;y=a+b*c;i=0,j=0;i++;这些都是合法的表达式语句,第二个表达式语句只做了算术运算,并没有保存结果,即没有副作用,在程序中应消除这些没用的表达式语句。3.3类型转换每个运算符的操作数的个数及类型都有特定限制。在一个表达式中,运算符的某个操作数如果不符合类型要求,就要对操作数进行类型转换。C++中的类型转换有3种:自动类型转换、赋值转换和强制类型转换。3.4.1自动类型转换自动类型转换(也称隐式类型转换)指系统自动地将表达式中的操作数转换成所需类型的值,转换顺序为由范围较小的类型向范围较大的类型转换。规那么1。两个不同类型的操作数进行运算时,先将较小范围的数值转换为另一个较大范围的数值,然后再进行计算。各种根本数据类型的数值范围从小到大排列次序如下:char,bool→short→int→float→doubleunsignedchar→unsignedshort→unsignedint→float→double例如定义两个变量a和f:inta=100;floatf=32.2f;那么计算以下表达式:a/f处理过程为:先将a的值转换成float型,然后再进行浮点数的除法运算,结果为一个float值3.10559。在这个过程中a变量的值不改变。分析下面两行输出结果是否一样。shorts1=32765;cout<<s1+3<<endl;s1=s1+3; //Acout<<s1<<endl; 按规那么1可知,两个有符号的值之间进行算术运算,其结果是有符号的。一个无符号的值与一个浮点数(如float)进行算术运算,其结果是浮点数(如float)。但两个无符号的值之间进行算术运算(两个值中没有unsignedint),其结果是有符号的int。例如:unsignedcharc1=2;unsignedshorts1=3;cout<<(c1*s1)<<endl; //乘法,输出6cout<<typeid(c1*s1).name()<<endl; //输出int规那么2对于bool、char、short、int类型,任意两个值之间进行算术运算、位运算,其结果都是一个int值。任意两个值之间进行逻辑运算,其结果都是一个bool值。注意规那么2是规那么1的一个例外。例如:charc1=-2;shorts1=3;cout<<(c1*s1)<<endl; //乘法,输出-6cout<<typeid(c1*s1).name()<<endl; //输出intcout<<(c1&s1)<<endl; //按位与,输出2cout<<typeid(c1&s1).name()<<endl; //输出intcout<<(c1&&s1)<<endl; //逻辑与,输出1,表示truecout<<typeid(c1&&s1).name()<<endl; //输出bool规那么3。对于bool、char、short、int类型,任一个类型值(无论是否带符号)与unsignedint之间进行算术运算,其结果都是unsignedint类型。注意规那么3又是规那么2的一个例外。例如:charc1=-2;unsignedshorts1=2;unsignedintj=3;cout<<(c1*j)<<endl;//乘法,输出4294967290,而不是-6cout<<typeid(c1*j).name()<<endl;//输出unsignedintcout<<(s1*j)<<endl; //乘法,输出6cout<<typeid(s1*j).name()<<endl;//输出unsignedint由上面例子可知,unsignedint被系统认为是整型数值中的最大范围的类型,因此其它类型与之计算时,都要转换到unsignedint。此时如果另一个整数恰好是负值,而结果是不带符号的正值,就不能得到预期结果,但二进制结果是正确的,例如4294967290与-6是一样的。在处理表达式的过程中,并不是将变量直接转换成最大范围的类型,而是在表达式处理过程中,按照需要逐步进行转换。例如:inti=1;charch=2;floatf=3.0f;doubledf=4.0;cout<<(ch*i+f*2.0-df)<<endl;表达式ch*i+f*2.0-df的计算过程为:(1)将ch转换为int型,计算ch*i,即2*1,结果为2,类型为int。(2)将f转换为double型,计算f*2.0,即3.0*2.0,结果为6.0,类型为double。(3)将ch*i的结果2转换为double型,计算2.0+6.0,结果为8.0,类型为double。(4)计算8.0-df,即4.0,整个表达式的结果为4.0,类型为double。自动类型转换的根本规那么是“宽化”或者“提升”,即将较小范围的数值类型转换到较大范围的数据类型。大多数自动类型转换是平安的。3.4.2赋值转换赋值类型转换出现在初始化表达式或者赋值表达式中。当初始化或赋值运算符的左值表达式的类型与右值表达式类型不同,且类型兼容时,将进行类型转换到左值类型。即先计算出右值表达式的值,然后将其转换为左值类型后再赋给左值。例如:charch='b';shorts=ch; //char转换到shortcout<<s<<endl; //输出:98i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论