赋值运算符

赋值符号“=”就是赋值运算符,它的作用是将一个数据赋给一个变量。如“a=3”的作用是执行一次赋值操作(或称赋值运算)。把常量3赋给变量a。也可以将一个表达式的值赋给一个变量。

赋值过程中的类型转换

如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时会自动进行类型转换。

1)  将浮点型数据(包括单、双精度)赋给整型变量时,舍弃其小数部分。

2)  将整型数据赋给浮点型变量时,数值不变,但以指数形式存储到变量中。

3) 将一个double型数据赋给float变量时,要注意数值范围不能溢出。

4)  字符型数据赋给整型变量,将字符的ASCII码赋给整型变量。

5) 将一个int、short或long型数据赋给一个char型变量,只将其低8位原封不动地送到char型变量(发生截断)。例如
   short int i=289;
   char c;
   c=i; //将一个int型数据赋给一个char型变量
赋值情况见图2.8。为方便起见,以一个int型数据占两个字节(16位)的情况来说明。


图2.8

6) 将signed(有符号)型数据赋给长度相同的unsigned(无符号)型变量,将存储单元内容原样照搬(连原有的符号位也作为数值一起传送)。

【例2.5】将有符号数据传送给无符号变量。

  1. #include <iostream>
  2. using namespace std;
  3. int main( )
  4. {
  5. unsigned short a;
  6. short int b=-1;
  7. a=b;
  8. cout<<"a="<<a<<endl;
  9. return 0;
  10. }

运行结果为
a=65535

赋给b的值是-1,怎么会得到65535呢?请看图2.9所示的赋值情况。


图2.9

-1的补码形式为1111111111111111(即全部16个二进制位均为1),将它传送给a,而a是无符号型变量,16个位全1是十进制的65535。如果b为正值,且在0~32767之间,则赋值后数值不变。

不同类型的整型数据间的赋值归根结底就是一条:按存储单元中的存储形式直接传送。

C和C++使用灵活,在不同类型数据之间赋值时,常常会出现意想不到的结果,而编译系统并不提示出错,全靠程序员的经验来找出问题。这就要求编程人员对出现问题的原因有所了解,以便迅速排除故障。

复合的赋值运算符

在赋值符“=”之前加上其他运算符,可以构成复合的运算符。如果在“=”前加一个“+”运算符就成了复合运算符“+=”。例如,可以有
    a+=3  等价于  a=a+3
    x*=y+8等价于  x=x*(y+8)
    x%=3  等价于  x=x%3
以“a+=3”为例来说明,它相当于使a进行一次自加3的操作。即先使a加3,再赋给a。同样,“x*=y+8”的作用是使x乘以(y+8),再赋给x。

为便于记忆,可以这样理解:

  1. a+= b(其中a为变量,b为表达式)
  2. a+= b (将有下划线的“a+”移到“=”右侧)
  3. a = a + b  (在“=”左侧补上变量名a)

注意,如果b是包含若干项的表达式,则相当于它有括号。如

  1. x %= y+3
  2. x %= (y+3)
  3. x = x%(y+3)(不要错认为x=x%y+3)
 
 

凡是二元(二目)运算符,都可以与赋值符一起组合成复合赋值符。C++可以使用以下几种复合赋值运算符:
    +=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=
其中后5种是有关位运算的。

C++之所以采用这种复合运算符,一是为了简化程序,使程序精炼,二是为了提高编译效率(这样写法与“逆波兰”式一致,有利于编译,能产生质量较高的目标代码)。专业的程序员在程序中常用复合运算符,初学者可能不习惯,也可以不用或少用。

赋值表达式

由赋值运算符将一个变量和一个表达式连接起来的式子称为“赋值表达式”。它的一般形式为:
    <变量> <赋值运算符> <表达式>
如“a=5”是一个赋值表达式。对赋值表达式求解的过程是:先求赋值运算符右侧的“表达式”的值,然后赋给赋值运算符左侧的变量。一个表达式应该有一个值。赋值运算符左侧的标识符称为“左值”(left value,简写为lvalue)。并不是任何对象都可以作为左值的,变量可以作为左值,而表达式a+b就不能作为左值,常变量也不能作为左值,因为常变量不能被赋值。

出现在赋值运算符右侧的表达式称为“右值”(right value,简写为rvalue)。显然左值也可以出现在赋值运算符右侧,因而左值都可以作为右值。如:
    int a=3,b,c;
    b=a;// b是左值
    c=b;// b也是右值
赋值表达式中的“表达式”,又可以是一个赋值表达式。如
    a=(b=5)
下面是赋值表达式的例子:
    a=b=c=5  (赋值表达式值为5,a,b,c值均为5)
    a=5+(c=6)(表达式值为11,a值为11,c值为6)
    a=(b=4)+(c=6)  (表达式值为10,a值为10,b等于4,c等于6)
    a=(b=10)/(c=2) (表达式值为5,a等于5,b等于10,c等于2)
请分析下面的赋值表达式:
    (a=3*5)=4*3
赋值表达式作为左值时应加括号,如果写成下面这样就会出现语法错误:
    a=3*5=4*3
因为3*5不是左值,不能出现在赋值运算符的左侧。

赋值表达式也可以包含复合的赋值运算符。如
    a+=a-=a*a
