赋值运算符

赋值符号“=”就是赋值运算符,它的作用是将一个数据赋给一个变量。如“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. Android手机设置隐藏命令大全

    注意:因Android版本较多,固有部分隐藏命令或不能使用 *#*#4636#*#* 显示手机信息.电池信息.电池记录.使用统计数据.WiFi 信息 *#*#7780#*#* 重设为原厂设定,不会删除 ...

  2. Cloud Foundry warden container 安全性探讨

    本文将从Cloud Foundry中warden container的几个方面探讨warden container的安全性. 1. warden container互訪 1.1.  互訪原理· 在Cl ...

  3. Difference between LINQ to SQL and LINQ to Entity(DataContext and DbContext)

    http://msdn.microsoft.com/en-us/library/cc161164.aspx http://stackoverflow.com/questions/2443836/wha ...

  4. html相关介绍

    HTML(超文本标记语言)  超文本标记语言,即HTML(Hypertext Markup Language),是用于描述网页文档的一种标记语言 XHTML1.0 可扩展超文本置标语言(eXtensi ...

  5. Hive环境搭建心得(Ubuntu)

    Hive是什么? 基于Hadoop的数据查询工具,可以使用类SQL进行数据查询. Hadoop安装 参考了Hadoop安装 注意到etc/hadoop/hadoop-env.sh里设置JAVA_HOM ...

  6. C陷阱与缺陷(一)

    第一章 词法陷阱 术语“符号”指的是程序的一个基本组成单元,其作用相当于一个句子中的单词.编译器中负责将程序分解为一个一个符号的部分,一般称为“词法分析器”. 1.1 =不同于== 一般容易将比较运算 ...

  7. asp.net判断用户是否登录

    最简单的代码: if(Session["LoginUser"] == null)  //注意:Session["LoginUser"]后面,没有ToString ...

  8. [K/3Cloud] 如何从被调用的动态表单界面返回数据

    在需要返回数据的地方调用表单返回方法完成数据返回 this.View.ReturnToParentWindow(retData); 在调用界面的回调函数中取出返回结果的ReturnData即可使用. ...

  9. 链接分析算法之:HITS算法

    链接分析算法之:HITS算法     HITS(HITS(Hyperlink - Induced Topic Search) ) 算法是由康奈尔大学( Cornell University ) 的Jo ...

  10. cocos2d-x游戏开发系列教程-超级玛丽09-怪物激活与移动

    在游戏中,很多怪物本身是会移动的,这里主要有蘑菇怪,乌龟等. 说起怪物的移动,首先在游戏里先要考虑怪物的抽象和设计. 在CMMonster.h中,有个类CMMonsterBasic,这个类抽象了所有的 ...