赋值运算符

赋值符号“=”就是赋值运算符,它的作用是将一个数据赋给一个变量。如“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中获取系统的时间

    activity代码 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); set ...

  2. SQL Server:错误处理及事务控制

    目录: 解读错误信息 RAISERROR THROW 实例 使用 @@ERROR 使用 XACT_ABORT 使用TRY/CATCH 现实中的事务语句 删除 更新 银行取钱 解读错误信息 Msg 54 ...

  3. FreeCodeCamp:Slasher Flick

    要求: 打不死的小强! 返回一个数组被截断n个元素后还剩余的元素,截断从索引0开始. 结果: slasher([1, 2, 3], 2) 应该返回 [3]. slasher([1, 2, 3], 0) ...

  4. How do I Find Out Linux CPU Utilization?

    From:http://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html Whenever a Linux sys ...

  5. 基于Qt下移动平台第三方接入-ShareSDK(新浪微博,微信朋友圈等分享登录)

    一. ShareSDK简介 ShareSDK是为iOS.Android.WP8的APP提供社会化功能的一个组件,开发者只需10分钟即 可集成到自己的APP中,它不仅支持如QQ.微信.新浪微博.腾讯微博 ...

  6. 「JAVA」:Berkeley DB的JAVA连接

    Berkeley DB是一个嵌入式的数据库,它适合于管理海量的.简单的数据.关键字/数据(key/value)是Berkeley DB用来进行数据管理的基础.每个key/value构成了一条记录,而整 ...

  7. 基于visual Studio2013解决C语言竞赛题之0307函数求值

      题目 解决代码及点评 这又是个条件函数,但是这个函数无法用switch来解决,因为switch只能用于和某条件相等情况下,而这个函数的范围是无穷的 遇到这种问题,我们还是需要用复合的if语 ...

  8. poj 3984 迷宫问题(dfs)

    题目链接:http://poj.org/problem?id=3984 思路:经典型的DFS题目.搜索时注意剪枝:越界处理,不能访问处理. 代码: #include <iostream> ...

  9. [对话CTO]当当网熊长青:兴趣是成为优秀工程师的第一因素-CSDN.NET

    Women Techmaker 北京站 [对话CTO]当当网熊长青:兴趣是成为优秀工程师的第一因素-CSDN.NET     [对话CTO]当当网熊长青:兴趣是成为优秀工程师的第一因素    发表于2 ...

  10. sublime2/3自总结经常使用快捷键(2的居多)

    Ctrl+D 选词 (重复按快捷键,就可以继续向下同一时候选中下一个同样的文本进行同一时候编辑) Ctrl+鼠标左键 能够同一时候选择要编辑的多处文本 Shift+鼠标右键(或使用鼠标中键)能够用鼠标 ...