也是一个赋值表达式。如果a的初值为12,此赋值表达式的求解步骤如下:

    1. 先进行“a-=a*a”的运算,它相当于a=a-a*a=12-144=-132。
    2. 再进行“a+=-132”的运算,它相当于a=a+(-132)=-132-132=-264。

C++赋值运算符与赋值表达式的更多相关文章

  1. JavaScript—赋值表达式

      赋值表达式的运算顺序是从右到左的,因此,可以通过以下方法对多个变量赋值 1 i=j=k=0;//也就是把三个变量初始化为0 赋值表达式中的递增和递减 n++和++n的区别:     简单来说,根据 ...

  2. Java学习随笔2:Java复合赋值表达式的小问题

    问题:i += j只是i = i + j的简写么? 答案:非也!看下面的程序: int i = 5; long j = 8; i += j; // 可以通过编译且结果正确 i = i + j; // ...

  3. JavaScript—赋值表达式-1

    赋值表达式的运算顺序是从右到左的,因此,可以通过以下方法对多个变量赋值 i=j=k=0;//也就是把三个变量初始化为0 赋值表达式中的递增和递减 n++和++n的区别: 简单来说,根据运算顺序,n++ ...

  4. <转>赋值表达式解析的流程

    转自:http://www.cnblogs.com/nazhizq/p/6520072.html 上节说到表达式的解析问题,exprstate函数用于解析普通的赋值表达式.lua语言支持多变量赋值.本 ...

  5. C语言中赋值表达式的返回值是什么?

    我们或多或少都有过,或者见过将赋值表达式参与运算的情况.这通常会伴随着一些意想不到的问题.今天我就见到了一段奇怪的代码: #include<stdio.h> int main() { ; ...

  6. js-带操作的赋值表达式

    带操作的赋值表达式为: a op= b 这里op代表一个运算符,这个表达式等价于: a = a op b 这里需要特别注意:在第一个表达式中,表达式a计算了一次,而在第二个表达式中,表达式a计算了两次 ...

  7. python-3.8.0 新特性之赋值表达式

    [python-3.8.0 新特性之赋值表达式] 赋值表达式的语法是这样的“ name := expression ”,形式上看和赋值语句 “ = ” 差不多,就作用上来看也雷同.也就是说 “:=” ...

  8. lua源码学习篇三:赋值表达式解析的流程

    上节说到表达式的解析问题,exprstate函数用于解析普通的赋值表达式.lua语言支持多变量赋值.本文先从单变量赋值表达式讲起. a = b = c = a + b 对于简单的两个数的求和过程,lu ...

  9. Python基础0:变量 赋值 表达式和运算符

    变量: 前面我们在使用print()输出内容的时候,如果内容很长,后面要再次输出的时候,就需重新在输入一遍. 如果给输出的内容起个简单的别名.这样我们用简短的别名来代替长内容,下次要输出的时候就直接使 ...

随机推荐

  1. Oracle 集群心跳及其參数misscount/disktimeout/reboottime

    在Oracle RAC中,能够从多个层次,多个不同的机制来检測RAC的健康状况,即能够通过心跳机制以及一定的投票算法来隔离故障.假设检測到某节点失败,则存在故障的节点将会被逐出集群以避免故障节点破坏数 ...

  2. leetcode_question_70 Climbing Stairs

    You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...

  3. c基础总结

    机器大小端判断: #include <stdio.h> typedef union{ char x; int i; }un; int main() { un tt; tt.i = ; ) ...

  4. 悬浮二维码 QQ ToTop

    //回顶部 <div id="lqdbe" style="position: absolute; visibility: visible; z-index: 1;  ...

  5. BZOJ 1823: [JSOI2010]满汉全席( 2-sat )

    2-sat...假如一个评委喜好的2样中..其中一样没做, 那另一样就一定要做, 这样去建图..然后跑tarjan. 时间复杂度O((n+m)*K) ------------------------- ...

  6. 64位win8 配置Apache2.4+mod_msgi4.4.21+django1.8.6+python3.4

    学习了很多前人分享的资料,整理如下: 安装步骤: 一.安装python3.4        下载 python-3.4.3.amd64.msi 直接安装         地址:https://www. ...

  7. windows apache 配置多个服务 站点 Apache Service Monitor

    把Apache安装为多个Window NT服务 ~~~ 可以在 services.msc中查看到1. 在DOS下跳到Apache安装目录里的bin目录(~~~或者用path命令 把apache的安装目 ...

  8. Python 第一章 基础知识

    如果熟其他计算机语言,可能会习惯于每行以分号结束.Python则不同,一行就是一行,不管多少. 如果喜欢的话,可以加上分号,但是不会有任何作用(除非同一行还有更多的代码),而且这也不是同行的做法. & ...

  9. 【Android】: 部分注意事项

    1.用来触发BroadcastReceive的Intent和启动Activity或Service的Intent是不兼容的. 2.当文件名做为ContentProvider查询的一部分返回的时候,不应该 ...

  10. cocos2dx进阶学习之坐标转换

    在cocos2dx中,有四种坐标系 GL坐标系:左下为原点,x轴向右,y轴向上 UI坐标系:左上为原点,x轴向右,y轴向下 世界坐标系:与GL坐标系相同 本地坐标系:是节点(CCNode)的坐标系,原 ...